diff hgext/phabricator.py @ 44550:bbb170f9396d

phabricator: add a `phabimport` command I've had `alias.phabimport = $hg phabread --stack $1 | $hg import --bypass -` for a while now, and I suspect others do too. That's limited though, in that it can't use the information on Phabricator to restore it in the original location, so I'm making it a first class command. This doesn't do anything ambitious like that- this is mostly a simplification of `hg import` to get the equivalent of the alias mentioned above. The `--bypass` option is hardcoded to be enabled and the message about amending rejects dropped (rejects aren't created with `--bypass`), because editing patches on Phabricator seems like an unusual workflow. This will need other options, like `--obsolete` and `--secret`. I think these would be more useful as config settings, as I imagine the workflows are pretty fixed depending on roles. Reviewers who don't queue patches probably never want `--obsolete`, but may need `--secret`. Reviewers who do will want the former, but not the latter. I left `--stack` as an option, but that should probably be a config knob too (or at least default to on)- if the point of this is to avoid rejects, it doesn't make sense to skip dependencies in most cases. Evolve is going to need a fix to its wrapping of `cmdutil.tryimportone()`, as it currently assumes `opts` has an `obsolete` key. It's worked around for now. Differential Revision: https://phab.mercurial-scm.org/D8136
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 16 Feb 2020 16:13:36 -0500
parents 9d2b2df2c2ba
children 9bae1d1a0f4c
line wrap: on
line diff
--- a/hgext/phabricator.py	Thu Mar 12 10:14:40 2020 +0100
+++ b/hgext/phabricator.py	Sun Feb 16 16:13:36 2020 -0500
@@ -1703,6 +1703,65 @@
 
 
 @vcrcommand(
+    b'phabimport',
+    [(b'', b'stack', False, _(b'import dependencies as well'))],
+    _(b'DREVSPEC [OPTIONS]'),
+    helpcategory=command.CATEGORY_IMPORT_EXPORT,
+)
+def phabimport(ui, repo, spec, **opts):
+    """import patches from Phabricator for the specified Differential Revisions
+
+    The patches are read and applied starting at the parent of the working
+    directory.
+
+    See ``hg help phabread`` for how to specify DREVSPEC.
+    """
+    opts = pycompat.byteskwargs(opts)
+
+    # --bypass avoids losing exec and symlink bits when importing on Windows,
+    # and allows importing with a dirty wdir.  It also aborts instead of leaving
+    # rejects.
+    opts[b'bypass'] = True
+
+    # Mandatory default values, synced with commands.import
+    opts[b'strip'] = 1
+    opts[b'prefix'] = b''
+    # Evolve 9.3.0 assumes this key is present in cmdutil.tryimportone()
+    opts[b'obsolete'] = False
+
+    def _write(patches):
+        parents = repo[None].parents()
+
+        with repo.wlock(), repo.lock(), repo.transaction(b'phabimport'):
+            for drev, contents in patches:
+                ui.status(_(b'applying patch from D%s\n') % drev)
+
+                with patch.extract(ui, pycompat.bytesio(contents)) as patchdata:
+                    msg, node, rej = cmdutil.tryimportone(
+                        ui,
+                        repo,
+                        patchdata,
+                        parents,
+                        opts,
+                        [],
+                        None,  # Never update wdir to another revision
+                    )
+
+                    if not node:
+                        raise error.Abort(_(b'D%s: no diffs found') % drev)
+
+                    ui.note(msg + b'\n')
+                    parents = [repo[node]]
+
+    opts = pycompat.byteskwargs(opts)
+    if opts.get(b'stack'):
+        spec = b':(%s)' % spec
+    drevs = querydrev(repo.ui, spec)
+
+    readpatch(repo.ui, drevs, _write)
+
+
+@vcrcommand(
     b'phabupdate',
     [
         (b'', b'accept', False, _(b'accept revisions')),