Show More
@@ -7,7 +7,9 b'' | |||||
7 | """simple Phabricator integration |
|
7 | """simple Phabricator integration | |
8 |
|
8 | |||
9 | This extension provides a ``phabsend`` command which sends a stack of |
|
9 | This extension provides a ``phabsend`` command which sends a stack of | |
10 |
changesets to Phabricator without amending commit messages |
|
10 | changesets to Phabricator without amending commit messages, and a ``phabread`` | |
|
11 | command which prints a stack of revisions in a format suitable | |||
|
12 | for :hg:`import`. | |||
11 |
|
13 | |||
12 | By default, Phabricator requires ``Test Plan`` which might prevent some |
|
14 | By default, Phabricator requires ``Test Plan`` which might prevent some | |
13 | changeset from being sent. The requirement could be disabled by changing |
|
15 | changeset from being sent. The requirement could be disabled by changing | |
@@ -25,6 +27,7 b' Config::' | |||||
25 | # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its |
|
27 | # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its | |
26 | # callsign is "FOO". |
|
28 | # callsign is "FOO". | |
27 | callsign = FOO |
|
29 | callsign = FOO | |
|
30 | ||||
28 | """ |
|
31 | """ | |
29 |
|
32 | |||
30 | from __future__ import absolute_import |
|
33 | from __future__ import absolute_import | |
@@ -273,3 +276,65 b' def phabsend(ui, repo, *revs, **opts):' | |||||
273 | ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx, |
|
276 | ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx, | |
274 | ctx.description().split('\n')[0])) |
|
277 | ctx.description().split('\n')[0])) | |
275 | lastrevid = newrevid |
|
278 | lastrevid = newrevid | |
|
279 | ||||
|
280 | _summaryre = re.compile('^Summary:\s*', re.M) | |||
|
281 | ||||
|
282 | def readpatch(repo, params, recursive=False): | |||
|
283 | """generate plain-text patch readable by 'hg import' | |||
|
284 | ||||
|
285 | params is passed to "differential.query". If recursive is True, also return | |||
|
286 | dependent patches. | |||
|
287 | """ | |||
|
288 | # Differential Revisions | |||
|
289 | drevs = callconduit(repo, 'differential.query', params) | |||
|
290 | if len(drevs) == 1: | |||
|
291 | drev = drevs[0] | |||
|
292 | else: | |||
|
293 | raise error.Abort(_('cannot get Differential Revision %r') % params) | |||
|
294 | ||||
|
295 | repo.ui.note(_('reading D%s\n') % drev[r'id']) | |||
|
296 | ||||
|
297 | diffid = max(int(v) for v in drev[r'diffs']) | |||
|
298 | body = callconduit(repo, 'differential.getrawdiff', {'diffID': diffid}) | |||
|
299 | desc = callconduit(repo, 'differential.getcommitmessage', | |||
|
300 | {'revision_id': drev[r'id']}) | |||
|
301 | header = '# HG changeset patch\n' | |||
|
302 | ||||
|
303 | # Remove potential empty "Summary:" | |||
|
304 | desc = _summaryre.sub('', desc) | |||
|
305 | ||||
|
306 | # Try to preserve metadata (user, date) from hg:meta property | |||
|
307 | diffs = callconduit(repo, 'differential.querydiffs', {'ids': [diffid]}) | |||
|
308 | props = diffs[str(diffid)][r'properties'] # could be empty list or dict | |||
|
309 | if props and r'hg:meta' in props: | |||
|
310 | meta = props[r'hg:meta'] | |||
|
311 | for k, v in meta.items(): | |||
|
312 | header += '# %s %s\n' % (k.capitalize(), v) | |||
|
313 | ||||
|
314 | patch = ('%s%s\n%s') % (header, desc, body) | |||
|
315 | ||||
|
316 | # Check dependencies | |||
|
317 | if recursive: | |||
|
318 | auxiliary = drev.get(r'auxiliary', {}) | |||
|
319 | depends = auxiliary.get(r'phabricator:depends-on', []) | |||
|
320 | for phid in depends: | |||
|
321 | patch = readpatch(repo, {'phids': [phid]}, recursive=True) + patch | |||
|
322 | return patch | |||
|
323 | ||||
|
324 | @command('phabread', | |||
|
325 | [('', 'stack', False, _('read dependencies'))], | |||
|
326 | _('REVID [OPTIONS]')) | |||
|
327 | def phabread(ui, repo, revid, **opts): | |||
|
328 | """print patches from Phabricator suitable for importing | |||
|
329 | ||||
|
330 | REVID could be a Differential Revision identity, like ``D123``, or just the | |||
|
331 | number ``123``, or a full URL like ``https://phab.example.com/D123``. | |||
|
332 | ||||
|
333 | If --stack is given, follow dependencies information and read all patches. | |||
|
334 | """ | |||
|
335 | try: | |||
|
336 | revid = int(revid.split('/')[-1].replace('D', '')) | |||
|
337 | except ValueError: | |||
|
338 | raise error.Abort(_('invalid Revision ID: %s') % revid) | |||
|
339 | patch = readpatch(repo, {'ids': [revid]}, recursive=opts.get('stack')) | |||
|
340 | ui.write(patch) |
General Comments 0
You need to be logged in to leave comments.
Login now