[PATCH shelve-ext] shelve: add logic to preserve active bookmarks
Kostia Balytskyi
ikostia at fb.com
Sun Mar 26 19:50:58 EDT 2017
Actually, please disregard. V2 is coming.
-----Original Message-----
From: Mercurial-devel [mailto:mercurial-devel-bounces at mercurial-scm.org] On Behalf Of Kostia Balytskyi
Sent: Monday, 27 March, 2017 00:22
To: mercurial-devel at mercurial-scm.org
Subject: [PATCH shelve-ext] shelve: add logic to preserve active bookmarks
# HG changeset patch
# User Kostia Balytskyi <ikostia at fb.com> # Date 1490570316 25200
# Sun Mar 26 16:18:36 2017 -0700
# Node ID bf8bee90e60aafe591279cab2077e82cbae86573
# Parent c60091fa1426892552dd6c0dd4b9c49e3c3da045
shelve: add logic to preserve active bookmarks
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.
Note: shelve-finishing logic in this patch handles this twice (in _finishshelve and in finally block). This is redundant for traditional shelve, but will be necessary for obs-based shelve which has successful transactions.
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
'''
@@ -358,7 +376,9 @@ def _includeunknownfiles(repo, pats, opt
extra['shelve_unknown'] = '\0'.join(s.unknown)
repo[None].add(s.unknown)
-def _finishshelve(repo):
+def _finishshelve(repo, activebookmark):
+ if activebookmark:
+ bookmarks.activate(repo, activebookmark)
_aborttransaction(repo)
def _docreatecmd(ui, repo, pats, opts):
@@ -377,7 +397,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 +410,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 +425,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
@@ -418,8 +440,9 @@ def _docreatecmd(ui, repo, pats, opts):
if origbranch != repo['.'].branch() and not _isbareshelve(pats, opts):
repo.dirstate.setbranch(origbranch)
- _finishshelve(repo)
+ _finishshelve(repo, activebookmark)
finally:
+ _restoreactivebookmark(repo, activebookmark)
lockmod.release(tr, lock)
def _isbareshelve(pats, opts):
@@ -639,6 +662,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 +696,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 +718,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 +744,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 +891,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 +906,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://urldefense.proofpoint.com/v2/url?u=https-3A__www.mercurial-2Dscm.org_mailman_listinfo_mercurial-2Ddevel&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Pp-gQYFgs4tKlSFPF5kfCw&m=UfkAC9K6wA-4OBqX3aDULFAfT65tSHhcvx7kPSuIZVc&s=OVtYch5600Z9FQPNtMvP7Muws1xPsOsaZRepar9rEgI&e=
More information about the Mercurial-devel
mailing list