obshistory: add _debugobshistorydisplaypredsandmarkers() and test it draft
authorAnton Shestakov <av6@dwimlabs.net>
Thu, 16 Jan 2020 11:33:53 +0700
changeset 5257 3e27cac81df6
parent 5256 0eba17d734ca
obshistory: add _debugobshistorydisplaypredsandmarkers() and test it
hgext3rd/evolve/obshistory.py
tests/test-evolve-obshistory.t
tests/test-fold.t
tests/test-rewind.t
--- a/hgext3rd/evolve/obshistory.py	Mon Jan 13 16:32:25 2020 +0700
+++ b/hgext3rd/evolve/obshistory.py	Thu Jan 16 11:33:53 2020 +0700
@@ -53,6 +53,7 @@
      (b'a', b'all', False, _(b'show all related changesets, not only precursors')),
      (b'p', b'patch', False, _(b'show the patch between two obs versions')),
      (b'f', b'filternonlocal', False, _(b'filter out non local commits')),
+     (b'o', b'origin', False, _(b'show origin of changesets instead of fate')),
      ] + commands.formatteropts,
     _(b'hg olog [OPTION]... [[-r] REV]...'),
     **compat.helpcategorykwargs('CATEGORY_CHANGE_NAVIGATION'))
@@ -94,7 +95,7 @@
     # -f was given, because that doesn't work with templates yet. Note
     # that --no-graph doesn't support -f (it ignores it), so we also
     # don't use templating with --no-graph.
-    if not opts['template'] and not (opts['filternonlocal'] and opts['graph']):
+    if not opts['template'] and not ((opts['filternonlocal'] or opts['origin']) and opts['graph']):
         opts['template'] = DEFAULT_TEMPLATE
 
     if opts['graph']:
@@ -164,6 +165,7 @@
 
         self.template = diffopts and diffopts.get(b'template')
         self.filter = diffopts and diffopts.get(b'filternonlocal')
+        self.origin = diffopts and diffopts.get(b'origin')
 
     def show(self, ctx, copies=None, matchfn=None, **props):
         if self.buffered:
@@ -180,13 +182,24 @@
 
             # Succs markers
             if self.filter is False:
-                succs = self.repo.obsstore.successors.get(changenode, ())
-                succs = sorted(succs)
+                if self.origin:
+                    r = predecessorsandmarkers(self.repo, ctx)
+                    if r is None:
+                        r = []
 
-                for successor in succs:
-                    _debugobshistorydisplaymarker(self.ui, markerfm, successor,
-                                                  ctx.node(), self.repo,
-                                                  self._includediff)
+                    for predset in sorted(r):
+                        markers = predset[b"markers"]
+                        if not markers:
+                            continue
+                        predecessors = predset[b"predecessors"]
+                        _debugobshistorydisplaypredsandmarkers(self.ui, markerfm, predecessors, markers, ctx.node(), self.repo, self._includediff)
+                else:
+                    markers = self.repo.obsstore.successors.get(changenode, ())
+                    for marker in sorted(markers):
+                        _debugobshistorydisplaymarker(self.ui, markerfm,
+                                                      marker, ctx.node(),
+                                                      self.repo,
+                                                      self._includediff)
 
             else:
                 r = obsutil.successorsandmarkers(self.repo, ctx)
@@ -715,6 +728,116 @@
 
     fm.plain(b"\n")
 
