diff -r b1158ce4ec50 -r 6a9f0261b181 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)