]> git.neil.brown.name Git - wiggle.git/commitdiff
Improve handling of hunk-header when merging.
authorNeil Brown <neilb@suse.de>
Tue, 8 May 2012 07:09:07 +0000 (17:09 +1000)
committerNeil Brown <neilb@suse.de>
Tue, 8 May 2012 07:09:07 +0000 (17:09 +1000)
If we are merging a patch, the patch will contain a number of
hunk-headers (essentially the @@ NN,MM @@) lines.

These should never appear in the merge, and must always line up with
end-of-line in the original as they represent a number of lines having
been deleted.

So:
  Cause these to each create a simple Extraneous merger, never
    combined with adjacent texts

  exclude them from any conflicts in isolate_conflict, so they
    can never appear in a merge

  Ensure that a preceeding 'Unmatched' finishes on an end-of-line.

Also update lots of self tests with improved results.

Signed-off-by: NeilBrown <neilb@suse.de>
merge2.c
tests/linux/idmap.h/merge
tests/linux/md-resync/merge
tests/linux/raid5line/lmerge
tests/linux/raid5line/merge
tests/linux/raid5line/wmerge
tests/simple/trivial-conflict/merge

index 83be6f16aec9c01c2fc80b9606a76e2099272e39..3b4a96bc754053501036b842d369f3df94b8f685 100644 (file)
--- a/merge2.c
+++ b/merge2.c
@@ -131,6 +131,10 @@ static int isolate_conflicts(struct file af, struct file bf, struct file cf,
                        m[i].in_conflict = 1;
                        j = i;
                        while (--j >= 0) {
+                               if (m[j].type == Extraneous &&
+                                   bf.list[m[j].b].start[0] == '\0')
+                                       /* hunk header - not conflict any more */
+                                       break;
                                if (!m[j].in_conflict) {
                                        m[j].in_conflict = 1;
                                        m[j].lo = 0;
@@ -179,6 +183,10 @@ static int isolate_conflicts(struct file af, struct file bf, struct file cf,
 
                        /* now the forward search */
                        for (j = i+1; m[j].type != End; j++) {
+                               if (m[j].type == Extraneous &&
+                                   bf.list[m[j].b].start[0] == '\0')
+                                       /* hunk header - not conflict any more */
+                                       break;
                                m[j].in_conflict = 1;
                                if (m[j].type == Unchanged || m[j].type == Changed) {
                                        m[j].hi = m[j].al;
@@ -266,10 +274,22 @@ struct ci make_merger(struct file af, struct file bf, struct file cf,
                rv.merger[i].in_conflict = 0;
 
                if (!match1 && match2) {
-                       if (a < csl1[c1].a) {
+                       /* This is either Unmatched or Extraneous - probably both.
+                        * If the match2 is a hunk-header Extraneous, it must
+                        * align with an end-of-line in 'a', so adjust endpoint
+                        */
+                       int newa = csl1[c1].a;
+                       if (bf.list[b].start && bf.list[b].start[0] == '\0') {
+                               while (newa > a &&
+                                      !ends_line(af.list[newa-1]))
+                                       newa--;
+                               while (newa < af.elcnt && !(newa == 0 || ends_line(af.list[newa-1])))
+                                       newa++;
+                       }
+                       if (a < newa) {
                                /* some unmatched text */
                                rv.merger[i].type = Unmatched;
-                               rv.merger[i].al = csl1[c1].a - a;
+                               rv.merger[i].al = newa - a;
                                rv.merger[i].bl = 0;
                                rv.merger[i].cl = 0;
                                wiggle_found++;
@@ -280,15 +300,19 @@ struct ci make_merger(struct file af, struct file bf, struct file cf,
                                /* some Extraneous text */
                                /* length is min of unmatched on left
                                 * and matched on right.
-                                * However a hunk-header is not allowed
-                                * in the middle of an extraneous section,
-                                * only at the start.
+                                * However a hunk-header must be an
+                                * Extraneous section by itself, so if this
+                                * start with one, the length is 1, and if
+                                * there is one in the middle, only take the
+                                * text up to there for now.
                                 */
                                rv.merger[i].type = Extraneous;
                                rv.merger[i].al = 0;
                                newb = b +
                                        min(csl1[c1].b - b,
                                            csl2[c2].len - (b-csl2[c2].a));
+                               if (bf.list[b].start[0] == '\0')
+                                       newb = b + 1;
                                for (j = b; j < newb; j++) {
                                        if (bf.list[j].start[0] == '\0') {
                                                if (wiggle_found > 1)
index 664ceea1a43b07eea77ec4c89c0125be8e2be54e..52028f884685c42e58d1a30773e35591950af1a5 100644 (file)
@@ -1,6 +1,5 @@
 <<<<<<<
 |||||||
-*** 55,6 **** 1
 #define IDMAP_STATUS_LOOKUPFAIL IDMAP_STATUS_FAIL
 
 
@@ -8,7 +7,6 @@
 #define IDMAP_NAMESZ  128
 
 =======
-*** 55,8 **** 1
 #define IDMAP_STATUS_LOOKUPFAIL IDMAP_STATUS_FAIL
 
 
index d6ff33e1924c1fd23e0f353d51d382a57add6aca..7960304fd9b8d79cbdbd4dbb667f8a2ea2aa91b4 100644 (file)
@@ -1538,7 +1538,8 @@ static void end_sync_write(struct buffer_head *bh, int uptodate)
                int size = bh->b_size;
                raid1_free_buf(r1_bh);
                sync_request_done(sect, mddev_to_conf(mddev));
-               md_done_sync(mddev,size>>9, uptodate    }
+               md_done_sync(mddev,size>>9, uptodate);
+       }
 }
 
 #define INVALID_LEVEL KERN_WARNING \
index ee56bcb0284b36b151871d72f3d54f43cfe121df..4d8dba6a3f1342b86ce540a8bcbea7fa09fb0c84 100644 (file)
@@ -1,9 +1,7 @@
-<<<<<<<
                clear_bit(BH_Uptodate, &sh->bh_cache[i]->b_state);
+<<<<<<<
 |||||||
-*** 1,1 **** 1
                clear_buffer_uptodate(sh->bh_cache[i]);
 =======
-*** 1,1 **** 1
                dev->flags = 0;
 >>>>>>>
index ee56bcb0284b36b151871d72f3d54f43cfe121df..e6ffa40530356eba6b711d03cd50598cd653503d 100644 (file)
@@ -1,9 +1,7 @@
 <<<<<<<
                clear_bit(BH_Uptodate, &sh->bh_cache[i]->b_state);
 |||||||
-*** 1,1 **** 1
                clear_buffer_uptodate(sh->bh_cache[i]);
 =======
-*** 1,1 **** 1
                dev->flags = 0;
 >>>>>>>
index a8464d924b4b05d12d633f2345e0d185cdc4732c..e0b1530c681eb9ceb0ebfe1d09551e4aaaae1e65 100644 (file)
@@ -1,3 +1 @@
-<<<---         clear_bit(BH_Uptodate, &|||*** 1,1 **** 1
-               clear_buffer_uptodate(===*** 1,1 **** 1
-               dev--->>>-><<<---->b_state|||===flags = 0--->>>;
+<<<---         clear_bit(BH_Uptodate, &|||             clear_buffer_uptodate(===               dev--->>>-><<<---->b_state|||===flags = 0--->>>;
index 8308b251619b9bb1f438aabd9243e34e639fa37f..4e532dfacdb27167a25493e44f49e5ea3cb95487 100644 (file)
@@ -1,9 +1,7 @@
 <<<<<<<
 c
 |||||||
-*** 1,1 **** 1
 a
 =======
-*** 1,1 **** 1
 b
 >>>>>>>