Mercurial > hg
diff hgext/rebase.py @ 37787:92213f6745ed
rebase: introduce support for automatically rebasing orphan changes
_destautorebase(SRC) is based on the _destrestack(SRC) revset from
fbamend. The supporting _possibledestination function is extracted
from evolve, with minor cleanups.
We've considered some alternatives here:
* This change, but with --auto as the flag name. We're hedging our bets
on this a little in this change so that if this ends up being the wrong
direction we haven't burned the valauble --auto name on rebase.
* --destination auto: I've got reservations about the discoverability of this,
and we don't currently have a good story for a revset alias of sorts that
changes behavior depending on the context in which it's used.
* A "rebase presets" feature, where we could use the currently-an-error
positional argument space for the rebase command to define presets, so that
users could define a 'linearize' preset that specifies
--revision='orphan()-obsolete()' and --dest=_destautoorphanrebase(SRC).
Personally, I find the third option somewhat appealing, but am
hesitant to "spend" the functionality space of positional arguments to
the rebase command. We should revisit the way we expose this
functionality sometime in the 4.7 cycle once we've had a chance to vet
the implementation of the functionality.
Differential Revision: https://phab.mercurial-scm.org/D2668
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 04 Mar 2018 15:29:41 -0500 |
parents | 953db9e00eeb |
children | 46e8abc4eb04 69d1cafe75f2 |
line wrap: on
line diff
--- a/hgext/rebase.py Wed Apr 18 14:32:36 2018 -0400 +++ b/hgext/rebase.py Sun Mar 04 15:29:41 2018 -0500 @@ -108,6 +108,25 @@ sourceset = revset.getset(repo, smartset.fullreposet(repo), x) return subset & smartset.baseset([_destrebase(repo, sourceset)]) +@revsetpredicate('_destautoorphanrebase') +def _revsetdestautoorphanrebase(repo, subset, x): + """automatic rebase destination for a single orphan revision""" + unfi = repo.unfiltered() + obsoleted = unfi.revs('obsolete()') + + src = revset.getset(repo, subset, x).first() + + # Empty src or already obsoleted - Do not return a destination + if not src or src in obsoleted: + return smartset.baseset() + dests = destutil.orphanpossibledestination(repo, src) + if len(dests) > 1: + raise error.Abort( + _("ambiguous automatic rebase: %r could end up on any of %r") % ( + src, dests)) + # We have zero or one destination, so we can just return here. + return smartset.baseset(dests) + def _ctxdesc(ctx): """short description for a context""" desc = '%d:%s "%s"' % (ctx.rev(), ctx, @@ -651,7 +670,10 @@ ('i', 'interactive', False, _('(DEPRECATED)')), ('t', 'tool', '', _('specify merge tool')), ('c', 'continue', False, _('continue an interrupted rebase')), - ('a', 'abort', False, _('abort an interrupted rebase'))] + + ('a', 'abort', False, _('abort an interrupted rebase')), + ('', 'auto-orphans', '', _('automatically rebase orphan revisions ' + 'in the specified revset (EXPERIMENTAL)')), + ] + cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) def rebase(ui, repo, **opts): @@ -783,6 +805,15 @@ # fail the entire transaction.) inmemory = False + if opts.get('auto_orphans'): + for key in opts: + if key != 'auto_orphans' and opts.get(key): + raise error.Abort(_('--auto-orphans is incompatible with %s') % + ('--' + key)) + userrevs = list(repo.revs(opts.get('auto_orphans'))) + opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] + opts['dest'] = '_destautoorphanrebase(SRC)' + if inmemory: try: # in-memory merge doesn't support conflicts, so if we hit any, abort