+def _debugobshistorydisplaypredsandmarkers(ui, fm, prednodes, markers, node, repo, includediff=False):
+    """
+    This function is a copy of _debugobshistorydisplaysuccsandmarkers modified
+    to show predecessors and origin of obsolete nodes.
+    """
+    fm.startitem()
+    fm.plain(b'  ')
+
+    verb = obsoriginverb(prednodes, markers)
+    fm.write(b'verb', b'%s', verb, label=b"evolve.verb")
+
+    effects = _markerseffects(markers)
+    if effects:
+        fmteffect = fm.formatlist(effects, b'effect', sep=b', ')
+        fm.write(b'effects', b'(%s)', fmteffect)
+
+    if len(prednodes) > 0:
+        fm.plain(b' from ')
+
+        shortsnodes = (nodemod.short(prednode) for prednode in sorted(prednodes))
+        nodes = fm.formatlist(shortsnodes, b'prednode', sep=b', ')
+        fm.write(b'prednodes', b'%s', nodes, label=b"evolve.node")
+
+    # Operations
+    operations = obsutil.markersoperations(markers)
+    if operations:
+        fm.plain(b' using ')
+        fm.write(b'operation', b'%s', b", ".join(operations), label=b"evolve.operation")
+
+    fm.plain(b' by ')
+
+    # Users
+    users = obsutil.markersusers(markers)
+    fm.write(b'user', b'%s', b", ".join(users), label=b"evolve.user")
+    fm.plain(b' ')
+
+    # Dates
+    dates = obsutil.markersdates(markers)
+    if dates:
+        min_date = min(dates)
+        max_date = max(dates)
+
+        if min_date == max_date:
+            fm.write(b"date", b"(at %s)", fm.formatdate(min_date), label=b"evolve.date")
+        else:
+            fm.write(b"date", b"(between %s and %s)", fm.formatdate(min_date),
+                     fm.formatdate(max_date), label=b"evolve.date")
+
+    # initial support for showing note
+    # if metadata.get('note'):
+    #     fm.plain('\n    note: ')
+    #     fm.write('note', "%s", metadata['note'], label="evolve.note")
+
+    # Patch display
+    if includediff is True:
+        _patchavailable = patchavailable(node, repo, prednodes, successive=False)
+
+        if _patchavailable[0] is True:
+            pred = _patchavailable[1]
+
+            predctx = repo[pred]
+            basectx = repo[node]
+            # Description patch
+            descriptionpatch = getmarkerdescriptionpatch(repo,
+                                                         predctx.description(),
+                                                         basectx.description())
+
+            if descriptionpatch:
+                # add the diffheader
+                diffheader = b"diff -r %s -r %s changeset-description\n" %\
+                             (predctx, basectx)
+                descriptionpatch = diffheader + descriptionpatch
+
+                def tolist(text):
+                    return [text]
+
+                ui.pushbuffer(labeled=True)
+                ui.write(b"\n")
+
+                for chunk, label in patch.difflabel(tolist, descriptionpatch):
+                    chunk = chunk.strip(b'\t')
+                    if chunk and chunk != b'\n':
+                        ui.write(b'    ')
+                    ui.write(chunk, label=label)
+                fm.write(b'descdiff', b'%s', ui.popbuffer())
+
+            # Content patch
+            ui.pushbuffer(labeled=True)
+            diffopts = patch.diffallopts(repo.ui, {})
+            matchfn = scmutil.matchall(repo)
+            firstline = True
+            linestart = True
+            for chunk, label in patch.diffui(repo, pred, node, matchfn,
+                                             opts=diffopts):
+                if firstline:
+                    ui.write(b'\n')
+                    firstline = False
+                if linestart:
+                    ui.write(b'    ')
+                    linestart = False
+                if chunk == b'\n':
+                    linestart = True
+                ui.write(chunk, label=label)
+            fm.write(b'patch', b'%s', ui.popbuffer())
+        else:
+            fm.write(b'nopatchreason', b"\n    (No patch available, %s)",
+                     _patchavailable[1])
+
+    fm.plain(b"\n")
+
 def _prepare_hunk(hunk):
     """Drop all information but the username and patch"""
     cleanunk = []
--- a/tests/test-evolve-obshistory.t	Mon Jan 13 16:32:25 2020 +0700
+++ b/tests/test-evolve-obshistory.t	Thu Jan 16 11:33:53 2020 +0700
@@ -116,6 +116,31 @@
          +A1
   
   
+
+  $ hg obslog 7a230b46bf61 --patch --origin
+  @  7a230b46bf61 (3) A2
+  |    reworded(description) from fdf9bde5129a using amend by test (at Thu Jan 01 00:00:00 1970 +0000)
+  |      diff -r fdf9bde5129a -r 7a230b46bf61 changeset-description
+  |      --- a/changeset-description
+  |      +++ b/changeset-description
+  |      @@ -1,1 +1,1 @@
+  |      -A1
+  |      +A2
+  |
+  |
+  x  fdf9bde5129a (2) A1
+  |    reworded(description) from 471f378eab4c using amend by test (at Thu Jan 01 00:00:00 1970 +0000)
+  |      diff -r 471f378eab4c -r fdf9bde5129a changeset-description
+  |      --- a/changeset-description
+  |      +++ b/changeset-description
+  |      @@ -1,1 +1,1 @@
+  |      -A0
+  |      +A1
+  |
+  |
+  x  471f378eab4c (1) A0
+  
+
   $ cd $TESTTMP/local-remote-markers-2
   $ hg pull
   pulling from $TESTTMP/local-remote-markers-1
@@ -144,6 +169,18 @@
          (No patch available, successor is unknown locally)
   
 
