--- a/hgext3rd/topic/__init__.py Fri Sep 01 17:53:14 2017 +0200
+++ b/hgext3rd/topic/__init__.py Fri Sep 01 18:02:50 2017 +0200
@@ -57,6 +57,7 @@
from mercurial.i18n import _
from mercurial import (
+ bookmarks,
cmdutil,
commands,
context,
@@ -439,6 +440,82 @@
branch = repo[None].branch()
return stack.showstack(ui, repo, branch=branch, topic=topic, opts=opts)
+@command('debugcb|debugconvertbookmark', [
+ ('b', 'bookmark', '', _('bookmark to convert to topic')),
+ ('', 'all', None, _('convert all bookmarks to topics')),
+ ],
+ _('[-b BOOKMARK] [--all]'))
+def debugconvertbookmark(ui, repo, **opts):
+ """Converts a bookmark to a topic with the same name.
+ """
+
+ bookmark = opts.get('bookmark')
+ convertall = opts.get('all')
+
+ if convertall and bookmark:
+ raise error.Abort(_("cannot use '--all' and '-b' together"))
+ if not (convertall or bookmark):
+ raise error.Abort(_("you must specify either '--all' or '-b'"))
+
+ bmstore = repo._bookmarks
+ lock = wlock = tr = None
+
+ if bookmark:
+ try:
+ node = bmstore[bookmark]
+ except KeyError:
+ raise error.Abort(_("no such bookmark exists: '%s'") % bookmark)
+
+ revnum = repo[node].rev()
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ tr = repo.transaction('debugconvertbookmark')
+ _convertbmarktopic(ui, repo, revnum, bookmark, tr)
+ tr.close()
+ finally:
+ lockmod.release(tr, lock, wlock)
+
+ elif convertall:
+ # deletion of bookmark will result in change in size of bmstore during
+ # iteration, so let's make a copy to iterate
+ storecopy = bmstore.copy()
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ tr = repo.transaction('debugconvertbookmark')
+ for bmark, revnode in sorted(storecopy.iteritems()):
+ if bmark == '@':
+ continue
+ _convertbmarktopic(ui, repo, repo[revnode].rev(), bmark, tr)
+ tr.close()
+ finally:
+ lockmod.release(tr, lock, wlock)
+
+def _convertbmarktopic(ui, repo, rev, bmark, tr):
+ """Sets a topic as same as bname to all the changesets under the bookmark
+ and delete the bookmark, if topic is set to any changeset
+
+ rev is the revision on which bookmark bmark is and tr is transaction object.
+ """
+
+ # copied from mercurial.repair.stripbmrevset
+ bookrevset = ("ancestors(bookmark(%s)) - ancestors(head() and not "
+ "bookmark(%s)) - ancestors(bookmark() and not "
+ "bookmark(%s))")
+ touchedrevs = repo.revs(bookrevset, bmark, bmark, bmark)
+ rewrote = _changetopics(ui, repo, touchedrevs, bmark)
+ # We didn't changed topic to any changesets because the revset
+ # returned an empty set of revisions, so let's skip deleting the
+ # bookmark corresponding to which we didn't put a topic on any
+ # changeset
+ if rewrote == 0:
+ return
+ ui.status(_('changed topic to "%s" on %d revisions\n') % (bmark,
+ rewrote))
+ ui.debug('removing bookmark "%s" from "%d"' % (bmark, rev))
+ bookmarks.delete(repo, tr, [bmark])
+
def _changecurrenttopic(repo, newtopic):
"""changes the current topic."""