# HG changeset patch # User Matt Harbison # Date 2020-02-16 20:06:20 # Node ID d5d262c7e7a232f610011db69cc716afa5a7a89e # Parent b715432fabbae3cf09583ed82186d20f868f43fe phabricator: refactor `phabread` to write all patches at once This will be necessary to create a first class `phabimport` command. That command requires a transaction, and will import all named patches within a single transaction. But if Phabricator queries also happen within the transaction, that leaves open the chance that an exception is raised, the transaction is abandoned, and the next command that is run will complain about needing to run `hg recover`. Differential Revision: https://phab.mercurial-scm.org/D8135 diff --git a/hgext/phabricator.py b/hgext/phabricator.py --- a/hgext/phabricator.py +++ b/hgext/phabricator.py @@ -1615,13 +1615,17 @@ def getdiffmeta(diff): def readpatch(ui, drevs, write): """generate plain-text patch readable by 'hg import' - write is usually ui.write. drevs is what "querydrev" returns, results of + write takes a list of (DREV, bytes), where DREV is the differential number + (as bytes, without the "D" prefix) and the bytes are the text of a patch + to be imported. drevs is what "querydrev" returns, results of "differential.query". """ # Prefetch hg:meta property for all diffs diffids = sorted(set(max(int(v) for v in drev[b'diffs']) for drev in drevs)) diffs = callconduit(ui, b'differential.querydiffs', {b'ids': diffids}) + patches = [] + # Generate patch for each drev for drev in drevs: ui.note(_(b'reading D%s\n') % drev[b'id']) @@ -1640,7 +1644,10 @@ def readpatch(ui, drevs, write): header += b'# %s %s\n' % (_metanamemap[k], meta[k]) content = b'%s%s\n%s' % (header, desc, body) - write(content) + patches.append((drev[b'id'], content)) + + # Write patches to the supplied callback + write(patches) @vcrcommand( @@ -1672,7 +1679,12 @@ def phabread(ui, repo, spec, **opts): if opts.get(b'stack'): spec = b':(%s)' % spec drevs = querydrev(repo.ui, spec) - readpatch(repo.ui, drevs, ui.write) + + def _write(patches): + for drev, content in patches: + ui.write(content) + + readpatch(repo.ui, drevs, _write) @vcrcommand(