diff tests/drawdag.py @ 33153:4d780d510b44

drawdag: support obsmarker creation in comments This patch adds special comment handling so one can create obsmarkers in drawdag comments like "# replace: A -> B -> C", "# prune: X, Y, Z", "split: P -> M, N" and they are just self-explained.
author Jun Wu <quark@fb.com>
date Tue, 27 Jun 2017 00:01:17 -0700
parents 46ba2cdda476
children 0830c841fc7f
line wrap: on
line diff
--- a/tests/drawdag.py	Mon Jun 26 23:31:53 2017 -0700
+++ b/tests/drawdag.py	Tue Jun 27 00:01:17 2017 -0700
@@ -72,10 +72,18 @@
 
 This is because 'o' is specially handled in the input: instead of using 'o' as
 the node name, the word to the right will be used.
+
+Some special comments could have side effects:
+
+    - Create obsmarkers
+      # replace: A -> B -> C -> D  # chained 1 to 1 replacements
+      # split: A -> B, C           # 1 to many
+      # prune: A, B, C             # many to nothing
 """
 from __future__ import absolute_import, print_function
 
 import collections
+import contextlib
 import itertools
 
 from mercurial.i18n import _
@@ -83,6 +91,7 @@
     context,
     error,
     node,
+    obsolete,
     registrar,
     scmutil,
     tags as tagsmod,
@@ -268,6 +277,13 @@
                 if leaf in v:
                     v.remove(leaf)
 
+@contextlib.contextmanager
+def transaction(repo):
+    with repo.wlock():
+        with repo.lock():
+            with repo.transaction('drawdag'):
+                yield
+
 @command('debugdrawdag', [])
 def debugdrawdag(ui, repo, **opts):
     """read an ASCII graph from stdin and create changesets
@@ -314,3 +330,33 @@
         committed[name] = n
         tagsmod.tag(repo, name, n, message=None, user=None, date=None,
                     local=True)
+
+    # handle special comments
+    with transaction(repo):
+        getctx = lambda x: repo.unfiltered()[committed[x.strip()]]
+        for line in text.splitlines():
+            if ' # ' not in line:
+                continue
+
+            rels = [] # obsolete relationships
+            comment = line.split(' # ', 1)[1].split(' # ')[0].strip()
+            args = comment.split(':', 1)
+            if len(args) <= 1:
+                continue
+
+            cmd = args[0].strip()
+            arg = args[1].strip()
+
+            if cmd in ('replace', 'rebase', 'amend'):
+                nodes = [getctx(m) for m in arg.split('->')]
+                for i in range(len(nodes) - 1):
+                    rels.append((nodes[i], (nodes[i + 1],)))
+            elif cmd in ('split',):
+                pre, succs = arg.split('->')
+                succs = succs.split(',')
+                rels.append((getctx(pre), (getctx(s) for s in succs)))
+            elif cmd in ('prune',):
+                for n in arg.split(','):
+                    rels.append((getctx(n), ()))
+            if rels:
+                obsolete.createmarkers(repo, rels, date=(0, 0), operation=cmd)