Mercurial > public > mercurial-scm > hg-stable
changeset 52989:688665425496
diff: add a --ignore-changes-from-ancestors option
This is a generalisation of the new feature from evolve but for any diff, it
allow to compares changes to patches regardless of the changes introduced by
ancestors, this is typically useful after rebase and graft.
I am not very happy about the name, but it is still experimental, so that can
be improved later.
Having the ability to compare ranges of commit would probably be handy too, but
this changeset focus in getting the basic case in. We have to think about the
UI a bit ahead however.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 03 Feb 2023 11:01:23 +0100 |
parents | 3ced516694ad |
children | 5ec596c91086 |
files | mercurial/commands.py tests/test-completion.t tests/test-diff-patches.t |
diffstat | 3 files changed, 502 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/commands.py Tue Feb 18 15:33:51 2025 +0100 +++ b/mercurial/commands.py Fri Feb 03 11:01:23 2023 +0100 @@ -27,6 +27,7 @@ bundlecaches, changegroup, cmdutil, + context as contextmod, copies, debugcommands as debugcommandsmod, destutil, @@ -2540,6 +2541,14 @@ (b'', b'from', b'', _(b'revision to diff from'), _(b'REV1')), (b'', b'to', b'', _(b'revision to diff to'), _(b'REV2')), (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')), + ( + b'', + b'ignore-changes-from-ancestors', + False, + _( + b'only compare the change made by the selected revision (EXPERIMENTAL)' + ), + ), ] + diffopts + diffopts2 @@ -2621,6 +2630,7 @@ to_rev = opts.get(b'to') stat = opts.get(b'stat') reverse = opts.get(b'reverse') + patch_only = opts.get(b'ignore_changes_from_ancestors') cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change']) cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change']) @@ -2638,6 +2648,30 @@ repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn') ctx1, ctx2 = logcmdutil.revpair(repo, revs) + if patch_only and ctx1.p1() != ctx2.p1(): + old_base = ctx1.p1() + new_base = ctx2.p1() + new_ctx = contextmod.overlayworkingctx(repo) + new_ctx.setbase(ctx1) + configoverrides = { + (b'ui', b'forcemerge'): b'internal:merge3-lie-about-conflicts' + } + with ui.configoverride(configoverrides, b'obslog-diff'), ui.silent(): + mergemod._update( + repo, + new_base, + labels=[ + b'from', + b'parent-of-to', + b'parent-of-from', + ], + force=True, + branchmerge=True, + wc=new_ctx, + ancestor=old_base, + ) + ctx1 = new_ctx.tomemctx(text=ctx1.description()) + if reverse: ctxleft = ctx2 ctxright = ctx1
--- a/tests/test-completion.t Tue Feb 18 15:33:51 2025 +0100 +++ b/tests/test-completion.t Fri Feb 03 11:01:23 2023 +0100 @@ -358,7 +358,7 @@ debugwhyunstable: debugwireargs: three, four, five, ssh, remotecmd, insecure debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure - diff: rev, from, to, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos + diff: rev, from, to, change, ignore-changes-from-ancestors, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template files: rev, print0, include, exclude, template, subrepos forget: interactive, include, exclude, dry-run
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-diff-patches.t Fri Feb 03 11:01:23 2023 +0100 @@ -0,0 +1,467 @@ +============================================================= +Testing comparing changeset regardless of change from parents +============================================================= + +Setup +===== + +Add a bunch of changes some related to each other some not. + + $ hg init test-repo + $ cd test-repo + $ cat << EOF > file-a.txt + > one + > two + > three + > four + > five + > six + > seven + > eight + > nine + > ten + > EOF + $ hg add file-a.txt + $ hg commit -m 'commit_root' + + $ sed s/two/deux/ file-a.txt > a + $ mv a file-a.txt + $ hg commit -m 'commit_A1_change' + + $ sed s/five/cinq/ file-a.txt > a + $ mv a file-a.txt + $ hg commit -m 'commit_A2_change' + + $ cat << EOF > file-b.txt + > egg + > salade + > orange + > EOF + $ hg add file-b.txt + $ hg commit -m 'commit_A3_change' + + $ cat << EOF > file-b.txt + > butter + > egg + > salade + > orange + > EOF + $ hg commit -m 'commit_A4_change' + + $ hg up 'desc("commit_root")' + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ sed s/two/deux/ file-a.txt > a + $ mv a file-a.txt + $ sed s/ten/dix/ file-a.txt > a + $ mv a file-a.txt + $ hg commit -m 'commit_B1_change' + created new head + + $ sed s/five/funf/ file-a.txt > a + $ mv a file-a.txt + $ sed s/eight/acht/ file-a.txt > a + $ mv a file-a.txt + $ hg commit -m 'commit_B2_change' + + $ cat << EOF > file-b.txt + > milk + > egg + > salade + > apple + > EOF + $ hg add file-b.txt + $ hg commit -m 'commit_B3_change' + + $ cat << EOF > file-b.txt + > butter + > milk + > egg + > salade + > apple + > EOF + $ hg commit -m 'commit_B4_change' + + $ hg log -G --patch + @ changeset: 8:0d6b02d59faf + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commit_B4_change + | + | diff -r 59c9679fd24c -r 0d6b02d59faf file-b.txt + | --- a/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + | +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + | @@ -1,3 +1,4 @@ + | +butter + | milk + | egg + | salade + | + o changeset: 7:59c9679fd24c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commit_B3_change + | + | diff -r 1e73118ddc3a -r 59c9679fd24c file-b.txt + | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 + | +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + | @@ -0,0 +1,4 @@ + | +milk + | +egg + | +salade + | +apple + | + o changeset: 6:1e73118ddc3a + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commit_B2_change + | + | diff -r 30a40f18d81e -r 1e73118ddc3a file-a.txt + | --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | @@ -2,9 +2,9 @@ + | deux + | three + | four + | -five + | +funf + | six + | seven + | -eight + | +acht + | nine + | dix + | + o changeset: 5:30a40f18d81e + | parent: 0:9c17110ca844 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commit_B1_change + | + | diff -r 9c17110ca844 -r 30a40f18d81e file-a.txt + | --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | @@ -1,5 +1,5 @@ + | one + | -two + | +deux + | three + | four + | five + | @@ -7,4 +7,4 @@ + | seven + | eight + | nine + | -ten + | +dix + | + | o changeset: 4:e6f5655bdf2e + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: commit_A4_change + | | + | | diff -r 074ad64f5cd7 -r e6f5655bdf2e file-b.txt + | | --- a/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + | | +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + | | @@ -1,3 +1,4 @@ + | | +butter + | | egg + | | salade + | | orange + | | + | o changeset: 3:074ad64f5cd7 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: commit_A3_change + | | + | | diff -r 37c330f02452 -r 074ad64f5cd7 file-b.txt + | | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 + | | +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + | | @@ -0,0 +1,3 @@ + | | +egg + | | +salade + | | +orange + | | + | o changeset: 2:37c330f02452 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: commit_A2_change + | | + | | diff -r 7bcbc987bcfe -r 37c330f02452 file-a.txt + | | --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | | +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | | @@ -2,7 +2,7 @@ + | | deux + | | three + | | four + | | -five + | | +cinq + | | six + | | seven + | | eight + | | + | o changeset: 1:7bcbc987bcfe + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: commit_A1_change + | + | diff -r 9c17110ca844 -r 7bcbc987bcfe file-a.txt + | --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + | @@ -1,5 +1,5 @@ + | one + | -two + | +deux + | three + | four + | five + | + o changeset: 0:9c17110ca844 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: commit_root + + diff -r 000000000000 -r 9c17110ca844 file-a.txt + --- /dev/null Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -0,0 +1,10 @@ + +one + +two + +three + +four + +five + +six + +seven + +eight + +nine + +ten + + +Then compare the resulting revisions: +==================================== + +A1 and B1 has the same parent, so the same output is expected. + + + $ hg diff --from 'desc("commit_A1_change")' --to 'desc("commit_B1_change")' + diff -r 7bcbc987bcfe -r 30a40f18d81e file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -7,4 +7,4 @@ + seven + eight + nine + -ten + +dix + $ hg diff --from 'desc("commit_A1_change")' --to 'desc("commit_B1_change")' --ignore-changes-from-ancestors + diff -r 7bcbc987bcfe -r 30a40f18d81e file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -7,4 +7,4 @@ + seven + eight + nine + -ten + +dix + +Skipping B1 change mean the final "ten" change is no longer part of the diff + + $ hg diff --from 'desc("commit_A1_change")' --to 'desc("commit_B2_change")' + diff -r 7bcbc987bcfe -r 1e73118ddc3a file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -2,9 +2,9 @@ + deux + three + four + -five + +funf + six + seven + -eight + +acht + nine + -ten + +dix + $ hg diff --from 'desc("commit_A1_change")' --to 'desc("commit_B2_change")' --ignore-changes-from-ancestors + diff -r 1e73118ddc3a file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -2,9 +2,9 @@ + deux + three + four + -five + +funf + six + seven + -eight + +acht + nine + dix + +Skipping A1 changes means the "two" changes introduced by "B1" (but also +present in A2 parent, A1) is back on the table. + + $ hg diff --from 'desc("commit_A2_change")' --to 'desc("commit_B1_change")' + diff -r 37c330f02452 -r 30a40f18d81e file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -2,9 +2,9 @@ + deux + three + four + -cinq + +five + six + seven + eight + nine + -ten + +dix + $ hg diff --from 'desc("commit_A2_change")' --to 'desc("commit_B1_change")' --ignore-changes-from-ancestors + diff -r 30a40f18d81e file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -1,10 +1,10 @@ + one + -two + +deux + three + four + -cinq + +five + six + seven + eight + nine + -ten + +dix + +All changes from A1 and B1 are no longer in the picture as we compare A2 and B2 + + $ hg diff --from 'desc("commit_A2_change")' --to 'desc("commit_B2_change")' + diff -r 37c330f02452 -r 1e73118ddc3a file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -2,9 +2,9 @@ + deux + three + four + -cinq + +funf + six + seven + -eight + +acht + nine + -ten + +dix + $ hg diff --from 'desc("commit_A2_change")' --to 'desc("commit_B2_change")' --ignore-changes-from-ancestors + diff -r 1e73118ddc3a file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -2,9 +2,9 @@ + deux + three + four + -cinq + +funf + six + seven + -eight + +acht + nine + dix + +Similar patches +--------------- + +comparing A3 and B3 patches is much more terse. focusing on the change to the +two similar patches, ignoring the rests of the changes (like comparing apples +and oranges) + + $ hg diff --from 'desc("commit_A3_change")' --to 'desc("commit_B3_change")' + diff -r 074ad64f5cd7 -r 59c9679fd24c file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -2,9 +2,9 @@ + deux + three + four + -cinq + +funf + six + seven + -eight + +acht + nine + -ten + +dix + diff -r 074ad64f5cd7 -r 59c9679fd24c file-b.txt + --- a/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -1,3 +1,4 @@ + +milk + egg + salade + -orange + +apple + $ hg diff --from 'desc("commit_A3_change")' --to 'desc("commit_B3_change")' --ignore-changes-from-ancestors + diff -r 59c9679fd24c file-b.txt + --- a/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -1,3 +1,4 @@ + +milk + egg + salade + -orange + +apple + + +Conflict handling +----------------- + +Conflict should not be a big deal and its resolution should be presented to the user. + + $ hg diff --from 'desc("commit_A4_change")' --to 'desc("commit_B4_change")' + diff -r e6f5655bdf2e -r 0d6b02d59faf file-a.txt + --- a/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-a.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -2,9 +2,9 @@ + deux + three + four + -cinq + +funf + six + seven + -eight + +acht + nine + -ten + +dix + diff -r e6f5655bdf2e -r 0d6b02d59faf file-b.txt + --- a/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -1,4 +1,5 @@ + butter + +milk + egg + salade + -orange + +apple + $ hg diff --from 'desc("commit_A4_change")' --to 'desc("commit_B4_change")' --ignore-changes-from-ancestors + diff -r 0d6b02d59faf file-b.txt + --- a/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + +++ b/file-b.txt Thu Jan 01 00:00:00 1970 +0000 + @@ -1,9 +1,5 @@ + -<<<<<<< from: e6f5655bdf2e - test: commit_A4_change + butter + -||||||| parent-of-from: 074ad64f5cd7 - test: commit_A3_change + -======= + milk + ->>>>>>> parent-of-to: 59c9679fd24c - test: commit_B3_change + egg + salade + apple