If a repo contains sequence of "hg copy" operations, each copying the previous file to generate a new one, then an "hg log -vf" operation on the last file lists all of the preceding versions. After a rebase, however, only the first and last files in the chain are listed by "hg log -vf". A demonstration script and output are shown below. This was discovered due to its impact on TortoiseHG, where it prevents the "Compare File Revisions" tool from being able to compare all of the versions in the files history. This issue was discovered on version 2.4.2 and was tested (below) on the current development tip as of 9 March 2014, version 2.9.1+41-19e9478c1a22 (i.e. after bug 1423, bug 2642, bug 3729, bug 3739 and bug 4001 were marked as "RESOLVED FIXED"). These tests were performed the OpenIndiana OS. It was also tested on version 2.7.1 running on Windows, with the same results. In the test output below, rebase was the only plugin in use. -------------------- Test Script -------------------- set -x hg --version cat ~/.hgrc hg init test1 cd test1 cat >> .hg/hgrc <<EOF [extensions] rebase = EOF echo a > a ; hg add a ; hg commit -m"File a created" hg copy a b ; echo b > b ; hg commit -m"File b created as copy of a and modified" hg copy b c ; echo c > c ; hg commit -m"File c created as copy of b and modified" hg copy c d ; echo d > d ; hg commit -m"File d created as copy of c and modified" hg status --rev 0 --copies hg log -vf d echo "Note that there are four entries in the log for d" hg update 0 echo unrelated > unrelated ; hg add unrelated ; hg commit -m"Unrelated file created" hg update 4 hg rebase --source 1 --dest 4 hg update 4 hg status --rev 0 --copies hg log -vf d echo "Note that there are now only two entries in the log for d" cd .. -------------------- Test Output -------------------- + hg --version Mercurial Distributed SCM (version 2.9.1+41-19e9478c1a22) (see http://mercurial.selenic.com for more information) Copyright (C) 2005-2014 Matt Mackall and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + cat ~/.hgrc [ui] username = TestUser + hg init test1 + cd test1 + cat + echo a + hg add a + hg commit '-mFile a created' + hg copy a b + echo b + hg commit '-mFile b created as copy of a and modified' + hg copy b c + echo c + hg commit '-mFile c created as copy of b and modified' + hg copy c d + echo d + hg commit '-mFile d created as copy of c and modified' + hg status --rev 0 --copies A b a A c a A d a + hg log -vf d changeset: 3:cb57ce5564eb tag: tip user: TestUser date: Sun Mar 09 13:29:24 2014 +0000 files: d description: File d created as copy of c and modified changeset: 2:ccf1919ad985 user: TestUser date: Sun Mar 09 13:29:23 2014 +0000 files: c description: File c created as copy of b and modified changeset: 1:93f972e0211a user: TestUser date: Sun Mar 09 13:29:23 2014 +0000 files: b description: File b created as copy of a and modified changeset: 0:8bfac4b2d6c5 user: TestUser date: Sun Mar 09 13:29:22 2014 +0000 files: a description: File a created + echo 'Note that there are four entries in the log for d' Note that there are four entries in the log for d + hg update 0 0 files updated, 0 files merged, 3 files removed, 0 files unresolved + echo unrelated + hg add unrelated + hg commit '-mUnrelated file created' created new head + hg update 4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + hg rebase --source 1 --dest 4 merging c and d to d saved backup bundle to <path removed>/test1/.hg/strip-backup/93f972e0211a-backup.hg + hg update 4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + hg status --rev 0 --copies A b a A c a A d a A unrelated + hg log -vf d changeset: 4:07d17b77b27d tag: tip user: TestUser date: Sun Mar 09 13:29:24 2014 +0000 files: b c d description: File d created as copy of c and modified changeset: 0:8bfac4b2d6c5 user: TestUser date: Sun Mar 09 13:29:22 2014 +0000 files: a description: File a created + echo 'Note that there are now only two entries in the log for d' Note that there are now only two entries in the log for d + cd ..
Created attachment 1774 [details] Unified test file for quickly iterating on this problem. Looking a little bit. Bug confirmed on tip as of today. The defect seems to be that the copy-of-copy disappears. The first copy survives, but the copy of b to c fails, and then the copy of c to d also fails. Not yet sure why.
Oh, I see. It's a bug with how cmdutil.duplicatecopies() is invoked: we inspect the copies relative to the base of the rebased set, not the first parent of the current revision we're rebasing. This means we record a copy of a -> c during the rebase of r2 in the test, when it should have been a copy of b -> c.
Fixed by http://selenic.com/repo/hg/rev/2ba6c9b4e0eb Augie Fackler <raf@durin42.com> rebase: fix bug that caused transitive copy records to disappear (issue4192) The defect was that copies were always duplicated against the target revision, rather than the first parent of the revision being rebased. This produced nominally correct results if changes were rebased one at a time (or with --collapse), but was wrong if we rebased a sequence of changesets which contained a sequence of copies. (please test the fix)
Fixed by https://mercurial-scm.org/repo/hg/rev/833210fbd900 Martin von Zweigbergk <martinvonz@google.com> graftcopies: remove `skip` and `repo` arguments The `skip` argument was added in 2ba6c9b4e0eb (rebase: fix bug that caused transitive copy records to disappear (issue4192), 2014-06-07) in order to fix https://bz.mercurial-scm.org/show_bug.cgi?id=4192. I ran tests at that commit without the `skiprev` argument and the only difference I noticed was that `test-rebase-collapse.t` failed differently, in the call that is now on line 501. Without the `skiprev` argument, that call would end up creating another commit because it tried to record an invalid copy. With the previous patch in this series, such invalid copies are no longer recorded, so it seems we don't need the `skip` argument anymore. I also removed the `repo` argument since that also becomes unused with the removal of the `skip` argument. Differential Revision: https://phab.mercurial-scm.org/D7860 (please test the fix)
Bug was set to TESTING for 7 days, resolving