annotate contrib/phabricator.py @ 33692:f100354cce52

phabricator: update diff property even if we choose not to create a new diff The diff property contains metadata like "HG Node". Previously we skip uploading a new diff if we are sure that the old patch and new patch have a same content. That has issues when a pusher adds an obsmarker using the old "HG Node" stored in the old diff. This patch adds logic to update the diff property so "HG Node" gets updated to prevent that issue. Differential Revision: https://phab.mercurial-scm.org/D229
author Jun Wu <quark@fb.com>
date Fri, 04 Aug 2017 12:21:23 -0700
parents 1664406a44d9
children e6d8ee3c9ec3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
1 # phabricator.py - simple Phabricator integration
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
2 #
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
3 # Copyright 2017 Facebook, Inc.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
4 #
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
7 """simple Phabricator integration
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
8
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
9 This extension provides a ``phabsend`` command which sends a stack of
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
10 changesets to Phabricator without amending commit messages, and a ``phabread``
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
11 command which prints a stack of revisions in a format suitable
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
12 for :hg:`import`.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
13
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
14 By default, Phabricator requires ``Test Plan`` which might prevent some
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
15 changeset from being sent. The requirement could be disabled by changing
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
16 ``differential.require-test-plan-field`` config server side.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
17
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
18 Config::
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
19
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
20 [phabricator]
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
21 # Phabricator URL
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
22 url = https://phab.example.com/
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
23
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
24 # API token. Get it from https://$HOST/conduit/login/
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
25 token = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
26
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
27 # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
28 # callsign is "FOO".
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
29 callsign = FOO
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
30
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
31 """
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
32
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
33 from __future__ import absolute_import
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
34
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
35 import json
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
36 import re
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
37
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
38 from mercurial.node import bin, nullid
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
39 from mercurial.i18n import _
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
40 from mercurial import (
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
41 encoding,
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
42 error,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
43 mdiff,
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
44 obsolete,
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
45 patch,
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
46 registrar,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
47 scmutil,
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
48 tags,
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
49 url as urlmod,
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
50 util,
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
51 )
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
52
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
53 cmdtable = {}
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
54 command = registrar.command(cmdtable)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
55
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
56 def urlencodenested(params):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
57 """like urlencode, but works with nested parameters.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
58
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
59 For example, if params is {'a': ['b', 'c'], 'd': {'e': 'f'}}, it will be
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
60 flattened to {'a[0]': 'b', 'a[1]': 'c', 'd[e]': 'f'} and then passed to
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
61 urlencode. Note: the encoding is consistent with PHP's http_build_query.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
62 """
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
63 flatparams = util.sortdict()
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
64 def process(prefix, obj):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
65 items = {list: enumerate, dict: lambda x: x.items()}.get(type(obj))
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
66 if items is None:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
67 flatparams[prefix] = obj
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
68 else:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
69 for k, v in items(obj):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
70 if prefix:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
71 process('%s[%s]' % (prefix, k), v)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
72 else:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
73 process(k, v)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
74 process('', params)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
75 return util.urlreq.urlencode(flatparams)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
76
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
77 def readurltoken(repo):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
78 """return conduit url, token and make sure they exist
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
79
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
80 Currently read from [phabricator] config section. In the future, it might
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
81 make sense to read from .arcconfig and .arcrc as well.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
82 """
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
83 values = []
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
84 section = 'phabricator'
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
85 for name in ['url', 'token']:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
86 value = repo.ui.config(section, name)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
87 if not value:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
88 raise error.Abort(_('config %s.%s is required') % (section, name))
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
89 values.append(value)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
90 return values
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
91
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
92 def callconduit(repo, name, params):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
93 """call Conduit API, params is a dict. return json.loads result, or None"""
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
94 host, token = readurltoken(repo)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
95 url, authinfo = util.url('/'.join([host, 'api', name])).authinfo()
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
96 urlopener = urlmod.opener(repo.ui, authinfo)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
97 repo.ui.debug('Conduit Call: %s %s\n' % (url, params))
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
98 params = params.copy()
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
99 params['api.token'] = token
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
100 request = util.urlreq.request(url, data=urlencodenested(params))
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
101 body = urlopener.open(request).read()
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
102 repo.ui.debug('Conduit Response: %s\n' % body)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
103 parsed = json.loads(body)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
104 if parsed.get(r'error_code'):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
105 msg = (_('Conduit Error (%s): %s')
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
106 % (parsed[r'error_code'], parsed[r'error_info']))
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
107 raise error.Abort(msg)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
108 return parsed[r'result']
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
109
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
110 @command('debugcallconduit', [], _('METHOD'))
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
111 def debugcallconduit(ui, repo, name):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
112 """call Conduit API
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
113
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
114 Call parameters are read from stdin as a JSON blob. Result will be written
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
115 to stdout as a JSON blob.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
116 """
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
117 params = json.loads(ui.fin.read())
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
118 result = callconduit(repo, name, params)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
119 s = json.dumps(result, sort_keys=True, indent=2, separators=(',', ': '))
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
120 ui.write('%s\n' % s)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
121
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
122 def getrepophid(repo):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
123 """given callsign, return repository PHID or None"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
124 # developer config: phabricator.repophid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
125 repophid = repo.ui.config('phabricator', 'repophid')
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
126 if repophid:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
127 return repophid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
128 callsign = repo.ui.config('phabricator', 'callsign')
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
129 if not callsign:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
130 return None
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
131 query = callconduit(repo, 'diffusion.repository.search',
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
132 {'constraints': {'callsigns': [callsign]}})
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
133 if len(query[r'data']) == 0:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
134 return None
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
135 repophid = encoding.strtolocal(query[r'data'][0][r'phid'])
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
136 repo.ui.setconfig('phabricator', 'repophid', repophid)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
137 return repophid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
138
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
139 _differentialrevisiontagre = re.compile('\AD([1-9][0-9]*)\Z')
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
140 _differentialrevisiondescre = re.compile(
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
141 '^Differential Revision:\s*(?:.*)D([1-9][0-9]*)$', re.M)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
142
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
143 def getoldnodedrevmap(repo, nodelist):
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
144 """find previous nodes that has been sent to Phabricator
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
145
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
146 return {node: (oldnode, Differential diff, Differential Revision ID)}
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
147 for node in nodelist with known previous sent versions, or associated
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
148 Differential Revision IDs. ``oldnode`` and ``Differential diff`` could
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
149 be ``None``.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
150
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
151 Examines commit messages like "Differential Revision:" to get the
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
152 association information.
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
153
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
154 If such commit message line is not found, examines all precursors and their
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
155 tags. Tags with format like "D1234" are considered a match and the node
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
156 with that tag, and the number after "D" (ex. 1234) will be returned.
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
157
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
158 The ``old node``, if not None, is guaranteed to be the last diff of
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
159 corresponding Differential Revision, and exist in the repo.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
160 """
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
161 url, token = readurltoken(repo)
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
162 unfi = repo.unfiltered()
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
163 nodemap = unfi.changelog.nodemap
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
164
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
165 result = {} # {node: (oldnode?, lastdiff?, drev)}
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
166 toconfirm = {} # {node: (force, {precnode}, drev)}
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
167 for node in nodelist:
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
168 ctx = unfi[node]
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
169 # For tags like "D123", put them into "toconfirm" to verify later
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
170 precnodes = list(obsolete.allprecursors(unfi.obsstore, [node]))
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
171 for n in precnodes:
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
172 if n in nodemap:
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
173 for tag in unfi.nodetags(n):
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
174 m = _differentialrevisiontagre.match(tag)
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
175 if m:
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
176 toconfirm[node] = (0, set(precnodes), int(m.group(1)))
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
177 continue
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
178
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
179 # Check commit message
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
180 m = _differentialrevisiondescre.search(ctx.description())
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
181 if m:
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
182 toconfirm[node] = (1, set(precnodes), int(m.group(1)))
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
183
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
184 # Double check if tags are genuine by collecting all old nodes from
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
185 # Phabricator, and expect precursors overlap with it.
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
186 if toconfirm:
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
187 drevs = [drev for force, precs, drev in toconfirm.values()]
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
188 alldiffs = callconduit(unfi, 'differential.querydiffs',
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
189 {'revisionIDs': drevs})
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
190 getnode = lambda d: bin(encoding.unitolocal(
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
191 getdiffmeta(d).get(r'node', ''))) or None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
192 for newnode, (force, precset, drev) in toconfirm.items():
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
193 diffs = [d for d in alldiffs.values()
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
194 if int(d[r'revisionID']) == drev]
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
195
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
196 # "precursors" as known by Phabricator
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
197 phprecset = set(getnode(d) for d in diffs)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
198
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
199 # Ignore if precursors (Phabricator and local repo) do not overlap,
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
200 # and force is not set (when commit message says nothing)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
201 if not force and not bool(phprecset & precset):
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
202 tagname = 'D%d' % drev
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
203 tags.tag(repo, tagname, nullid, message=None, user=None,
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
204 date=None, local=True)
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
205 unfi.ui.warn(_('D%s: local tag removed - does not match '
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
206 'Differential history\n') % drev)
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
207 continue
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
208
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
209 # Find the last node using Phabricator metadata, and make sure it
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
210 # exists in the repo
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
211 oldnode = lastdiff = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
212 if diffs:
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
213 lastdiff = max(diffs, key=lambda d: int(d[r'id']))
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
214 oldnode = getnode(lastdiff)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
215 if oldnode and oldnode not in nodemap:
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
216 oldnode = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
217
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
218 result[newnode] = (oldnode, lastdiff, drev)
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
219
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
220 return result
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
221
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
222 def getdiff(ctx, diffopts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
223 """plain-text diff without header (user, commit message, etc)"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
224 output = util.stringio()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
225 for chunk, _label in patch.diffui(ctx.repo(), ctx.p1().node(), ctx.node(),
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
226 None, opts=diffopts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
227 output.write(chunk)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
228 return output.getvalue()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
229
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
230 def creatediff(ctx):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
231 """create a Differential Diff"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
232 repo = ctx.repo()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
233 repophid = getrepophid(repo)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
234 # Create a "Differential Diff" via "differential.createrawdiff" API
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
235 params = {'diff': getdiff(ctx, mdiff.diffopts(git=True, context=32767))}
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
236 if repophid:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
237 params['repositoryPHID'] = repophid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
238 diff = callconduit(repo, 'differential.createrawdiff', params)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
239 if not diff:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
240 raise error.Abort(_('cannot create diff for %s') % ctx)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
241 return diff
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
242
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
243 def writediffproperties(ctx, diff):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
244 """write metadata to diff so patches could be applied losslessly"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
245 params = {
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
246 'diff_id': diff[r'id'],
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
247 'name': 'hg:meta',
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
248 'data': json.dumps({
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
249 'user': ctx.user(),
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
250 'date': '%d %d' % ctx.date(),
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
251 'node': ctx.hex(),
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
252 'parent': ctx.p1().hex(),
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
253 }),
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
254 }
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
255 callconduit(ctx.repo(), 'differential.setdiffproperty', params)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
256
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
257 def createdifferentialrevision(ctx, revid=None, parentrevid=None, oldnode=None,
33692
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
258 olddiff=None, actions=None):
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
259 """create or update a Differential Revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
260
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
261 If revid is None, create a new Differential Revision, otherwise update
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
262 revid. If parentrevid is not None, set it as a dependency.
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
263
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
264 If oldnode is not None, check if the patch content (without commit message
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
265 and metadata) has changed before creating another diff.
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
266
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
267 If actions is not None, they will be appended to the transaction.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
268 """
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
269 repo = ctx.repo()
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
270 if oldnode:
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
271 diffopts = mdiff.diffopts(git=True, context=1)
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
272 oldctx = repo.unfiltered()[oldnode]
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
273 neednewdiff = (getdiff(ctx, diffopts) != getdiff(oldctx, diffopts))
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
274 else:
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
275 neednewdiff = True
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
276
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
277 transactions = []
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
278 if neednewdiff:
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
279 diff = creatediff(ctx)
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
280 writediffproperties(ctx, diff)
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
281 transactions.append({'type': 'update', 'value': diff[r'phid']})
33692
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
282 else:
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
283 # Even if we don't need to upload a new diff because the patch content
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
284 # does not change. We might still need to update its metadata so
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
285 # pushers could know the correct node metadata.
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
286 assert olddiff
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
287 diff = olddiff
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
288 writediffproperties(ctx, diff)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
289
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
290 # Use a temporary summary to set dependency. There might be better ways but
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
291 # I cannot find them for now. But do not do that if we are updating an
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
292 # existing revision (revid is not None) since that introduces visible
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
293 # churns (someone edited "Summary" twice) on the web page.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
294 if parentrevid and revid is None:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
295 summary = 'Depends on D%s' % parentrevid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
296 transactions += [{'type': 'summary', 'value': summary},
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
297 {'type': 'summary', 'value': ' '}]
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
298
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
299 if actions:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
300 transactions += actions
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
301
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
302 # Parse commit message and update related fields.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
303 desc = ctx.description()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
304 info = callconduit(repo, 'differential.parsecommitmessage',
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
305 {'corpus': desc})
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
306 for k, v in info[r'fields'].items():
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
307 if k in ['title', 'summary', 'testPlan']:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
308 transactions.append({'type': k, 'value': v})
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
309
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
310 params = {'transactions': transactions}
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
311 if revid is not None:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
312 # Update an existing Differential Revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
313 params['objectIdentifier'] = revid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
314
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
315 revision = callconduit(repo, 'differential.revision.edit', params)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
316 if not revision:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
317 raise error.Abort(_('cannot create revision for %s') % ctx)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
318
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
319 return revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
320
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
321 def userphids(repo, names):
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
322 """convert user names to PHIDs"""
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
323 query = {'constraints': {'usernames': names}}
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
324 result = callconduit(repo, 'user.search', query)
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
325 # username not found is not an error of the API. So check if we have missed
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
326 # some names here.
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
327 data = result[r'data']
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
328 resolved = set(entry[r'fields'][r'username'] for entry in data)
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
329 unresolved = set(names) - resolved
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
330 if unresolved:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
331 raise error.Abort(_('unknown username: %s')
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
332 % ' '.join(sorted(unresolved)))
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
333 return [entry[r'phid'] for entry in data]
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
334
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
335 @command('phabsend',
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
336 [('r', 'rev', [], _('revisions to send'), _('REV')),
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
337 ('', 'reviewer', [], _('specify reviewers')),
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
338 ('', 'confirm', None, _('ask for confirmation before sending'))],
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
339 _('REV [OPTIONS]'))
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
340 def phabsend(ui, repo, *revs, **opts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
341 """upload changesets to Phabricator
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
342
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
343 If there are multiple revisions specified, they will be send as a stack
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
344 with a linear dependencies relationship using the order specified by the
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
345 revset.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
346
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
347 For the first time uploading changesets, local tags will be created to
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
348 maintain the association. After the first time, phabsend will check
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
349 obsstore and tags information so it can figure out whether to update an
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
350 existing Differential Revision, or create a new one.
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
351
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
352 The --confirm option lets you confirm changesets before sending them. You
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
353 can also add following to your configuration file to make it default
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
354 behaviour.
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
355
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
356 [phabsend]
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
357 confirm = true
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
358 """
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
359 revs = list(revs) + opts.get('rev', [])
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
360 revs = scmutil.revrange(repo, revs)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
361
33266
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
362 if not revs:
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
363 raise error.Abort(_('phabsend requires at least one changeset'))
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
364
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
365 confirm = ui.configbool('phabsend', 'confirm')
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
366 confirm |= bool(opts.get('confirm'))
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
367 if confirm:
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
368 confirmed = _confirmbeforesend(repo, revs)
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
369 if not confirmed:
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
370 raise error.Abort(_('phabsend cancelled'))
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
371
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
372 actions = []
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
373 reviewers = opts.get('reviewer', [])
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
374 if reviewers:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
375 phids = userphids(repo, reviewers)
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
376 actions.append({'type': 'reviewers.add', 'value': phids})
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
377
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
378 # {newnode: (oldnode, olddiff, olddrev}
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
379 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
380
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
381 # Send patches one by one so we know their Differential Revision IDs and
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
382 # can provide dependency relationship
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
383 lastrevid = None
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
384 for rev in revs:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
385 ui.debug('sending rev %d\n' % rev)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
386 ctx = repo[rev]
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
387
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
388 # Get Differential Revision ID
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
389 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
390 if oldnode != ctx.node():
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
391 # Create or update Differential Revision
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
392 revision = createdifferentialrevision(ctx, revid, lastrevid,
33692
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
393 oldnode, olddiff, actions)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
394 newrevid = int(revision[r'object'][r'id'])
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
395 if revid:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
396 action = _('updated')
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
397 else:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
398 action = _('created')
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
399
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
400 # Create a local tag to note the association
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
401 tagname = 'D%d' % newrevid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
402 tags.tag(repo, tagname, ctx.node(), message=None, user=None,
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
403 date=None, local=True)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
404 else:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
405 # Nothing changed. But still set "newrevid" so the next revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
406 # could depend on this one.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
407 newrevid = revid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
408 action = _('skipped')
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
409
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
410 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
411 ctx.description().split('\n')[0]))
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
412 lastrevid = newrevid
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
413
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
414 # Map from "hg:meta" keys to header understood by "hg import". The order is
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
415 # consistent with "hg export" output.
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
416 _metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'),
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
417 (r'node', 'Node ID'), (r'parent', 'Parent ')])
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
418
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
419 def _confirmbeforesend(repo, revs):
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
420 ui = repo.ui
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
421 for rev in revs:
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
422 ctx = repo[rev]
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
423 desc = ctx.description().splitlines()[0]
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
424 ui.write(('%d: ' % rev), label='phabsend.revnumber')
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
425 ui.write(('%s\n' % desc), label='phabsend.desc')
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
426
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
427 if ui.promptchoice(_('Phabsend the above changes (yn)?'
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
428 '$$ &Yes $$ &No')):
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
429 return False
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
430
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
431 return True
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
432
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
433 def querydrev(repo, params, stack=False):
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
434 """return a list of "Differential Revision" dicts
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
435
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
436 params is the input of "differential.query" API, and is expected to match
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
437 just a single Differential Revision.
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
438
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
439 A "Differential Revision dict" looks like:
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
440
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
441 {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
442 "id": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
443 "phid": "PHID-DREV-672qvysjcczopag46qty",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
444 "title": "example",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
445 "uri": "https://phab.example.com/D2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
446 "dateCreated": "1499181406",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
447 "dateModified": "1499182103",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
448 "authorPHID": "PHID-USER-tv3ohwc4v4jeu34otlye",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
449 "status": "0",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
450 "statusName": "Needs Review",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
451 "properties": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
452 "branch": null,
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
453 "summary": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
454 "testPlan": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
455 "lineCount": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
456 "activeDiffPHID": "PHID-DIFF-xoqnjkobbm6k4dk6hi72",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
457 "diffs": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
458 "3",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
459 "4",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
460 ],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
461 "commits": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
462 "reviewers": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
463 "ccs": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
464 "hashes": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
465 "auxiliary": {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
466 "phabricator:projects": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
467 "phabricator:depends-on": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
468 "PHID-DREV-gbapp366kutjebt7agcd"
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
469 ]
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
470 },
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
471 "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
472 "sourcePath": null
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
473 }
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
474
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
475 If stack is True, return a list of "Differential Revision dict"s in an
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
476 order that the latter ones depend on the former ones. Otherwise, return a
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
477 list of a unique "Differential Revision dict".
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
478 """
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
479 prefetched = {} # {id or phid: drev}
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
480 def fetch(params):
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
481 """params -> single drev or None"""
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
482 key = (params.get(r'ids') or params.get(r'phids') or [None])[0]
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
483 if key in prefetched:
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
484 return prefetched[key]
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
485 # Otherwise, send the request. If we're fetching a stack, be smarter
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
486 # and fetch more ids in one batch, even if it could be unnecessary.
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
487 batchparams = params
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
488 if stack and len(params.get(r'ids', [])) == 1:
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
489 i = int(params[r'ids'][0])
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
490 # developer config: phabricator.batchsize
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
491 batchsize = repo.ui.configint('phabricator', 'batchsize', 12)
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
492 batchparams = {'ids': range(max(1, i - batchsize), i + 1)}
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
493 drevs = callconduit(repo, 'differential.query', batchparams)
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
494 # Fill prefetched with the result
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
495 for drev in drevs:
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
496 prefetched[drev[r'phid']] = drev
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
497 prefetched[int(drev[r'id'])] = drev
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
498 if key not in prefetched:
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
499 raise error.Abort(_('cannot get Differential Revision %r') % params)
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
500 return prefetched[key]
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
501
33271
02299a28ba34 phabricator: do not read a same revision twice
Jun Wu <quark@fb.com>
parents: 33269
diff changeset
502 visited = set()
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
503 result = []
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
504 queue = [params]
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
505 while queue:
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
506 params = queue.pop()
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
507 drev = fetch(params)
33271
02299a28ba34 phabricator: do not read a same revision twice
Jun Wu <quark@fb.com>
parents: 33269
diff changeset
508 if drev[r'id'] in visited:
02299a28ba34 phabricator: do not read a same revision twice
Jun Wu <quark@fb.com>
parents: 33269
diff changeset
509 continue
02299a28ba34 phabricator: do not read a same revision twice
Jun Wu <quark@fb.com>
parents: 33269
diff changeset
510 visited.add(drev[r'id'])
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
511 result.append(drev)
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
512 if stack:
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
513 auxiliary = drev.get(r'auxiliary', {})
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
514 depends = auxiliary.get(r'phabricator:depends-on', [])
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
515 for phid in depends:
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
516 queue.append({'phids': [phid]})
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
517 result.reverse()
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
518 return result
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
519
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
520 def getdescfromdrev(drev):
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
521 """get description (commit message) from "Differential Revision"
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
522
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
523 This is similar to differential.getcommitmessage API. But we only care
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
524 about limited fields: title, summary, test plan, and URL.
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
525 """
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
526 title = drev[r'title']
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
527 summary = drev[r'summary'].rstrip()
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
528 testplan = drev[r'testPlan'].rstrip()
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
529 if testplan:
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
530 testplan = 'Test Plan:\n%s' % testplan
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
531 uri = 'Differential Revision: %s' % drev[r'uri']
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
532 return '\n\n'.join(filter(None, [title, summary, testplan, uri]))
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
533
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
534 def getdiffmeta(diff):
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
535 """get commit metadata (date, node, user, p1) from a diff object
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
536
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
537 The metadata could be "hg:meta", sent by phabsend, like:
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
538
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
539 "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
540 "hg:meta": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
541 "date": "1499571514 25200",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
542 "node": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
543 "user": "Foo Bar <foo@example.com>",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
544 "parent": "6d0abad76b30e4724a37ab8721d630394070fe16"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
545 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
546 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
547
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
548 Or converted from "local:commits", sent by "arc", like:
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
549
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
550 "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
551 "local:commits": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
552 "98c08acae292b2faf60a279b4189beb6cff1414d": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
553 "author": "Foo Bar",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
554 "time": 1499546314,
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
555 "branch": "default",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
556 "tag": "",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
557 "commit": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
558 "rev": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
559 "local": "1000",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
560 "parents": ["6d0abad76b30e4724a37ab8721d630394070fe16"],
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
561 "summary": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
562 "message": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
563 "authorEmail": "foo@example.com"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
564 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
565 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
566 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
567
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
568 Note: metadata extracted from "local:commits" will lose time zone
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
569 information.
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
570 """
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
571 props = diff.get(r'properties') or {}
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
572 meta = props.get(r'hg:meta')
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
573 if not meta and props.get(r'local:commits'):
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
574 commit = sorted(props[r'local:commits'].values())[0]
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
575 meta = {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
576 r'date': r'%d 0' % commit[r'time'],
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
577 r'node': commit[r'rev'],
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
578 r'user': r'%s <%s>' % (commit[r'author'], commit[r'authorEmail']),
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
579 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
580 if len(commit.get(r'parents', ())) >= 1:
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
581 meta[r'parent'] = commit[r'parents'][0]
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
582 return meta or {}
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
583
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
584 def readpatch(repo, params, write, stack=False):
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
585 """generate plain-text patch readable by 'hg import'
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
586
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
587 write is usually ui.write. params is passed to "differential.query". If
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
588 stack is True, also write dependent patches.
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
589 """
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
590 # Differential Revisions
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
591 drevs = querydrev(repo, params, stack)
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
592
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
593 # Prefetch hg:meta property for all diffs
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
594 diffids = sorted(set(max(int(v) for v in drev[r'diffs']) for drev in drevs))
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
595 diffs = callconduit(repo, 'differential.querydiffs', {'ids': diffids})
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
596
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
597 # Generate patch for each drev
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
598 for drev in drevs:
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
599 repo.ui.note(_('reading D%s\n') % drev[r'id'])
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
600
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
601 diffid = max(int(v) for v in drev[r'diffs'])
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
602 body = callconduit(repo, 'differential.getrawdiff', {'diffID': diffid})
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
603 desc = getdescfromdrev(drev)
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
604 header = '# HG changeset patch\n'
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
605
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
606 # Try to preserve metadata from hg:meta property. Write hg patch
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
607 # headers that can be read by the "import" command. See patchheadermap
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
608 # and extract in mercurial/patch.py for supported headers.
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
609 meta = getdiffmeta(diffs[str(diffid)])
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
610 for k in _metanamemap.keys():
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
611 if k in meta:
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
612 header += '# %s %s\n' % (_metanamemap[k], meta[k])
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
613
33601
850d2ec2cf6a phabricator: convert unicode to binary when writing patches
Jun Wu <quark@fb.com>
parents: 33564
diff changeset
614 content = '%s%s\n%s' % (header, desc, body)
850d2ec2cf6a phabricator: convert unicode to binary when writing patches
Jun Wu <quark@fb.com>
parents: 33564
diff changeset
615 write(encoding.unitolocal(content))
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
616
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
617 @command('phabread',
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
618 [('', 'stack', False, _('read dependencies'))],
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
619 _('REVID [OPTIONS]'))
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
620 def phabread(ui, repo, revid, **opts):
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
621 """print patches from Phabricator suitable for importing
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
622
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
623 REVID could be a Differential Revision identity, like ``D123``, or just the
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
624 number ``123``, or a full URL like ``https://phab.example.com/D123``.
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
625
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
626 If --stack is given, follow dependencies information and read all patches.
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
627 """
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
628 try:
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
629 revid = int(revid.split('/')[-1].replace('D', ''))
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
630 except ValueError:
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
631 raise error.Abort(_('invalid Revision ID: %s') % revid)
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
632 readpatch(repo, {'ids': [revid]}, ui.write, opts.get('stack'))