comparison hgext/phabricator.py @ 44422:d5d262c7e7a2

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
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 16 Feb 2020 15:06:20 -0500
parents b715432fabba
children 5e2d74e5f450
comparison
equal deleted inserted replaced
44421:b715432fabba 44422:d5d262c7e7a2
1613 1613
1614 1614
1615 def readpatch(ui, drevs, write): 1615 def readpatch(ui, drevs, write):
1616 """generate plain-text patch readable by 'hg import' 1616 """generate plain-text patch readable by 'hg import'
1617 1617
1618 write is usually ui.write. drevs is what "querydrev" returns, results of 1618 write takes a list of (DREV, bytes), where DREV is the differential number
1619 (as bytes, without the "D" prefix) and the bytes are the text of a patch
1620 to be imported. drevs is what "querydrev" returns, results of
1619 "differential.query". 1621 "differential.query".
1620 """ 1622 """
1621 # Prefetch hg:meta property for all diffs 1623 # Prefetch hg:meta property for all diffs
1622 diffids = sorted(set(max(int(v) for v in drev[b'diffs']) for drev in drevs)) 1624 diffids = sorted(set(max(int(v) for v in drev[b'diffs']) for drev in drevs))
1623 diffs = callconduit(ui, b'differential.querydiffs', {b'ids': diffids}) 1625 diffs = callconduit(ui, b'differential.querydiffs', {b'ids': diffids})
1626
1627 patches = []
1624 1628
1625 # Generate patch for each drev 1629 # Generate patch for each drev
1626 for drev in drevs: 1630 for drev in drevs:
1627 ui.note(_(b'reading D%s\n') % drev[b'id']) 1631 ui.note(_(b'reading D%s\n') % drev[b'id'])
1628 1632
1638 for k in _metanamemap.keys(): 1642 for k in _metanamemap.keys():
1639 if k in meta: 1643 if k in meta:
1640 header += b'# %s %s\n' % (_metanamemap[k], meta[k]) 1644 header += b'# %s %s\n' % (_metanamemap[k], meta[k])
1641 1645
1642 content = b'%s%s\n%s' % (header, desc, body) 1646 content = b'%s%s\n%s' % (header, desc, body)
1643 write(content) 1647 patches.append((drev[b'id'], content))
1648
1649 # Write patches to the supplied callback
1650 write(patches)
1644 1651
1645 1652
1646 @vcrcommand( 1653 @vcrcommand(
1647 b'phabread', 1654 b'phabread',
1648 [(b'', b'stack', False, _(b'read dependencies'))], 1655 [(b'', b'stack', False, _(b'read dependencies'))],
1670 """ 1677 """
1671 opts = pycompat.byteskwargs(opts) 1678 opts = pycompat.byteskwargs(opts)
1672 if opts.get(b'stack'): 1679 if opts.get(b'stack'):
1673 spec = b':(%s)' % spec 1680 spec = b':(%s)' % spec
1674 drevs = querydrev(repo.ui, spec) 1681 drevs = querydrev(repo.ui, spec)
1675 readpatch(repo.ui, drevs, ui.write) 1682
1683 def _write(patches):
1684 for drev, content in patches:
1685 ui.write(content)
1686
1687 readpatch(repo.ui, drevs, _write)
1676 1688
1677 1689
1678 @vcrcommand( 1690 @vcrcommand(
1679 b'phabupdate', 1691 b'phabupdate',
1680 [ 1692 [