##// END OF EJS Templates
phabricator: add --amend option to phabsend...
Jun Wu -
r33784:fa3aa6c9 default
parent child Browse files
Show More
@@ -38,6 +38,8 b' import re'
38 from mercurial.node import bin, nullid
38 from mercurial.node import bin, nullid
39 from mercurial.i18n import _
39 from mercurial.i18n import _
40 from mercurial import (
40 from mercurial import (
41 cmdutil,
42 context,
41 encoding,
43 encoding,
42 error,
44 error,
43 mdiff,
45 mdiff,
@@ -315,7 +317,7 b' def createdifferentialrevision(ctx, revi'
315 if not revision:
317 if not revision:
316 raise error.Abort(_('cannot create revision for %s') % ctx)
318 raise error.Abort(_('cannot create revision for %s') % ctx)
317
319
318 return revision
320 return revision, diff
319
321
320 def userphids(repo, names):
322 def userphids(repo, names):
321 """convert user names to PHIDs"""
323 """convert user names to PHIDs"""
@@ -333,6 +335,7 b' def userphids(repo, names):'
333
335
334 @command('phabsend',
336 @command('phabsend',
335 [('r', 'rev', [], _('revisions to send'), _('REV')),
337 [('r', 'rev', [], _('revisions to send'), _('REV')),
338 ('', 'amend', False, _('update commit messages')),
336 ('', 'reviewer', [], _('specify reviewers')),
339 ('', 'reviewer', [], _('specify reviewers')),
337 ('', 'confirm', None, _('ask for confirmation before sending'))],
340 ('', 'confirm', None, _('ask for confirmation before sending'))],
338 _('REV [OPTIONS]'))
341 _('REV [OPTIONS]'))
@@ -348,18 +351,28 b' def phabsend(ui, repo, *revs, **opts):'
348 obsstore and tags information so it can figure out whether to update an
351 obsstore and tags information so it can figure out whether to update an
349 existing Differential Revision, or create a new one.
352 existing Differential Revision, or create a new one.
350
353
354 If --amend is set, update commit messages so they have the
355 ``Differential Revision`` URL, remove related tags. This is similar to what
356 arcanist will do, and is more desired in author-push workflows. Otherwise,
357 use local tags to record the ``Differential Revision`` association.
358
351 The --confirm option lets you confirm changesets before sending them. You
359 The --confirm option lets you confirm changesets before sending them. You
352 can also add following to your configuration file to make it default
360 can also add following to your configuration file to make it default
353 behaviour.
361 behaviour.
354
362
355 [phabsend]
363 [phabsend]
356 confirm = true
364 confirm = true
365
366 phabsend will check obsstore and the above association to decide whether to
367 update an existing Differential Revision, or create a new one.
357 """
368 """
358 revs = list(revs) + opts.get('rev', [])
369 revs = list(revs) + opts.get('rev', [])
359 revs = scmutil.revrange(repo, revs)
370 revs = scmutil.revrange(repo, revs)
360
371
361 if not revs:
372 if not revs:
362 raise error.Abort(_('phabsend requires at least one changeset'))
373 raise error.Abort(_('phabsend requires at least one changeset'))
374 if opts.get('amend'):
375 cmdutil.checkunfinished(repo)
363
376
364 confirm = ui.configbool('phabsend', 'confirm')
377 confirm = ui.configbool('phabsend', 'confirm')
365 confirm |= bool(opts.get('confirm'))
378 confirm |= bool(opts.get('confirm'))
@@ -377,6 +390,9 b' def phabsend(ui, repo, *revs, **opts):'
377 # {newnode: (oldnode, olddiff, olddrev}
390 # {newnode: (oldnode, olddiff, olddrev}
378 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
391 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
379
392
393 drevids = [] # [int]
394 diffmap = {} # {newnode: diff}
395
380 # Send patches one by one so we know their Differential Revision IDs and
396 # Send patches one by one so we know their Differential Revision IDs and
381 # can provide dependency relationship
397 # can provide dependency relationship
382 lastrevid = None
398 lastrevid = None
@@ -386,17 +402,21 b' def phabsend(ui, repo, *revs, **opts):'
386
402
387 # Get Differential Revision ID
403 # Get Differential Revision ID
388 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
404 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
389 if oldnode != ctx.node():
405 if oldnode != ctx.node() or opts.get('amend'):
390 # Create or update Differential Revision
406 # Create or update Differential Revision
391 revision = createdifferentialrevision(ctx, revid, lastrevid,
407 revision, diff = createdifferentialrevision(
392 oldnode, olddiff, actions)
408 ctx, revid, lastrevid, oldnode, olddiff, actions)
409 diffmap[ctx.node()] = diff
393 newrevid = int(revision[r'object'][r'id'])
410 newrevid = int(revision[r'object'][r'id'])
394 if revid:
411 if revid:
395 action = _('updated')
412 action = _('updated')
396 else:
413 else:
397 action = _('created')
414 action = _('created')
398
415
399 # Create a local tag to note the association
416 # Create a local tag to note the association, if commit message
417 # does not have it already
418 m = _differentialrevisiondescre.search(ctx.description())
419 if not m or int(m.group(1)) != newrevid:
400 tagname = 'D%d' % newrevid
420 tagname = 'D%d' % newrevid
401 tags.tag(repo, tagname, ctx.node(), message=None, user=None,
421 tags.tag(repo, tagname, ctx.node(), message=None, user=None,
402 date=None, local=True)
422 date=None, local=True)
@@ -408,8 +428,43 b' def phabsend(ui, repo, *revs, **opts):'
408
428
409 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
429 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
410 ctx.description().split('\n')[0]))
430 ctx.description().split('\n')[0]))
431 drevids.append(newrevid)
411 lastrevid = newrevid
432 lastrevid = newrevid
412
433
434 # Update commit messages and remove tags
435 if opts.get('amend'):
436 unfi = repo.unfiltered()
437 drevs = callconduit(repo, 'differential.query', {'ids': drevids})
438 with repo.wlock(), repo.lock(), repo.transaction('phabsend'):
439 wnode = unfi['.'].node()
440 mapping = {} # {oldnode: [newnode]}
441 for i, rev in enumerate(revs):
442 old = unfi[rev]
443 drevid = drevids[i]
444 drev = [d for d in drevs if int(d[r'id']) == drevid][0]
445 newdesc = getdescfromdrev(drev)
446 # Make sure commit message contain "Differential Revision"
447 if old.description() != newdesc:
448 parents = [
449 mapping.get(old.p1().node(), (old.p1(),))[0],
450 mapping.get(old.p2().node(), (old.p2(),))[0],
451 ]
452 new = context.metadataonlyctx(
453 repo, old, parents=parents, text=newdesc,
454 user=old.user(), date=old.date(), extra=old.extra())
455 newnode = new.commit()
456 mapping[old.node()] = [newnode]
457 # Update diff property
458 writediffproperties(unfi[newnode], diffmap[old.node()])
459 # Remove local tags since it's no longer necessary
460 tagname = 'D%d' % drevid
461 if tagname in repo.tags():
462 tags.tag(repo, tagname, nullid, message=None, user=None,
463 date=None, local=True)
464 scmutil.cleanupnodes(repo, mapping, 'phabsend')
465 if wnode in mapping:
466 unfi.setparents(mapping[wnode][0])
467
413 # Map from "hg:meta" keys to header understood by "hg import". The order is
468 # Map from "hg:meta" keys to header understood by "hg import". The order is
414 # consistent with "hg export" output.
469 # consistent with "hg export" output.
415 _metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'),
470 _metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'),
General Comments 0
You need to be logged in to leave comments. Login now