phabricator: add node and p1 to hg:meta property
authorJun Wu <quark@fb.com>
Tue, 04 Jul 2017 16:36:48 -0700
changeset 33264 266321579c68
parent 33263 ed61189763ef
child 33265 95f658b558a3
phabricator: add node and p1 to hg:meta property The "hg:meta" property is for extra metadata to reconstruct the patch. Previously it does not have node or parent information since I think by reading the patch again, the commit message will be mangled (like, added the "Differential Revision" line) and we cannot preserve the commit hash. However, the "parent" information could be useful. It could be helpful to locate the "base revision" so in case of a conflict applying the patch directly, we might be able to use 3-way merge to resolve it correctly. Note: "local:commits" is an existing "property" used by Phabricator that has the node and parent information. However, it lacks of timezone information and requires "author" and "authorEmail" to be separated. So we are using a different "property" - "hg:meta" to be distinguished from "local:commits".
contrib/phabricator.py
--- a/contrib/phabricator.py	Tue Jul 04 16:16:37 2017 -0700
+++ b/contrib/phabricator.py	Tue Jul 04 16:36:48 2017 -0700
@@ -196,6 +196,8 @@
         'data': json.dumps({
             'user': ctx.user(),
             'date': '%d %d' % ctx.date(),
+            'node': ctx.hex(),
+            'parent': ctx.p1().hex(),
         }),
     }
     callconduit(ctx.repo(), 'differential.setdiffproperty', params)
@@ -292,6 +294,11 @@
 
 _summaryre = re.compile('^Summary:\s*', re.M)
 
+# Map from "hg:meta" keys to header understood by "hg import". The order is
+# consistent with "hg export" output.
+_metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'),
+                              (r'node', 'Node ID'), (r'parent', 'Parent ')])
+
 def readpatch(repo, params, recursive=False):
     """generate plain-text patch readable by 'hg import'
 
@@ -316,13 +323,16 @@
     # Remove potential empty "Summary:"
     desc = _summaryre.sub('', desc)
 
-    # Try to preserve metadata (user, date) from hg:meta property
+    # Try to preserve metadata from hg:meta property. Write hg patch headers
+    # that can be read by the "import" command. See patchheadermap and extract
+    # in mercurial/patch.py for supported headers.
     diffs = callconduit(repo, 'differential.querydiffs', {'ids': [diffid]})
     props = diffs[str(diffid)][r'properties'] # could be empty list or dict
     if props and r'hg:meta' in props:
         meta = props[r'hg:meta']
-        for k, v in meta.items():
-            header += '# %s %s\n' % (k.capitalize(), v)
+        for k in _metanamemap.keys():
+            if k in meta:
+                header += '# %s %s\n' % (_metanamemap[k], meta[k])
 
     patch = ('%s%s\n%s') % (header, desc, body)