[Bug 5369] New: Merge copy tracing sometimes misses files moved/combined from multiple different paths

bugzilla at mercurial-scm.org bugzilla at mercurial-scm.org
Thu Sep 15 06:42:05 UTC 2016


https://bz.mercurial-scm.org/show_bug.cgi?id=5369

            Bug ID: 5369
           Summary: Merge copy tracing sometimes misses files
                    moved/combined from multiple different paths
           Product: Mercurial
           Version: 3.9.1
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: bug
          Priority: normal
         Component: Mercurial
          Assignee: bugzilla at selenic.com
          Reporter: gabor.stefanik at nng.com
                CC: mercurial-devel at selenic.com

When two different files are moved to the same filename in different commits,
and those two files are then combined in a subsequent merge commit, a situation
can arise where the resulting file has two rename ancestors.

Once this situation arises, changes to some of the ancestor files will fail to
be merged into the common descendant, instead Hg will ask to recreate the
ancestor file. Which files will merge properly, and which ones will ask for
recreation, is deterministic, but highly implementation-dependent.

The problem is that mergecopies returns copies in a dict that's essentially a
many-to-one mapping of copy targets to copy sources (i.e. each source can go to
multiple targets, but each target may come from only source). As this case
shows, the actual relationship between copy sources and copy targets is
many-to-many.

With bug 4028 fixed, this can also show up when the same file is copied to 2
different names in separate branches, the 2 branches are merged, and then a
graft is attempted backwards through the merged renames. In fact, this bug was
discovered during a review of the bug 4028 patchset.

Reproduction:

hg init test
cd test
for i in 1 2 3 4 5 6 7 8; do echo $i >> a; done
for i in a b c d e f g h; do echo $i >> b; done
hg add a b
hg ci -m initial
hg mv a c
hg ci -m 'a->c'
hg up 0
hg mv b c
hg ci -m 'b->c'
hg merge
<resolve the conflict so that both files' contents are preserved, numbers
first, then letters>
hg commit -m merge
hg up 0
for i in 0 1 2 3 4 5 6 7 8; do echo $i >> a; done
hg ci -m 0
hg up 0
for i in a b c d e f g h i; do echo $i >> b; done
hg ci -m i
hg up 3
hg merge 4 # works
hg ci -m goodmerge
hg up 3
hg merge 5 # fails, "other changed b which local deleted"

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Mercurial-devel mailing list