mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
merge3: make identical changes merge cleanly
when making the same change on both the left and right fork, this should not be a merge conflict. Instead, the two changes should merge cleanly.
This commit is contained in:
parent
4364b71ccc
commit
c59eb6d117
12 changed files with 137 additions and 20 deletions
|
@ -57,6 +57,7 @@ extern int anychange;
|
|||
extern Biobuf stdout;
|
||||
|
||||
#define MAXPATHLEN 1024
|
||||
#define MAXLINELEN 4096
|
||||
|
||||
#define DIRECTORY(s) ((s)->qid.type&QTDIR)
|
||||
#define REGULAR_FILE(s) ((s)->type == 'M' && !DIRECTORY(s))
|
||||
|
@ -76,3 +77,4 @@ void change(Diff *, int, int, int, int);
|
|||
void freediff(Diff *);
|
||||
void flushchanges(Diff *);
|
||||
void fetch(Diff *d, long *f, int a, int b, Biobuf *bp, char *s);
|
||||
int readline(Biobuf*, char*, int);
|
||||
|
|
|
@ -4,17 +4,16 @@
|
|||
#include <ctype.h>
|
||||
#include "diff.h"
|
||||
|
||||
#define MAXLINELEN 4096
|
||||
#define MIN(x, y) ((x) < (y) ? (x): (y))
|
||||
|
||||
static int
|
||||
readline(Biobuf *bp, char *buf)
|
||||
int
|
||||
readline(Biobuf *bp, char *buf, int nbuf)
|
||||
{
|
||||
int c;
|
||||
char *p, *e;
|
||||
|
||||
p = buf;
|
||||
e = p + MAXLINELEN-1;
|
||||
e = p + nbuf-1;
|
||||
do {
|
||||
c = Bgetc(bp);
|
||||
if (c < 0) {
|
||||
|
@ -44,7 +43,7 @@ readline(Biobuf *bp, char *buf)
|
|||
* summing 1-s complement in 16-bit hunks
|
||||
*/
|
||||
static int
|
||||
readhash(Biobuf *bp, char *buf)
|
||||
readhash(Biobuf *bp, char *buf, int nbuf)
|
||||
{
|
||||
long sum;
|
||||
unsigned shift;
|
||||
|
@ -53,7 +52,7 @@ readhash(Biobuf *bp, char *buf)
|
|||
|
||||
sum = 1;
|
||||
shift = 0;
|
||||
if ((len = readline(bp, buf)) == -1)
|
||||
if ((len = readline(bp, buf, nbuf)) == -1)
|
||||
return 0;
|
||||
p = buf;
|
||||
switch(bflag) /* various types of white space handling */
|
||||
|
@ -138,7 +137,7 @@ prepare(Diff *d, int i, char *arg, char *orig)
|
|||
Bseek(bp, 0, 0);
|
||||
}
|
||||
p = emalloc(3*sizeof(Line));
|
||||
for (j = 0; h = readhash(bp, buf); p[j].value = h)
|
||||
for (j = 0; h = readhash(bp, buf, sizeof(buf)); p[j].value = h)
|
||||
p = erealloc(p, (++j+3)*sizeof(Line));
|
||||
d->len[i] = j;
|
||||
d->file[i] = p;
|
||||
|
@ -179,12 +178,12 @@ check(Diff *d, Biobuf *bf, Biobuf *bt)
|
|||
d->ixold[0] = 0;
|
||||
d->ixnew[0] = 0;
|
||||
for (f = t = 1; f < d->len[0]; f++) {
|
||||
flen = readline(bf, fbuf);
|
||||
flen = readline(bf, fbuf, sizeof(fbuf));
|
||||
d->ixold[f] = d->ixold[f-1] + flen; /* ftell(bf) */
|
||||
if (d->J[f] == 0)
|
||||
continue;
|
||||
do {
|
||||
tlen = readline(bt, tbuf);
|
||||
tlen = readline(bt, tbuf, sizeof(tbuf));
|
||||
d->ixnew[t] = d->ixnew[t-1] + tlen; /* ftell(bt) */
|
||||
} while (t++ < d->J[f]);
|
||||
if (bflag) {
|
||||
|
@ -195,7 +194,7 @@ check(Diff *d, Biobuf *bf, Biobuf *bt)
|
|||
d->J[f] = 0;
|
||||
}
|
||||
while (t < d->len[1]) {
|
||||
tlen = readline(bt, tbuf);
|
||||
tlen = readline(bt, tbuf, sizeof(tbuf));
|
||||
d->ixnew[t] = d->ixnew[t-1] + tlen; /* fseek(bt) */
|
||||
t++;
|
||||
}
|
||||
|
@ -227,7 +226,7 @@ fetch(Diff *d, long *f, int a, int b, Biobuf *bp, char *s)
|
|||
return;
|
||||
Bseek(bp, f[a-1], 0);
|
||||
while (a++ <= b) {
|
||||
len = readline(bp, buf);
|
||||
len = readline(bp, buf, sizeof(buf));
|
||||
if(len == 0 || buf[len-1] != '\n'){
|
||||
Bprint(&stdout, "%s%s\n", s, buf);
|
||||
Bprint(&stdout, "\\ No newline at end of file\n");
|
||||
|
|
|
@ -58,6 +58,33 @@ overlaps(int lx, int ly, int rx, int ry)
|
|||
return ry >= lx;
|
||||
}
|
||||
|
||||
static int
|
||||
same(Diff *l, Change *lc, Diff *r, Change *rc)
|
||||
{
|
||||
char lbuf[MAXLINELEN], rbuf[MAXLINELEN];
|
||||
int i, ll, rl, lx, ly, rx, ry;
|
||||
|
||||
lx = lc->newx;
|
||||
ly = lc->newy;
|
||||
rx = rc->newx;
|
||||
ry = rc->newy;
|
||||
if(ly - lx != ry - rx)
|
||||
return 0;
|
||||
assert(lx <= ly && ly < l->len[1]);
|
||||
assert(rx <= ry && ry < r->len[1]);
|
||||
Bseek(l->input[1], l->ixnew[lx-1], 0);
|
||||
Bseek(r->input[1], r->ixnew[rx-1], 0);
|
||||
for(i = 0; i <= (ly - lx); i++){
|
||||
ll = readline(l->input[1], lbuf, sizeof(lbuf));
|
||||
rl = readline(r->input[1], rbuf, sizeof(rbuf));
|
||||
if(ll != rl)
|
||||
return 0;
|
||||
if(memcmp(lbuf, rbuf, ll) != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char*
|
||||
merge(Diff *l, Diff *r)
|
||||
{
|
||||
|
@ -116,14 +143,19 @@ merge(Diff *l, Diff *r)
|
|||
lc->oldy += δ;
|
||||
lc->newy += δ;
|
||||
}
|
||||
fetch(l, l->ixold, ln, x-1, l->input[0], "");
|
||||
Bprint(&stdout, "<<<<<<<<<< %s\n", l->file2);
|
||||
fetch(l, l->ixnew, lc->newx, lc->newy, l->input[1], "");
|
||||
Bprint(&stdout, "========== original\n");
|
||||
fetch(l, l->ixold, x, y, l->input[0], "");
|
||||
Bprint(&stdout, "========== %s\n", r->file2);
|
||||
fetch(r, r->ixnew, rc->newx, rc->newy, r->input[1], "");
|
||||
Bprint(&stdout, ">>>>>>>>>>\n");
|
||||
if(same(l, lc, r, rc)){
|
||||
fetch(l, l->ixold, ln, x-1, l->input[0], "");
|
||||
fetch(l, l->ixnew, lc->newx, lc->newy, l->input[1], "");
|
||||
}else{
|
||||
fetch(l, l->ixold, ln, x-1, l->input[0], "");
|
||||
Bprint(&stdout, "<<<<<<<<<< %s\n", l->file2);
|
||||
fetch(l, l->ixnew, lc->newx, lc->newy, l->input[1], "");
|
||||
Bprint(&stdout, "========== original\n");
|
||||
fetch(l, l->ixold, x, y, l->input[0], "");
|
||||
Bprint(&stdout, "========== %s\n", r->file2);
|
||||
fetch(r, r->ixnew, rc->newx, rc->newy, r->input[1], "");
|
||||
Bprint(&stdout, ">>>>>>>>>>\n");
|
||||
}
|
||||
ln = y+1;
|
||||
il++;
|
||||
ir++;
|
||||
|
|
10
sys/src/cmd/diff/test/merge-t10.c
Normal file
10
sys/src/cmd/diff/test/merge-t10.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
10
sys/src/cmd/diff/test/merge-t10.expected
Normal file
10
sys/src/cmd/diff/test/merge-t10.expected
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
y
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
10
sys/src/cmd/diff/test/merge-t10.l
Normal file
10
sys/src/cmd/diff/test/merge-t10.l
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
y
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
10
sys/src/cmd/diff/test/merge-t10.r
Normal file
10
sys/src/cmd/diff/test/merge-t10.r
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
y
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
10
sys/src/cmd/diff/test/merge-t11.c
Normal file
10
sys/src/cmd/diff/test/merge-t11.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
12
sys/src/cmd/diff/test/merge-t11.expected
Normal file
12
sys/src/cmd/diff/test/merge-t11.expected
Normal file
|
@ -0,0 +1,12 @@
|
|||
A
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
y
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
Z
|
12
sys/src/cmd/diff/test/merge-t11.l
Normal file
12
sys/src/cmd/diff/test/merge-t11.l
Normal file
|
@ -0,0 +1,12 @@
|
|||
A
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
y
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
Z
|
10
sys/src/cmd/diff/test/merge-t11.r
Normal file
10
sys/src/cmd/diff/test/merge-t11.r
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
y
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/rc
|
||||
|
||||
tests=`{seq 9}
|
||||
tests=`{seq 11}
|
||||
for(t in $tests){
|
||||
echo ../$O.merge3 merge-t$t.l merge-t$t.c merge-t$t.r
|
||||
../$O.merge3 merge-t$t.l merge-t$t.c merge-t$t.r > merge-t$t.out
|
||||
|
|
Loading…
Reference in a new issue