X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=xdiff%2Fxmerge.c;h=b83b3348cc3aab66b13cb565a0a0fabaef4b689b;hb=ab002e34e26c39a716dc80359450f739ba907122;hp=286f177b542811f67fc77f633445a12cb1b5f198;hpb=53a7085a104936aef29400369aab15e0d1ccbb28;p=git.git diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c index 286f177b5..b83b3348c 100644 --- a/xdiff/xmerge.c +++ b/xdiff/xmerge.c @@ -38,8 +38,9 @@ static int xdl_append_merge(xdmerge_t **merge, int mode, long i1, long chg1, long i2, long chg2) { xdmerge_t *m = *merge; - if (m && mode == m->mode && - (i1 == m->i1 + m->chg1 || i2 == m->i2 + m->chg2)) { + if (m && (i1 <= m->i1 + m->chg1 || i2 <= m->i2 + m->chg2)) { + if (mode != m->mode) + m->mode = 0; m->chg1 = i1 + chg1 - m->i1; m->chg2 = i2 + chg2 - m->i2; } else { @@ -165,6 +166,8 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1, size += xdl_recs_copy(xe2, m->i2 - m->i1 + i1, m->i1 + m->chg2 - i1, 0, dest ? dest + size : NULL); + else + continue; i1 = m->i1 + m->chg1; } size += xdl_recs_copy(xe1, i1, xe1->xdf2.nrec - i1, 0, @@ -189,16 +192,20 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m, if (m->mode) continue; + /* no sense refining a conflict when one side is empty */ + if (m->chg1 == 0 || m->chg2 == 0) + continue; + /* * This probably does not work outside git, since * we have a very simple mmfile structure. */ t1.ptr = (char *)xe1->xdf2.recs[m->i1]->ptr; - t1.size = xe1->xdf2.recs[m->i1 + m->chg1]->ptr - + xe1->xdf2.recs[m->i1 + m->chg1]->size - t1.ptr; - t2.ptr = (char *)xe2->xdf2.recs[m->i1]->ptr; - t2.size = xe2->xdf2.recs[m->i1 + m->chg1]->ptr - + xe2->xdf2.recs[m->i1 + m->chg1]->size - t2.ptr; + t1.size = xe1->xdf2.recs[m->i1 + m->chg1 - 1]->ptr + + xe1->xdf2.recs[m->i1 + m->chg1 - 1]->size - t1.ptr; + t2.ptr = (char *)xe2->xdf2.recs[m->i2]->ptr; + t2.size = xe2->xdf2.recs[m->i2 + m->chg2 - 1]->ptr + + xe2->xdf2.recs[m->i2 + m->chg2 - 1]->size - t2.ptr; if (xdl_do_diff(&t1, &t2, xpp, &xe) < 0) return -1; if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 || @@ -208,9 +215,10 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m, return -1; } if (!xscr) { - /* If this happens, it's a bug. */ + /* If this happens, the changes are identical. */ xdl_free_env(&xe); - return -2; + m->mode = 4; + continue; } x = xscr; m->i1 = xscr->i1 + i1; @@ -313,22 +321,10 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1, i1 = xscr1->i1 + xscr1->chg1; i2 = xscr2->i1 + xscr2->chg1; - if (i1 > i2) { - xscr1->chg1 -= i1 - i2; - xscr1->i1 = i2; - xscr1->i2 += xscr1->chg2; - xscr1->chg2 = 0; - xscr1 = xscr1->next; - } else if (i2 > i1) { - xscr2->chg1 -= i2 - i1; - xscr2->i1 = i1; - xscr2->i2 += xscr2->chg2; - xscr2->chg2 = 0; + if (i1 >= i2) xscr2 = xscr2->next; - } else { + if (i2 >= i1) xscr1 = xscr1->next; - xscr2 = xscr2->next; - } } while (xscr1) { if (!changes)