ref: c59eb6d117c6dc99bc6e4330d3a9a3453888dee7
parent: 4364b71cccf8353dc8f65a5e0db4041f6a0a1e53
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jan 20 21:44:42 EST 2024
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.
--- a/sys/src/cmd/diff/diff.h
+++ b/sys/src/cmd/diff/diff.h
@@ -57,6 +57,7 @@
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 freediff(Diff *);
void flushchanges(Diff *);
void fetch(Diff *d, long *f, int a, int b, Biobuf *bp, char *s);
+int readline(Biobuf*, char*, int);
--- a/sys/src/cmd/diff/diffio.c
+++ b/sys/src/cmd/diff/diffio.c
@@ -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 @@
* 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 @@
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 @@
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 @@
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 @@
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 @@
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");
--- a/sys/src/cmd/diff/merge3.c
+++ b/sys/src/cmd/diff/merge3.c
@@ -58,6 +58,33 @@
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 @@
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++;
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t10.c
@@ -1,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t10.expected
@@ -1,0 +1,10 @@
+1
+2
+3
+4
+y
+6
+7
+8
+9
+10
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t10.l
@@ -1,0 +1,10 @@
+1
+2
+3
+4
+y
+6
+7
+8
+9
+10
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t10.r
@@ -1,0 +1,10 @@
+1
+2
+3
+4
+y
+6
+7
+8
+9
+10
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t11.c
@@ -1,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t11.expected
@@ -1,0 +1,12 @@
+A
+1
+2
+3
+4
+y
+6
+7
+8
+9
+10
+Z
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t11.l
@@ -1,0 +1,12 @@
+A
+1
+2
+3
+4
+y
+6
+7
+8
+9
+10
+Z
--- /dev/null
+++ b/sys/src/cmd/diff/test/merge-t11.r
@@ -1,0 +1,10 @@
+1
+2
+3
+4
+y
+6
+7
+8
+9
+10
--- a/sys/src/cmd/diff/test/merge.rc
+++ b/sys/src/cmd/diff/test/merge.rc
@@ -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