Patchwork [02,of,10] phabricator: add node and p1 to hg:meta property

login
register
mail settings
Submitter Jun Wu
Date July 5, 2017, 1:58 a.m.
Message ID <dcb29d9e139b96af5273.1499219907@x1c>
Download mbox | patch
Permalink /patch/22007/
State Accepted
Headers show

Comments

Jun Wu - July 5, 2017, 1:58 a.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1499211408 25200
#      Tue Jul 04 16:36:48 2017 -0700
# Node ID dcb29d9e139b96af5273a91150871a0b8eb0a93e
# Parent  650ef9794f032c216e85476db39170a52041260f
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r dcb29d9e139b
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".

Patch

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -197,4 +197,6 @@  def writediffproperties(ctx, diff):
             'user': ctx.user(),
             'date': '%d %d' % ctx.date(),
+            'node': ctx.hex(),
+            'parent': ctx.p1().hex(),
         }),
     }
@@ -293,4 +295,9 @@  def phabsend(ui, repo, *revs, **opts):
 _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'
@@ -317,11 +324,14 @@  def readpatch(repo, params, recursive=Fa
     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)