Bug 4192 - Rebase loses copy information
Summary: Rebase loses copy information
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: rebase (show other bugs)
Version: 2.9.1
Hardware: PC All
: normal bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-09 10:17 UTC by Granville Moore
Modified: 2020-01-24 00:01 UTC (History)
5 users (show)

See Also:
Python Version: ---


Attachments
Unified test file for quickly iterating on this problem. (1.83 KB, text/plain)
2014-06-07 14:19 UTC, Augie Fackler
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Granville Moore 2014-03-09 10:17 UTC
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 ..
Comment 1 Augie Fackler 2014-06-07 14:19 UTC
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.
Comment 2 Augie Fackler 2014-06-07 14:22 UTC
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.
Comment 3 HG Bot 2014-07-02 00:45 UTC
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)
Comment 4 HG Bot 2020-01-16 13:20 UTC
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)
Comment 5 Bugzilla 2020-01-24 00:01 UTC
Bug was set to TESTING for 7 days, resolving