[PATCH 3 of 7 shelve-ext v5] shelve: add obs-based shelve functionality
Kostia Balytskyi
ikostia at fb.com
Wed Mar 29 09:18:46 EDT 2017
# HG changeset patch
# User Kostia Balytskyi <ikostia at fb.com>
# Date 1490790691 25200
# Wed Mar 29 05:31:31 2017 -0700
# Node ID fc1144e5993a5c85060b913e2d92cd4b1b61772e
# Parent 0aa864184c9d78c11d18980cf0faa10828445ff5
shelve: add obs-based shelve functionality
Obsolescense-based shelve works in a following way:
1. In order to shelve some changes, it creates a commit, records its
node into a .oshelve file and prunes created commit.
2. In order to finish a shelve operation, transaction is just
closed and not aborted.
diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -380,10 +380,15 @@ def _nothingtoshelvemessaging(ui, repo,
else:
ui.status(_("nothing changed\n"))
-def _shelvecreatedcommit(repo, node, name):
- bases = list(mutableancestors(repo[node]))
- shelvedfile(repo, name, 'hg').writebundle(bases, node)
- cmdutil.export(repo, [node],
+def _shelvecreatedcommit(ui, repo, node, name, tr):
+ if isobsshelve(repo, ui):
+ shelvedfile(repo, name, 'oshelve').writeobsshelveinfo({
+ 'node': nodemod.hex(node)
+ })
+ else:
+ bases = list(mutableancestors(repo[node]))
+ shelvedfile(repo, name, 'hg').writebundle(bases, node)
+ cmdutil.export(repo.unfiltered(), [node],
fp=shelvedfile(repo, name, patchextension).opener('wb'),
opts=mdiff.diffopts(git=True))
@@ -394,8 +399,13 @@ def _includeunknownfiles(repo, pats, opt
extra['shelve_unknown'] = '\0'.join(s.unknown)
repo[None].add(s.unknown)
-def _finishshelve(repo):
- _aborttransaction(repo)
+def _finishshelve(ui, repo, tr, node):
+ if isobsshelve(repo, ui):
+ obsolete.createmarkers(repo, [(repo.unfiltered()[node], ())])
+ tr.close()
+ tr.release()
+ else:
+ _aborttransaction(repo)
def _docreatecmd(ui, repo, pats, opts):
wctx = repo[None]
@@ -417,9 +427,12 @@ def _docreatecmd(ui, repo, pats, opts):
try:
lock = repo.lock()
- # use an uncommitted transaction to generate the bundle to avoid
- # pull races. ensure we don't print the abort message to stderr.
- tr = repo.transaction('commit', report=lambda x: None)
+ # depending on whether shelve is traditional or
+ # obsolescense-based, we either abort or commit this
+ # transaction in the end. If we abort it, we don't
+ # want to print anything to stderr
+ report = None if isobsshelve(repo, ui) else (lambda x: None)
+ tr = repo.transaction('commit', report=report)
interactive = opts.get('interactive', False)
includeunknown = (opts.get('unknown', False) and
@@ -447,16 +460,19 @@ def _docreatecmd(ui, repo, pats, opts):
_nothingtoshelvemessaging(ui, repo, pats, opts)
return 1
- _shelvecreatedcommit(repo, node, name)
+ _shelvecreatedcommit(ui, repo, node, name, tr)
if ui.formatted():
desc = util.ellipsis(desc, ui.termwidth())
ui.status(_('shelved as %s\n') % name)
- hg.update(repo, parent.node())
+ # current wc parent may be already obsolete becuase
+ # it might have been created previously and shelve just
+ # reuses it
+ hg.update(repo.unfiltered(), parent.node())
if origbranch != repo['.'].branch() and not _isbareshelve(pats, opts):
repo.dirstate.setbranch(origbranch)
- _finishshelve(repo)
+ _finishshelve(ui, repo, tr, node)
finally:
_restoreactivebookmark(repo, activebookmark)
lockmod.release(tr, lock)
More information about the Mercurial-devel
mailing list