##// END OF EJS Templates
phabricator: rework phabread to reduce memory usage and round-trips...
Jun Wu -
r33267:dba9f886 default
parent child Browse files
Show More
@@ -314,50 +314,106 b' def phabsend(ui, repo, *revs, **opts):'
314 314 _metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'),
315 315 (r'node', 'Node ID'), (r'parent', 'Parent ')])
316 316
317 def readpatch(repo, params, recursive=False):
317 def querydrev(repo, params, stack=False):
318 """return a list of "Differential Revision" dicts
319
320 params is the input of "differential.query" API, and is expected to match
321 just a single Differential Revision.
322
323 A "Differential Revision dict" looks like:
324
325 {
326 "id": "2",
327 "phid": "PHID-DREV-672qvysjcczopag46qty",
328 "title": "example",
329 "uri": "https://phab.example.com/D2",
330 "dateCreated": "1499181406",
331 "dateModified": "1499182103",
332 "authorPHID": "PHID-USER-tv3ohwc4v4jeu34otlye",
333 "status": "0",
334 "statusName": "Needs Review",
335 "properties": [],
336 "branch": null,
337 "summary": "",
338 "testPlan": "",
339 "lineCount": "2",
340 "activeDiffPHID": "PHID-DIFF-xoqnjkobbm6k4dk6hi72",
341 "diffs": [
342 "3",
343 "4",
344 ],
345 "commits": [],
346 "reviewers": [],
347 "ccs": [],
348 "hashes": [],
349 "auxiliary": {
350 "phabricator:projects": [],
351 "phabricator:depends-on": [
352 "PHID-DREV-gbapp366kutjebt7agcd"
353 ]
354 },
355 "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv",
356 "sourcePath": null
357 }
358
359 If stack is True, return a list of "Differential Revision dict"s in an
360 order that the latter ones depend on the former ones. Otherwise, return a
361 list of a unique "Differential Revision dict".
362 """
363 result = []
364 queue = [params]
365 while queue:
366 params = queue.pop()
367 drevs = callconduit(repo, 'differential.query', params)
368 if len(drevs) != 1:
369 raise error.Abort(_('cannot get Differential Revision %r') % params)
370 drev = drevs[0]
371 result.append(drev)
372 if stack:
373 auxiliary = drev.get(r'auxiliary', {})
374 depends = auxiliary.get(r'phabricator:depends-on', [])
375 for phid in depends:
376 queue.append({'phids': [phid]})
377 result.reverse()
378 return result
379
380 def readpatch(repo, params, write, stack=False):
318 381 """generate plain-text patch readable by 'hg import'
319 382
320 params is passed to "differential.query". If recursive is True, also return
321 dependent patches.
383 write is usually ui.write. params is passed to "differential.query". If
384 stack is True, also write dependent patches.
322 385 """
323 386 # Differential Revisions
324 drevs = callconduit(repo, 'differential.query', params)
325 if len(drevs) == 1:
326 drev = drevs[0]
327 else:
328 raise error.Abort(_('cannot get Differential Revision %r') % params)
329
330 repo.ui.note(_('reading D%s\n') % drev[r'id'])
387 drevs = querydrev(repo, params, stack)
331 388
332 diffid = max(int(v) for v in drev[r'diffs'])
333 body = callconduit(repo, 'differential.getrawdiff', {'diffID': diffid})
334 desc = callconduit(repo, 'differential.getcommitmessage',
335 {'revision_id': drev[r'id']})
336 header = '# HG changeset patch\n'
389 # Prefetch hg:meta property for all diffs
390 diffids = sorted(set(max(int(v) for v in drev[r'diffs']) for drev in drevs))
391 diffs = callconduit(repo, 'differential.querydiffs', {'ids': diffids})
337 392
338 # Remove potential empty "Summary:"
339 desc = _summaryre.sub('', desc)
393 # Generate patch for each drev
394 for drev in drevs:
395 repo.ui.note(_('reading D%s\n') % drev[r'id'])
340 396
341 # Try to preserve metadata from hg:meta property. Write hg patch headers
342 # that can be read by the "import" command. See patchheadermap and extract
343 # in mercurial/patch.py for supported headers.
344 diffs = callconduit(repo, 'differential.querydiffs', {'ids': [diffid]})
345 props = diffs[str(diffid)][r'properties'] # could be empty list or dict
346 if props and r'hg:meta' in props:
347 meta = props[r'hg:meta']
348 for k in _metanamemap.keys():
349 if k in meta:
350 header += '# %s %s\n' % (_metanamemap[k], meta[k])
397 diffid = max(int(v) for v in drev[r'diffs'])
398 body = callconduit(repo, 'differential.getrawdiff', {'diffID': diffid})
399 desc = callconduit(repo, 'differential.getcommitmessage',
400 {'revision_id': drev[r'id']})
401 header = '# HG changeset patch\n'
402
403 # Remove potential empty "Summary:"
404 desc = _summaryre.sub('', desc)
351 405
352 patch = ('%s%s\n%s') % (header, desc, body)
406 # Try to preserve metadata from hg:meta property. Write hg patch
407 # headers that can be read by the "import" command. See patchheadermap
408 # and extract in mercurial/patch.py for supported headers.
409 props = diffs[str(diffid)][r'properties'] # could be empty list or dict
410 if props and r'hg:meta' in props:
411 meta = props[r'hg:meta']
412 for k in _metanamemap.keys():
413 if k in meta:
414 header += '# %s %s\n' % (_metanamemap[k], meta[k])
353 415
354 # Check dependencies
355 if recursive:
356 auxiliary = drev.get(r'auxiliary', {})
357 depends = auxiliary.get(r'phabricator:depends-on', [])
358 for phid in depends:
359 patch = readpatch(repo, {'phids': [phid]}, recursive=True) + patch
360 return patch
416 write(('%s%s\n%s') % (header, desc, body))
361 417
362 418 @command('phabread',
363 419 [('', 'stack', False, _('read dependencies'))],
@@ -374,5 +430,4 b' def phabread(ui, repo, revid, **opts):'
374 430 revid = int(revid.split('/')[-1].replace('D', ''))
375 431 except ValueError:
376 432 raise error.Abort(_('invalid Revision ID: %s') % revid)
377 patch = readpatch(repo, {'ids': [revid]}, recursive=opts.get('stack'))
378 ui.write(patch)
433 readpatch(repo, {'ids': [revid]}, ui.write, opts.get('stack'))
General Comments 0
You need to be logged in to leave comments. Login now