Show More
@@ -38,6 +38,8 b' import re' | |||
|
38 | 38 | from mercurial.node import bin, nullid |
|
39 | 39 | from mercurial.i18n import _ |
|
40 | 40 | from mercurial import ( |
|
41 | cmdutil, | |
|
42 | context, | |
|
41 | 43 | encoding, |
|
42 | 44 | error, |
|
43 | 45 | mdiff, |
@@ -315,7 +317,7 b' def createdifferentialrevision(ctx, revi' | |||
|
315 | 317 | if not revision: |
|
316 | 318 | raise error.Abort(_('cannot create revision for %s') % ctx) |
|
317 | 319 | |
|
318 | return revision | |
|
320 | return revision, diff | |
|
319 | 321 | |
|
320 | 322 | def userphids(repo, names): |
|
321 | 323 | """convert user names to PHIDs""" |
@@ -333,6 +335,7 b' def userphids(repo, names):' | |||
|
333 | 335 | |
|
334 | 336 | @command('phabsend', |
|
335 | 337 | [('r', 'rev', [], _('revisions to send'), _('REV')), |
|
338 | ('', 'amend', False, _('update commit messages')), | |
|
336 | 339 | ('', 'reviewer', [], _('specify reviewers')), |
|
337 | 340 | ('', 'confirm', None, _('ask for confirmation before sending'))], |
|
338 | 341 | _('REV [OPTIONS]')) |
@@ -348,18 +351,28 b' def phabsend(ui, repo, *revs, **opts):' | |||
|
348 | 351 | obsstore and tags information so it can figure out whether to update an |
|
349 | 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 | 359 | The --confirm option lets you confirm changesets before sending them. You |
|
352 | 360 | can also add following to your configuration file to make it default |
|
353 | 361 | behaviour. |
|
354 | 362 | |
|
355 | 363 | [phabsend] |
|
356 | 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 | 369 | revs = list(revs) + opts.get('rev', []) |
|
359 | 370 | revs = scmutil.revrange(repo, revs) |
|
360 | 371 | |
|
361 | 372 | if not revs: |
|
362 | 373 | raise error.Abort(_('phabsend requires at least one changeset')) |
|
374 | if opts.get('amend'): | |
|
375 | cmdutil.checkunfinished(repo) | |
|
363 | 376 | |
|
364 | 377 | confirm = ui.configbool('phabsend', 'confirm') |
|
365 | 378 | confirm |= bool(opts.get('confirm')) |
@@ -377,6 +390,9 b' def phabsend(ui, repo, *revs, **opts):' | |||
|
377 | 390 | # {newnode: (oldnode, olddiff, olddrev} |
|
378 | 391 | oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs]) |
|
379 | 392 | |
|
393 | drevids = [] # [int] | |
|
394 | diffmap = {} # {newnode: diff} | |
|
395 | ||
|
380 | 396 | # Send patches one by one so we know their Differential Revision IDs and |
|
381 | 397 | # can provide dependency relationship |
|
382 | 398 | lastrevid = None |
@@ -386,20 +402,24 b' def phabsend(ui, repo, *revs, **opts):' | |||
|
386 | 402 | |
|
387 | 403 | # Get Differential Revision ID |
|
388 | 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 | 406 | # Create or update Differential Revision |
|
391 |
revision = createdifferentialrevision( |
|
|
392 |
|
|
|
407 | revision, diff = createdifferentialrevision( | |
|
408 | ctx, revid, lastrevid, oldnode, olddiff, actions) | |
|
409 | diffmap[ctx.node()] = diff | |
|
393 | 410 | newrevid = int(revision[r'object'][r'id']) |
|
394 | 411 | if revid: |
|
395 | 412 | action = _('updated') |
|
396 | 413 | else: |
|
397 | 414 | action = _('created') |
|
398 | 415 | |
|
399 | # Create a local tag to note the association | |
|
400 | tagname = 'D%d' % newrevid | |
|
401 | tags.tag(repo, tagname, ctx.node(), message=None, user=None, | |
|
402 | date=None, local=True) | |
|
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: | |
|
420 | tagname = 'D%d' % newrevid | |
|
421 | tags.tag(repo, tagname, ctx.node(), message=None, user=None, | |
|
422 | date=None, local=True) | |
|
403 | 423 | else: |
|
404 | 424 | # Nothing changed. But still set "newrevid" so the next revision |
|
405 | 425 | # could depend on this one. |
@@ -408,8 +428,43 b' def phabsend(ui, repo, *revs, **opts):' | |||
|
408 | 428 | |
|
409 | 429 | ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx, |
|
410 | 430 | ctx.description().split('\n')[0])) |
|
431 | drevids.append(newrevid) | |
|
411 | 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 | 468 | # Map from "hg:meta" keys to header understood by "hg import". The order is |
|
414 | 469 | # consistent with "hg export" output. |
|
415 | 470 | _metanamemap = util.sortdict([(r'user', 'User'), (r'date', 'Date'), |
General Comments 0
You need to be logged in to leave comments.
Login now