phabricator: check associated Differential Revision from commit message
authorJun Wu <quark@fb.com>
Tue, 04 Jul 2017 16:16:37 -0700
changeset 33263 ed61189763ef
parent 33262 8e6f4939a69a
child 33264 266321579c68
phabricator: check associated Differential Revision from commit message Previously, only tags can "associate" a changeset to a Differential Revision. But the usual pattern (arc patch or hg phabread) is to put the Differential Revision URL in commit message. This patch makes the code read commit message to find associated Differential Revision if associated tags are not found. This makes some workflows possible. For example, if the author loses their repo, or switch to another computer, they can continue download their own patches from Phabricator and update them without needing to manually create tags.
contrib/phabricator.py
--- a/contrib/phabricator.py	Wed Jul 05 11:10:11 2017 -0500
+++ b/contrib/phabricator.py	Tue Jul 04 16:16:37 2017 -0700
@@ -135,7 +135,9 @@
     repo.ui.setconfig('phabricator', 'repophid', repophid)
     return repophid
 
-_differentialrevisionre = re.compile('\AD([1-9][0-9]*)\Z')
+_differentialrevisiontagre = re.compile('\AD([1-9][0-9]*)\Z')
+_differentialrevisiondescre = re.compile(
+    '^Differential Revision:.*D([1-9][0-9]*)$', re.M)
 
 def getmapping(ctx):
     """return (node, associated Differential Revision ID) or (None, None)
@@ -143,15 +145,26 @@
     Examines all precursors and their tags. Tags with format like "D1234" are
     considered a match and the node with that tag, and the number after "D"
     (ex. 1234) will be returned.
+
+    If tags are not found, examine commit message. The "Differential Revision:"
+    line could associate this changeset to a Differential Revision.
     """
     unfi = ctx.repo().unfiltered()
     nodemap = unfi.changelog.nodemap
+
+    # Check tags like "D123"
     for n in obsolete.allprecursors(unfi.obsstore, [ctx.node()]):
         if n in nodemap:
             for tag in unfi.nodetags(n):
-                m = _differentialrevisionre.match(tag)
+                m = _differentialrevisiontagre.match(tag)
                 if m:
                     return n, int(m.group(1))
+
+    # Check commit message
+    m = _differentialrevisiondescre.search(ctx.description())
+    if m:
+        return None, int(m.group(1))
+
     return None, None
 
 def getdiff(ctx, diffopts):