##// 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 _metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'),
314 _metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'),
315 (r'node', 'Node ID'), (r'parent', 'Parent ')])
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 """generate plain-text patch readable by 'hg import'
381 """generate plain-text patch readable by 'hg import'
319
382
320 params is passed to "differential.query". If recursive is True, also return
383 write is usually ui.write. params is passed to "differential.query". If
321 dependent patches.
384 stack is True, also write dependent patches.
322 """
385 """
323 # Differential Revisions
386 # Differential Revisions
324 drevs = callconduit(repo, 'differential.query', params)
387 drevs = querydrev(repo, params, stack)
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'])
331
388
332 diffid = max(int(v) for v in drev[r'diffs'])
389 # Prefetch hg:meta property for all diffs
333 body = callconduit(repo, 'differential.getrawdiff', {'diffID': diffid})
390 diffids = sorted(set(max(int(v) for v in drev[r'diffs']) for drev in drevs))
334 desc = callconduit(repo, 'differential.getcommitmessage',
391 diffs = callconduit(repo, 'differential.querydiffs', {'ids': diffids})
335 {'revision_id': drev[r'id']})
336 header = '# HG changeset patch\n'
337
392
338 # Remove potential empty "Summary:"
393 # Generate patch for each drev
339 desc = _summaryre.sub('', desc)
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
397 diffid = max(int(v) for v in drev[r'diffs'])
342 # that can be read by the "import" command. See patchheadermap and extract
398 body = callconduit(repo, 'differential.getrawdiff', {'diffID': diffid})
343 # in mercurial/patch.py for supported headers.
399 desc = callconduit(repo, 'differential.getcommitmessage',
344 diffs = callconduit(repo, 'differential.querydiffs', {'ids': [diffid]})
400 {'revision_id': drev[r'id']})
345 props = diffs[str(diffid)][r'properties'] # could be empty list or dict
401 header = '# HG changeset patch\n'
346 if props and r'hg:meta' in props:
402
347 meta = props[r'hg:meta']
403 # Remove potential empty "Summary:"
348 for k in _metanamemap.keys():
404 desc = _summaryre.sub('', desc)
349 if k in meta:
350 header += '# %s %s\n' % (_metanamemap[k], meta[k])
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
416 write(('%s%s\n%s') % (header, desc, body))
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
361
417
362 @command('phabread',
418 @command('phabread',
363 [('', 'stack', False, _('read dependencies'))],
419 [('', 'stack', False, _('read dependencies'))],
@@ -374,5 +430,4 b' def phabread(ui, repo, revid, **opts):'
374 revid = int(revid.split('/')[-1].replace('D', ''))
430 revid = int(revid.split('/')[-1].replace('D', ''))
375 except ValueError:
431 except ValueError:
376 raise error.Abort(_('invalid Revision ID: %s') % revid)
432 raise error.Abort(_('invalid Revision ID: %s') % revid)
377 patch = readpatch(repo, {'ids': [revid]}, recursive=opts.get('stack'))
433 readpatch(repo, {'ids': [revid]}, ui.write, opts.get('stack'))
378 ui.write(patch)
General Comments 0
You need to be logged in to leave comments. Login now