Bug ID: 5371
           Summary: Inconsistent grafting behaviour for "hg graft" with
                    origins and their destinations
           Product: Mercurial
           Version: stable branch
          Hardware: PC
                OS: Linux
            Status: UNCONFIRMED
          Severity: bug
          Priority: wish
         Component: Mercurial

Given two revs 'a' and 'b' for which "destination(a) = b" and a third rev 'c'
to graft to:

"hg graft a && hg graft b"  will graft 'a' in the first run and skip 'b' with a
that it's already grafted.

However running "hg graft a b", will try to graft both without a warning.

Also after "hg graft a" onto c "hg graft b" or "hg graft a" will both skip,
however "hg graft a b"
will only skip b but try to graft a.


hg init;
touch a && hg add a && hg ci -ma;
touch aa && hg add aa && hg ci -maa;
hg update -r 0; #a 
touch ab && hg add ab && hg ci -mab;
hg update -r 0; #a
touch ac && hg add ac && hg ci -mac;
hg update -r 1; #aa
hg graft 2;
hg log -G;
hg update -r 3;

"hg log -G --template '{rev}: {desc}\n'
o  4: ab
| @  3: ac
| |
| | o  2: ab
| |/
o |  1: aa
o  0: a

First case: 

Running "hg graft 2 && hg graft 4" from this state gives: 
grafting 2:ad9a61009f92 "ab"
skipping already grafted revision 4:3be803d3419c (5:cea991ddcf20 also has
origin 2:ad9a61009f92)

Running "hg graft 2 4" from this state gives:
grafting 2:010db3795a82 "ab"
grafting 4:099239fefcb8 "ab" (tip)
note: graft of 4:099239fefcb8 created no changes to commit

Second case:

Running "hg graft 2 && hg graft 2; hg graft 4;" gives: 
grafting 2:efa7c40f520f "ab"
skipping revision 2:efa7c40f520f (already grafted to 5:9d16a67d5a26)
skipping already grafted revision 4:ce90f6b72b78 (5:9d16a67d5a26 also has
origin 2:efa7c40f520f)

Running "hg graft 2 && hg graft 2 4" gives:
grafting 2:00a645073646 "ab"
skipping revision 2:00a645073646 (already grafted to 5:d612afdb0ceb)
grafting 4:b2b4b47d2a4f "ab"
note: graft of 4:b2b4b47d2a4f created no changes to commit

This comes down to the following lines in `_dograft()` from

        ids = {}
        for ctx in repo.set("%ld", revs):
            ids[ctx.hex()] = ctx.rev()
            n = ctx.extra().get('source')
            if n:
                ids[n] = ctx.rev()

If `n` is already in `ids` it will replace it and afterwards there is no logic
to check for this case:

This could be fixed by writing sources into a seperate dict and then accounting
for the case that a rev is 
in both.

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

Reply via email to