Patchwork [2,of,3,evolve-ext,v2] prune: remove a list of bookmarks

login
register
mail settings
Submitter Shubhanshu Agrawal
Date Dec. 11, 2015, 8:28 p.m.
Message ID <dd37098b0235b9bd3f2d.1449865712@shubhanshu-mbp.dhcp.thefacebook.com>
Download mbox | patch
Permalink /patch/11977/
State Accepted
Headers show

Comments

Shubhanshu Agrawal - Dec. 11, 2015, 8:28 p.m.
# HG changeset patch
# User Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
# Date 1449859366 28800
#      Fri Dec 11 10:42:46 2015 -0800
# Node ID dd37098b0235b9bd3f2d43b5fa7c14c2fa12e19d
# Parent  f93f4e4374bad7eb2c2d1853a98a1e6826cf789e
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

Patch

diff --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -2200,46 +2200,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)
 
@@ -2295,7 +2297,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')
@@ -2305,11 +2309,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'))
@@ -2398,7 +2402,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()
@@ -2409,8 +2413,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)