prune: remove a list of bookmarks
authorShubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
Fri, 11 Dec 2015 10:42:46 -0800
changeset 1563 6a9f0261b181
parent 1562 b1158ce4ec50
child 1564 42c30774e63d
prune: remove a list of bookmarks Currently prune works with a single bookmark, the changes in this patch modifies the prune module to work with a list of bookmarks Building on this we can take a list of bookmarks as input and remove all of them in a single go
hgext/evolve.py
--- a/hgext/evolve.py	Fri Dec 11 11:15:33 2015 +0000
+++ b/hgext/evolve.py	Fri Dec 11 10:42:46 2015 -0800
@@ -2208,46 +2208,48 @@
         return 1
     return result
 
-def _reachablefrombookmark(repo, revs, bookmark):
+def _reachablefrombookmark(repo, revs, bookmarks):
     """filter revisions and bookmarks reachable from the given bookmark
     yoinked from mq.py
     """
     repomarks = repo._bookmarks
-    if bookmark not in repomarks:
-        raise error.Abort(_("bookmark '%s' not found") % bookmark)
+    if not bookmarks.issubset(repomarks):
+        raise error.Abort(_("bookmark '%s' not found") %
+            ','.join(sorted(bookmarks - set(repomarks.keys()))))
 
     # If the requested bookmark is not the only one pointing to a
     # a revision we have to only delete the bookmark and not strip
     # anything. revsets cannot detect that case.
-    uniquebm = True
-    for m, n in repomarks.iteritems():
-        if m != bookmark and n == repo[bookmark].node():
-            uniquebm = False
-            break
-    if uniquebm:
-        if util.safehasattr(repair, 'stripbmrevset'):
-            rsrevs = repair.stripbmrevset(repo, bookmark)
-        else:
-            rsrevs = repo.revs("ancestors(bookmark(%s)) - "
-                               "ancestors(head() and not bookmark(%s)) - "
-                               "ancestors(bookmark() and not bookmark(%s)) - "
-                               "obsolete()",
-                               bookmark, bookmark, bookmark)
-        revs = set(revs)
-        revs.update(set(rsrevs))
-        revs = sorted(revs)
+    nodetobookmarks = {}
+    for mark, node in repomarks.iteritems():
+        nodetobookmarks.setdefault(node, []).append(mark)
+    for marks in nodetobookmarks.values():
+        if bookmarks.issuperset(marks):
+           if util.safehasattr(repair, 'stripbmrevset'):
+               rsrevs = repair.stripbmrevset(repo, marks[0])
+           else:
+               rsrevs = repo.revs("ancestors(bookmark(%s)) - "
+                                  "ancestors(head() and not bookmark(%s)) - "
+                                  "ancestors(bookmark() and not bookmark(%s)) - "
+                                  "obsolete()",
+                                  marks[0], marks[0], marks[0])
+           revs = set(revs)
+           revs.update(set(rsrevs))
+           revs = sorted(revs)
     return repomarks, revs
 
-def _deletebookmark(repo, repomarks, bookmark):
+def _deletebookmark(repo, repomarks, bookmarks):
     wlock = lock = tr = None
     try:
         wlock = repo.wlock()
         lock = repo.lock()
         tr = repo.transaction('prune')
-        del repomarks[bookmark]
+        for bookmark in bookmarks:
+            del repomarks[bookmark]
         repomarks.recordchange(tr)
         tr.close()
-        repo.ui.write(_("bookmark '%s' deleted\n") % bookmark)
+        for bookmark in sorted(bookmarks):
+            repo.ui.write(_("bookmark '%s' deleted\n") % bookmark)
     finally:
         lockmod.release(tr, lock, wlock)
 
@@ -2303,7 +2305,9 @@
     """
     revs = scmutil.revrange(repo, list(revs) + opts.get('rev'))
     succs = opts['new'] + opts['succ']
-    bookmark = opts.get('bookmark')
+    bookmarks = None
+    if opts.get('bookmark'):
+        bookmarks = set([opts.get('bookmark')])
     metadata = _getmetadata(**opts)
     biject = opts.get('biject')
     fold = opts.get('fold')
@@ -2313,11 +2317,11 @@
     if 1 < len(options):
         raise error.Abort(_("can only specify one of %s") % ', '.join(options))
 
-    if bookmark:
-        repomarks, revs = _reachablefrombookmark(repo, revs, bookmark)
+    if bookmarks:
+        repomarks, revs = _reachablefrombookmark(repo, revs, bookmarks)
         if not revs:
             # no revisions to prune - delete bookmark immediately
-            _deletebookmark(repo, repomarks, bookmark)
+            _deletebookmark(repo, repomarks, bookmarks)
 
     if not revs:
         raise error.Abort(_('nothing to prune'))
@@ -2406,7 +2410,7 @@
                 # Active bookmark that we don't want to delete (with -B option)
                 # we deactivate and move it before the update and reactivate it
                 # after
-                movebookmark = bookactive and not bookmark
+                movebookmark = bookactive and not bookmarks
                 if movebookmark:
                     bmdeactivate(repo)
                     repo._bookmarks[bookactive] = newnode.node()
@@ -2417,8 +2421,8 @@
                     bmactivate(repo, bookactive)
 
         # update bookmarks
-        if bookmark:
-            _deletebookmark(repo, repomarks, bookmark)
+        if bookmarks:
+            _deletebookmark(repo, repomarks, bookmarks)
 
         # create markers
         obsolete.createmarkers(repo, relations, metadata=metadata)