+  $ hg obslog 7a230b46bf61 --patch --origin
+  o  7a230b46bf61 (2) A2
+  |    reworded(description) from fdf9bde5129a using amend by test (at Thu Jan 01 00:00:00 1970 +0000)
+  |      (No patch available, predecessor is unknown locally)
+  |
+  x  fdf9bde5129a
+  |    reworded(description) from 471f378eab4c using amend by test (at Thu Jan 01 00:00:00 1970 +0000)
+  |      (No patch available, context is not local)
+  |
+  @  471f378eab4c (1) A0
+  
+
   $ hg obslog 7a230b46bf61 --patch -f
   o  7a230b46bf61 (2) A2
   |
@@ -170,10 +207,19 @@
   
 
   $ hg obslog 7a230b46bf61 --graph \
-  > -T '{node|short} {rev} {desc|firstline}\n{markers % "rewritten using {operation}"}\n'
+  > -T '{node|short} {rev} {desc|firstline}\n{markers % "{verb} using {operation}"}\n'
   o  7a230b46bf61 2 A2
   |
   x  fdf9bde5129a
-  |  rewritten using amend
+  |  reworded using amend
   @  471f378eab4c 1 A0
-     rewritten using amend
+     reworded using amend
+
+  $ hg obslog 7a230b46bf61 --graph --origin \
+  > -T '{node|short} {rev} {desc|firstline}\n{markers % "{verb} using {operation}"}\n'
+  o  7a230b46bf61 2 A2
+  |  reworded using amend
+  x  fdf9bde5129a
+  |  reworded using amend
+  @  471f378eab4c 1 A0
+  
--- a/tests/test-fold.t	Mon Jan 13 16:32:25 2020 +0700
+++ b/tests/test-fold.t	Thu Jan 16 11:33:53 2020 +0700
@@ -100,6 +100,33 @@
   c8d03c1b5e94af74b772900c58259d2e08917735 198b5c405d01a50c41a81a00fc61677b81981a5f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '33', 'fold-id': '25cb328e', 'fold-idx': '1', 'fold-size': '3', 'operation': 'fold', 'user': 'test'}
   f69452c5b1af6cbaaa56ef50cf94fff5bcc6ca23 198b5c405d01a50c41a81a00fc61677b81981a5f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '37', 'fold-id': '25cb328e', 'fold-idx': '2', 'fold-size': '3', 'operation': 'fold', 'user': 'test'}
 
+  $ hg obslog
+  @    198b5c405d01 (11) r5
+  |\
+  | \
+  | |\
+  x | |  4de32a90b66c (7) r7
+   / /     folded(description, date, parent) as 198b5c405d01 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |
+  x |  c8d03c1b5e94 (5) r5
+   /     folded(description, date) as 198b5c405d01 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
+  |
+  x  f69452c5b1af (6) r6
+       folded(description, date, parent) as 198b5c405d01 using fold by test (Thu Jan 01 00:00:00 1970 +0000)
+  
+  $ hg obslog --origin
+  @    198b5c405d01 (11) r5
+  |\     folded(description, date, parent) from 4de32a90b66c, c8d03c1b5e94, f69452c5b1af using fold by test (at Thu Jan 01 00:00:00 1970 +0000)
+  | |
+  | \
+  | |\
+  x | |  4de32a90b66c (7) r7
+   / /
+  x /  c8d03c1b5e94 (5) r5
+   /
+  x  f69452c5b1af (6) r6
+  
+
 Checking whether the bookmarks are moved or not
 
   $ hg log -G
--- a/tests/test-rewind.t	Mon Jan 13 16:32:25 2020 +0700
+++ b/tests/test-rewind.t	Thu Jan 16 11:33:53 2020 +0700
@@ -522,6 +522,15 @@
   x  49fb7d900906 (3) c_CD0
        split(parent, content) as 9576e80d6851, a0316c4c5417 using split by test (Thu Jan 01 00:00:02 1970 +0000)
   
+  $ hg obslog --all --origin
+  @  9576e80d6851 (5) c_CD0
+  |    rewritten(parent, content) from 49fb7d900906 using split by test (at Thu Jan 01 00:00:02 1970 +0000)
+  |
+  | o  a0316c4c5417 (4) c_CD0
+  |/     rewritten(parent, content) from 49fb7d900906 using split by test (at Thu Jan 01 00:00:02 1970 +0000)
+  |
+  x  49fb7d900906 (3) c_CD0
+  
 
 Actual rewind
 `````````````