changeset 6889:a66cf9008781

obslog: also display patch for rebased changesets This applies the same logic that is used for "merge-diff" to rebased changesets. The successors' content is compared to the content of the predecessors rebased in-memory on the new parents. This highlights the changes that were actually introduced while rebasing (like conflict resolution or API adjustment). As a side effect, obslog now also outputs slightly more diffs for splits, showing what parts of the original big changeset were moved to the smaller split components (but for now it only works for the first few changesets).
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sun, 22 Sep 2024 02:58:54 +0200
parents 1e836ad40272
children 361dcfcb3f08
files hgext3rd/evolve/obshistory.py tests/test-evolve-obshistory-amend-then-fold.t tests/test-evolve-obshistory-fold.t tests/test-evolve-obshistory-lots-of-splits.t tests/test-evolve-obshistory-split.t tests/test-evolve-phase-divergence.t tests/test-evolve-public-content-divergent-corner-cases.t
diffstat 7 files changed, 183 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/hgext3rd/evolve/obshistory.py	Sun Sep 22 12:20:03 2024 +0200
+++ b/hgext3rd/evolve/obshistory.py	Sun Sep 22 02:58:54 2024 +0200
@@ -11,6 +11,7 @@
 
 from mercurial import (
     commands,
+    context,
     error,
     graphmod,
     logcmdutil,
@@ -29,6 +30,7 @@
 from mercurial.i18n import _
 
 from . import (
+    compat,
     exthelper,
 )
 
@@ -319,11 +321,15 @@
         self.reason = reason
         super(_NoPatchAvailable, self).__init__()
 
-def patchavailable(repo, node, candidates, successive=True):
-    """ Check if it's possible to get a diff between node and candidates.
+def prepare_patch(repo, node, candidates, successive=True):
+    """ Prepare 2 contexts for a diff between node and one of its candidates.
 
     `candidates` contains nodes, which can be either successors (`successive`
     is True) or predecessors (`successive` is False) of `node`.
+
+    Return a (from_ctx, to_ctx) tuple of contexts. One of these contexts could
+    be a result of in-memory rebase to align it with parents of the other
+    context.
     """
     if node not in repo:
         raise _NoPatchAvailable(b"context is not local")
@@ -350,14 +356,57 @@
             msg = b"predecessor is unknown locally"
         raise _NoPatchAvailable(msg)
 
+    node_ctx = repo[node]
+    cand_ctx = repo[cand]
+
     # Check that both node and cand have the same parents
-    nodep1, nodep2 = repo[node].p1(), repo[node].p2()
-    candp1, candp2 = repo[cand].p1(), repo[cand].p2()
+    nodep1, nodep2 = node_ctx.p1(), node_ctx.p2()
+    candp1, candp2 = cand_ctx.p1(), cand_ctx.p2()
+
+    if nodep1 != candp1:
+        # XXX the case when both p1 and p2 changed could be better.
+        #
+        # For simplicity if both parents change, we currently only reflect the
+        # impact on "p1" changeset. This should be improved at some point, but
+        # this is good enough for now.
+        cand_ctx = _rebase_cand(repo, cand_ctx, nodep1, candp1)
+    elif nodep2 != candp2:
+        cand_ctx = _rebase_cand(repo, cand_ctx, nodep2, candp2)
+    if successive:
+        return (node_ctx, cand_ctx)
+    else:
+        return (cand_ctx, node_ctx)
+
+
+def _rebase_cand(repo, ctx, old_base, new_base):
+    """return a view of ctx rebased in-memory from old_base to new_base
 
-    if nodep1 != candp1 or nodep2 != candp2:
-        raise _NoPatchAvailable(b"changesets rebased")
-
-    return cand
+    This can be used to produce a patch in obslog even when changesets were
+    rebased.
+    """
+    # XXX inspired by the diff.merge feature (mercurial.diffutil.diff_parent).
+    # We should move this logic to core.
+    base = context.overlayworkingctx(repo)
+    base.setbase(ctx)
+    configoverrides = {
+        (b'ui', b'forcemerge'): b'internal:merge3-lie-about-conflicts'
+    }
+    with repo.ui.configoverride(configoverrides, b'obslog-diff'):
+        with repo.ui.silent():
+            compat._update(
+                repo,
+                new_base,
+                labels=[
+                    b'predecessor',
+                    b'successor-parent',
+                    b'predecessor-parent',
+                ],
+                force=True,
+                branchmerge=True,
+                wc=base,
+                ancestor=old_base,
+            )
+    return base.tomemctx(text=ctx.description())
 
 def getmarkerdescriptionpatch(repo, basedesc, succdesc):
     # description are stored without final new line,
@@ -692,16 +741,10 @@
     if includediff is True:
 
         try:
-            diffnode = patchavailable(repo, node, nodes, successive=successive)
+            actx, bctx = prepare_patch(repo, node, nodes, successive=successive)
         except _NoPatchAvailable as exc:
             fm.data(nopatchreason=exc.reason)
         else:
-            if successive:
-                actx = repo[node]
-                bctx = repo[diffnode]
-            else:
-                actx = repo[diffnode]
-                bctx = repo[node]
             # Description patch
             descriptionpatch = getmarkerdescriptionpatch(repo,
                                                          actx.description(),
--- a/tests/test-evolve-obshistory-amend-then-fold.t	Sun Sep 22 12:20:03 2024 +0200
+++ b/tests/test-evolve-obshistory-amend-then-fold.t	Sun Sep 22 02:58:54 2024 +0200
@@ -101,7 +101,13 @@
   |
   x  b7ea6d14e664 (3) B1
   |    folded(description, parent, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
-  |      (No patch available, changesets rebased)
+  |      diff -r b7ea6d14e664 -r eb5a0daa2192+ changeset-description
+  |      --- a/changeset-description
+  |      +++ b/changeset-description
+  |      @@ -1,1 +1,1 @@
+  |      -B1
+  |      +C0
+  |
   |
   x  0dec01379d3b (2) B0
        reworded(description) as b7ea6d14e664 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
@@ -154,7 +160,13 @@
   |
   x  b7ea6d14e664 (3) B1
   |    folded(description, parent, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
-  |      (No patch available, changesets rebased)
+  |      diff -r b7ea6d14e664 -r eb5a0daa2192+ changeset-description
+  |      --- a/changeset-description
+  |      +++ b/changeset-description
+  |      @@ -1,1 +1,1 @@
+  |      -B1
+  |      +C0
+  |
   |
   x  0dec01379d3b (2) B0
        reworded(description) as b7ea6d14e664 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
--- a/tests/test-evolve-obshistory-fold.t	Sun Sep 22 12:20:03 2024 +0200
+++ b/tests/test-evolve-obshistory-fold.t	Sun Sep 22 02:58:54 2024 +0200
@@ -93,7 +93,13 @@
   |\
   x |  0dec01379d3b (2) B0
    /     folded(description, parent, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
+  |        diff -r 0dec01379d3b -r eb5a0daa2192+ changeset-description
+  |        --- a/changeset-description
+  |        +++ b/changeset-description
+  |        @@ -1,1 +1,1 @@
+  |        -B0
+  |        +C0
+  |
   |
   x  471f378eab4c (1) A0
        folded(description, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
@@ -116,7 +122,13 @@
   $ hg obslog --hidden 0dec01379d3b --patch --no-origin
   x  0dec01379d3b (2) B0
        folded(description, parent, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
-         (No patch available, changesets rebased)
+         diff -r 0dec01379d3b -r eb5a0daa2192+ changeset-description
+         --- a/changeset-description
+         +++ b/changeset-description
+         @@ -1,1 +1,1 @@
+         -B0
+         +C0
+  
   
 Check that with all option, all changesets are shown
   $ hg obslog --hidden --all 0dec01379d3b --patch --no-origin
@@ -124,7 +136,13 @@
   |\
   x |  0dec01379d3b (2) B0
    /     folded(description, parent, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
+  |        diff -r 0dec01379d3b -r eb5a0daa2192+ changeset-description
+  |        --- a/changeset-description
+  |        +++ b/changeset-description
+  |        @@ -1,1 +1,1 @@
+  |        -B0
+  |        +C0
+  |
   |
   x  471f378eab4c (1) A0
        folded(description, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
@@ -148,7 +166,13 @@
   |\
   x |  0dec01379d3b (2) B0
    /     folded(description, parent, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
+  |        diff -r 0dec01379d3b -r eb5a0daa2192+ changeset-description
+  |        --- a/changeset-description
+  |        +++ b/changeset-description
+  |        @@ -1,1 +1,1 @@
+  |        -B0
+  |        +C0
+  |
   |
   x  471f378eab4c (1) A0
        folded(description, content) as eb5a0daa2192 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
--- a/tests/test-evolve-obshistory-lots-of-splits.t	Sun Sep 22 12:20:03 2024 +0200
+++ b/tests/test-evolve-obshistory-lots-of-splits.t	Sun Sep 22 02:58:54 2024 +0200
@@ -194,7 +194,12 @@
   $ hg obslog de7290d8b885 --hidden --all --patch
   o  1ae8bc733a14 (4) A0
   |    split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |      (No patch available, changesets rebased)
+  |      diff -r 1ae8bc733a14 d
+  |      --- a/d	Thu Jan 01 00:00:00 1970 +0000
+  |      +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |      @@ -1,1 +0,0 @@
+  |      -45
+  |
   |
   | o  337fec4d2edc (2) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
@@ -217,11 +222,20 @@
   |
   | @  c7f044602e9b (5) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
   |
   | o  f257fde29c7a (3) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
+  |        diff -r f257fde29c7a c
+  |        --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +0,0 @@
+  |        -44
+  |        diff -r f257fde29c7a d
+  |        --- a/d	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +0,0 @@
+  |        -45
+  |
   |
   x  de7290d8b885 (1) A0
   
@@ -269,7 +283,6 @@
   $ hg obslog c7f044602e9b --patch
   @  c7f044602e9b (5) A0
   |    split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |      (No patch available, changesets rebased)
   |
   x  de7290d8b885 (1) A0
   
@@ -365,7 +378,12 @@
   $ hg obslog 2::5 --patch
   o  1ae8bc733a14 (4) A0
   |    split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |      (No patch available, changesets rebased)
+  |      diff -r 1ae8bc733a14 d
+  |      --- a/d	Thu Jan 01 00:00:00 1970 +0000
+  |      +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |      @@ -1,1 +0,0 @@
+  |      -45
+  |
   |
   | o  337fec4d2edc (2) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
@@ -388,11 +406,20 @@
   |
   | @  c7f044602e9b (5) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
   |
   | o  f257fde29c7a (3) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
+  |        diff -r f257fde29c7a c
+  |        --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +0,0 @@
+  |        -44
+  |        diff -r f257fde29c7a d
+  |        --- a/d	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +0,0 @@
+  |        -45
+  |
   |
   x  de7290d8b885 (1) A0
   
@@ -412,7 +439,12 @@
   $ hg obslog 5 --all --patch
   o  1ae8bc733a14 (4) A0
   |    split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |      (No patch available, changesets rebased)
+  |      diff -r 1ae8bc733a14 d
+  |      --- a/d	Thu Jan 01 00:00:00 1970 +0000
+  |      +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |      @@ -1,1 +0,0 @@
+  |      -45
+  |
   |
   | o  337fec4d2edc (2) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
@@ -435,11 +467,20 @@
   |
   | @  c7f044602e9b (5) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
   |
   | o  f257fde29c7a (3) A0
   |/     split(parent, content) from de7290d8b885 using split by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
+  |        diff -r f257fde29c7a c
+  |        --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +0,0 @@
+  |        -44
+  |        diff -r f257fde29c7a d
+  |        --- a/d	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +0,0 @@
+  |        -45
+  |
   |
   x  de7290d8b885 (1) A0
   
--- a/tests/test-evolve-obshistory-split.t	Sun Sep 22 12:20:03 2024 +0200
+++ b/tests/test-evolve-obshistory-split.t	Sun Sep 22 02:58:54 2024 +0200
@@ -182,7 +182,6 @@
   | @  f257fde29c7a (3) A0
   |/     split(parent, content) from 471597cad322 using split by test (Thu Jan 01 00:00:00 1970 +0000)
   |        note: testing split
-  |        (No patch available, changesets rebased)
   |
   x  471597cad322 (1) A0
   
@@ -192,7 +191,6 @@
   @  f257fde29c7a (3) A0
   |    split(parent, content) from 471597cad322 using split by test (Thu Jan 01 00:00:00 1970 +0000)
   |      note: testing split
-  |      (No patch available, changesets rebased)
   |
   x  471597cad322 (1) A0
   
@@ -211,7 +209,6 @@
   | @  f257fde29c7a (3) A0
   |/     split(parent, content) from 471597cad322 using split by test (Thu Jan 01 00:00:00 1970 +0000)
   |        note: testing split
-  |        (No patch available, changesets rebased)
   |
   x  471597cad322 (1) A0
   
@@ -251,7 +248,6 @@
   | @  f257fde29c7a (3) A0
   |/     split(parent, content) from 471597cad322 using split by test (Thu Jan 01 00:00:00 1970 +0000)
   |        note: testing split
-  |        (No patch available, changesets rebased)
   |
   x  471597cad322 (1) A0
   
--- a/tests/test-evolve-phase-divergence.t	Sun Sep 22 12:20:03 2024 +0200
+++ b/tests/test-evolve-phase-divergence.t	Sun Sep 22 02:58:54 2024 +0200
@@ -1832,7 +1832,14 @@
   $ hg obslog --patch
   @  9eebcb77a7e2 (3) phase-divergent update to 3074c7249d20:
   |    rewritten(description, parent, content) from 599454370881 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  |      (No patch available, changesets rebased)
+  |      diff -r 599454370881+ -r 9eebcb77a7e2 changeset-description
+  |      --- a/changeset-description
+  |      +++ b/changeset-description
+  |      @@ -1,1 +1,3 @@
+  |      +phase-divergent update to 3074c7249d20:
+  |      +
+  |       E2
+  |
   |
   x  599454370881 (2) E2
   |    rewritten(description, content) from 3074c7249d20 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
--- a/tests/test-evolve-public-content-divergent-corner-cases.t	Sun Sep 22 12:20:03 2024 +0200
+++ b/tests/test-evolve-public-content-divergent-corner-cases.t	Sun Sep 22 02:58:54 2024 +0200
@@ -382,7 +382,30 @@
   |
   | *  e568fd1029bb (4) added c e
   |/     rewritten(description, parent, content) from 9150fe93bec6 using prune by test (Thu Jan 01 00:00:00 1970 +0000)
-  |        (No patch available, changesets rebased)
+  |        diff -r 9150fe93bec6+ -r e568fd1029bb changeset-description
+  |        --- a/changeset-description
+  |        +++ b/changeset-description
+  |        @@ -1,1 +1,1 @@
+  |        -added d
+  |        +added c e
+  |
+  |        diff -r e568fd1029bb c
+  |        --- a/c	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ b/c	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +1,1 @@
+  |        -c
+  |        +cfoo
+  |        diff -r e568fd1029bb d
+  |        --- a/d	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -1,1 +0,0 @@
+  |        -dd
+  |        diff -r e568fd1029bb e
+  |        --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  |        +++ b/e	Thu Jan 01 00:00:00 1970 +0000
+  |        @@ -0,0 +1,1 @@
+  |        +e
+  |
   |
   x  9150fe93bec6 (3) added d