# HG changeset patch # User Alexis S. L. Carvalho # Date 2007-01-30 21:09:08 # Node ID e7282dede8cd6b0a5b18a2c76e7f2a223d3d1f88 # Parent 3600b84656d335e6d847440247b7ff3f46512f4c filecommit: don't forget the local parent on a merge with a local rename diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -607,6 +607,24 @@ class localrepository(repo.repository): meta = {} cp = self.dirstate.copied(fn) if cp: + # Mark the new revision of this file as a copy of another + # file. This copy data will effectively act as a parent + # of this new revision. If this is a merge, the first + # parent will be the nullid (meaning "look up the copy data") + # and the second one will be the other parent. For example: + # + # 0 --- 1 --- 3 rev1 changes file foo + # \ / rev2 renames foo to bar and changes it + # \- 2 -/ rev3 should have bar with all changes and + # should record that bar descends from + # bar in rev2 and foo in rev1 + # + # this allows this merge to succeed: + # + # 0 --- 1 --- 3 rev4 reverts the content change from rev2 + # \ / merging rev3 and rev4 should use bar@rev2 + # \- 2 --- 4 as the merge base + # meta["copy"] = cp if not manifest2: # not a branch merge meta["copyrev"] = hex(manifest1.get(cp, nullid)) @@ -615,7 +633,7 @@ class localrepository(repo.repository): meta["copyrev"] = hex(manifest1.get(cp, nullid)) elif fp1 != nullid: # copied on local side, reversed meta["copyrev"] = hex(manifest2.get(cp)) - fp2 = nullid + fp2 = fp1 else: # directory rename meta["copyrev"] = hex(manifest1.get(cp, nullid)) self.ui.debug(_(" %s: copy %s:%s\n") % diff --git a/tests/test-merge-commit b/tests/test-merge-commit new file mode 100755 --- /dev/null +++ b/tests/test-merge-commit @@ -0,0 +1,77 @@ +#!/bin/sh +# check that renames are correctly saved by a commit after a merge + +HGMERGE=merge +export HGMERGE + +# test with the merge on 3 having the rename on the local parent +hg init a +cd a + +echo line1 > foo +hg add foo +hg ci -m '0: add foo' -d '0 0' + +echo line2 >> foo +hg ci -m '1: change foo' -d '0 0' + +hg up -C 0 +hg mv foo bar +rm bar +echo line0 > bar +echo line1 >> bar +hg ci -m '2: mv foo bar; change bar' -d '0 0' + +hg merge 1 +echo '% contents of bar should be line0 line1 line2' +cat bar +hg ci -m '3: merge with local rename' -d '0 0' +hg debugindex .hg/store/data/bar.i +hg debugrename bar +hg debugindex .hg/store/data/foo.i + +# revert the content change from rev 2 +hg up -C 2 +rm bar +echo line1 > bar +hg ci -m '4: revert content change from rev 2' -d '0 0' + +hg log --template '#rev#:#node|short# #parents#\n' +echo '% this should use bar@rev2 as the ancestor' +hg --debug merge 3 +echo '% contents of bar should be line1 line2' +cat bar +hg ci -m '5: merge' -d '0 0' +hg debugindex .hg/store/data/bar.i + + +# same thing, but with the merge on 3 having the rename on the remote parent +echo +echo +cd .. +hg clone -U -r 1 -r 2 a b +cd b + +hg up -C 1 +hg merge 2 +echo '% contents of bar should be line0 line1 line2' +cat bar +hg ci -m '3: merge with remote rename' -d '0 0' +hg debugindex .hg/store/data/bar.i +hg debugrename bar +hg debugindex .hg/store/data/foo.i + +# revert the content change from rev 2 +hg up -C 2 +rm bar +echo line1 > bar +hg ci -m '4: revert content change from rev 2' -d '0 0' + +hg log --template '#rev#:#node|short# #parents#\n' +echo '% this should use bar@rev2 as the ancestor' +hg --debug merge 3 +echo '% contents of bar should be line1 line2' +cat bar +hg ci -m '5: merge' -d '0 0' +hg debugindex .hg/store/data/bar.i + diff --git a/tests/test-merge-commit.out b/tests/test-merge-commit.out new file mode 100644 --- /dev/null +++ b/tests/test-merge-commit.out @@ -0,0 +1,83 @@ +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +merging bar and foo +0 files updated, 1 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +% contents of bar should be line0 line1 line2 +line0 +line1 +line2 + rev offset length base linkrev nodeid p1 p2 + 0 0 77 0 2 da78c0659611 000000000000 000000000000 + 1 77 76 0 3 4b358025380b 000000000000 da78c0659611 +bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2 + rev offset length base linkrev nodeid p1 p2 + 0 0 7 0 0 690b295714ae 000000000000 000000000000 + 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +4:2d2f9a22c82b 2:0a3ab4856510 +3:7d3b554bfdf1 2:0a3ab4856510 1:5cd961e4045d +2:0a3ab4856510 0:2665aaee66e9 +1:5cd961e4045d +0:2665aaee66e9 +% this should use bar@rev2 as the ancestor +resolving manifests + overwrite None partial False + ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 7d3b554bfdf1 + bar: versions differ -> m +merging bar +my bar@2d2f9a22c82b+ other bar@7d3b554bfdf1 ancestor bar@0a3ab4856510 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +% contents of bar should be line1 line2 +line1 +line2 + rev offset length base linkrev nodeid p1 p2 + 0 0 77 0 2 da78c0659611 000000000000 000000000000 + 1 77 76 0 3 4b358025380b 000000000000 da78c0659611 + 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000 + 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b + + +requesting all changes +adding changesets +adding manifests +adding file changes +added 3 changesets with 3 changes to 2 files (+1 heads) +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +merging foo and bar +0 files updated, 1 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +% contents of bar should be line0 line1 line2 +line0 +line1 +line2 + rev offset length base linkrev nodeid p1 p2 + 0 0 77 0 2 da78c0659611 000000000000 000000000000 + 1 77 76 0 3 4b358025380b 000000000000 da78c0659611 +bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2 + rev offset length base linkrev nodeid p1 p2 + 0 0 7 0 0 690b295714ae 000000000000 000000000000 + 1 7 13 1 1 9e25c27b8757 690b295714ae 000000000000 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +4:2d2f9a22c82b 2:0a3ab4856510 +3:96ab80c60897 1:5cd961e4045d 2:0a3ab4856510 +2:0a3ab4856510 0:2665aaee66e9 +1:5cd961e4045d +0:2665aaee66e9 +% this should use bar@rev2 as the ancestor +resolving manifests + overwrite None partial False + ancestor 0a3ab4856510 local 2d2f9a22c82b+ remote 96ab80c60897 + bar: versions differ -> m +merging bar +my bar@2d2f9a22c82b+ other bar@96ab80c60897 ancestor bar@0a3ab4856510 +0 files updated, 1 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +% contents of bar should be line1 line2 +line1 +line2 + rev offset length base linkrev nodeid p1 p2 + 0 0 77 0 2 da78c0659611 000000000000 000000000000 + 1 77 76 0 3 4b358025380b 000000000000 da78c0659611 + 2 153 7 2 4 4defe5eec418 da78c0659611 000000000000 + 3 160 13 3 5 4663501da27b 4defe5eec418 4b358025380b