[PATCH shelve-ext v2] shelve: add logic to preserve active bookmarks
Augie Fackler
raf at durin42.com
Mon Mar 27 12:34:14 EDT 2017
On Sun, Mar 26, 2017 at 04:52:56PM -0700, Kostia Balytskyi wrote:
> # HG changeset patch
> # User Kostia Balytskyi <ikostia at fb.com>
> # Date 1490572279 25200
> # Sun Mar 26 16:51:19 2017 -0700
> # Node ID 89739c20e31944f987de17620d76c82df6f0eda7
> # Parent c60091fa1426892552dd6c0dd4b9c49e3c3da045
> shelve: add logic to preserve active bookmarks
Queued this, very happy to have this explicit instead of implicit.
>
> This adds an explicit active-bookmark-handling logic
> to shelve. Traditional shelve handles it by transaction aborts,
> but it is a bit ugly and having an explicit functionality
> seems better.
>
> diff --git a/hgext/shelve.py b/hgext/shelve.py
> --- a/hgext/shelve.py
> +++ b/hgext/shelve.py
> @@ -28,6 +28,7 @@ import itertools
>
> from mercurial.i18n import _
> from mercurial import (
> + bookmarks,
> bundle2,
> bundlerepo,
> changegroup,
> @@ -170,6 +171,8 @@ class shelvedstate(object):
> _filename = 'shelvedstate'
> _keep = 'keep'
> _nokeep = 'nokeep'
> + # colon is essential to differentiate from a real bookmark name
> + _noactivebook = ':no-active-bookmark'
>
> @classmethod
> def load(cls, repo):
> @@ -187,6 +190,7 @@ class shelvedstate(object):
> nodestoprune = [nodemod.bin(h) for h in fp.readline().split()]
> branchtorestore = fp.readline().strip()
> keep = fp.readline().strip() == cls._keep
> + activebook = fp.readline().strip()
> except (ValueError, TypeError) as err:
> raise error.CorruptedState(str(err))
> finally:
> @@ -201,6 +205,9 @@ class shelvedstate(object):
> obj.nodestoprune = nodestoprune
> obj.branchtorestore = branchtorestore
> obj.keep = keep
> + obj.activebookmark = ''
> + if activebook != cls._noactivebook:
> + obj.activebookmark = activebook
> except error.RepoLookupError as err:
> raise error.CorruptedState(str(err))
>
> @@ -208,7 +215,7 @@ class shelvedstate(object):
>
> @classmethod
> def save(cls, repo, name, originalwctx, pendingctx, nodestoprune,
> - branchtorestore, keep=False):
> + branchtorestore, keep=False, activebook=''):
> fp = repo.vfs(cls._filename, 'wb')
> fp.write('%i\n' % cls._version)
> fp.write('%s\n' % name)
> @@ -220,6 +227,7 @@ class shelvedstate(object):
> ' '.join([nodemod.hex(n) for n in nodestoprune]))
> fp.write('%s\n' % branchtorestore)
> fp.write('%s\n' % (cls._keep if keep else cls._nokeep))
> + fp.write('%s\n' % (activebook or cls._noactivebook))
> fp.close()
>
> @classmethod
> @@ -244,6 +252,16 @@ def cleanupoldbackups(repo):
> for ext in shelvefileextensions:
> vfs.tryunlink(base + '.' + ext)
>
> +def _backupactivebookmark(repo):
> + activebookmark = repo._activebookmark
> + if activebookmark:
> + bookmarks.deactivate(repo)
> + return activebookmark
> +
> +def _restoreactivebookmark(repo, mark):
> + if mark:
> + bookmarks.activate(repo, mark)
> +
> def _aborttransaction(repo):
> '''Abort current transaction for shelve/unshelve, but keep dirstate
> '''
> @@ -377,7 +395,7 @@ def _docreatecmd(ui, repo, pats, opts):
> if not opts.get('message'):
> opts['message'] = desc
>
> - lock = tr = None
> + lock = tr = activebookmark = None
> try:
> lock = repo.lock()
>
> @@ -390,6 +408,7 @@ def _docreatecmd(ui, repo, pats, opts):
> not opts.get('addremove', False))
>
> name = getshelvename(repo, parent, opts)
> + activebookmark = _backupactivebookmark(repo)
> extra = {}
> if includeunknown:
> _includeunknownfiles(repo, pats, opts, extra)
> @@ -404,7 +423,8 @@ def _docreatecmd(ui, repo, pats, opts):
> node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
> else:
> node = cmdutil.dorecord(ui, repo, commitfunc, None,
> - False, cmdutil.recordfilter, *pats, **opts)
> + False, cmdutil.recordfilter, *pats,
> + **opts)
> if not node:
> _nothingtoshelvemessaging(ui, repo, pats, opts)
> return 1
> @@ -420,6 +440,7 @@ def _docreatecmd(ui, repo, pats, opts):
>
> _finishshelve(repo)
> finally:
> + _restoreactivebookmark(repo, activebookmark)
> lockmod.release(tr, lock)
>
> def _isbareshelve(pats, opts):
> @@ -639,6 +660,7 @@ def unshelvecontinue(ui, repo, state, op
> restorebranch(ui, repo, state.branchtorestore)
>
> repair.strip(ui, repo, state.nodestoprune, backup=False, topic='shelve')
> + _restoreactivebookmark(repo, state.activebookmark)
> shelvedstate.clear(repo)
> unshelvecleanup(ui, repo, state.name, opts)
> ui.status(_("unshelve of '%s' complete\n") % state.name)
> @@ -672,7 +694,8 @@ def _unshelverestorecommit(ui, repo, bas
> return repo, shelvectx
>
> def _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev, basename, pctx,
> - tmpwctx, shelvectx, branchtorestore):
> + tmpwctx, shelvectx, branchtorestore,
> + activebookmark):
> """Rebase restored commit from its original location to a destination"""
> # If the shelve is not immediately on top of the commit
> # we'll be merging with, rebase it to be on top.
> @@ -693,7 +716,7 @@ def _rebaserestoredcommit(ui, repo, opts
> nodestoprune = [repo.changelog.node(rev)
> for rev in xrange(oldtiprev, len(repo))]
> shelvedstate.save(repo, basename, pctx, tmpwctx, nodestoprune,
> - branchtorestore, opts.get('keep'))
> + branchtorestore, opts.get('keep'), activebookmark)
>
> repo.vfs.rename('rebasestate', 'unshelverebasestate')
> raise error.InterventionRequired(
> @@ -719,7 +742,8 @@ def _forgetunknownfiles(repo, shelvectx,
> toforget = (addedafter & shelveunknown) - addedbefore
> repo[None].forget(toforget)
>
> -def _finishunshelve(repo, oldtiprev, tr):
> +def _finishunshelve(repo, oldtiprev, tr, activebookmark):
> + _restoreactivebookmark(repo, activebookmark)
> # The transaction aborting will strip all the commits for us,
> # but it doesn't update the inmemory structures, so addchangegroup
> # hooks still fire and try to operate on the missing commits.
> @@ -865,6 +889,7 @@ def _dounshelve(ui, repo, *shelved, **op
> # and shelvectx is the unshelved changes. Then we merge it all down
> # to the original pctx.
>
> + activebookmark = _backupactivebookmark(repo)
> overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
> with ui.configoverride(overrides, 'unshelve'):
> tmpwctx, addedbefore = _commitworkingcopychanges(ui, repo, opts,
> @@ -879,13 +904,14 @@ def _dounshelve(ui, repo, *shelved, **op
>
> shelvectx = _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev,
> basename, pctx, tmpwctx,
> - shelvectx, branchtorestore)
> + shelvectx, branchtorestore,
> + activebookmark)
> mergefiles(ui, repo, pctx, shelvectx)
> restorebranch(ui, repo, branchtorestore)
> _forgetunknownfiles(repo, shelvectx, addedbefore)
>
> shelvedstate.clear(repo)
> - _finishunshelve(repo, oldtiprev, tr)
> + _finishunshelve(repo, oldtiprev, tr, activebookmark)
> unshelvecleanup(ui, repo, basename, opts)
> finally:
> ui.quiet = oldquiet
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list