--- a/hgext/drophack.py Tue Feb 28 17:04:58 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-'''This extension add a hacky command to drop changeset during review
-
-This extension is intended as a temporary hack to allow Matt Mackall to use
-evolve in the Mercurial review it self. You should probably not use it if your
-name is not Matt Mackall.
-'''
-
-import os
-import time
-import contextlib
-
-from mercurial.i18n import _
-from mercurial import cmdutil
-from mercurial import repair
-from mercurial import scmutil
-from mercurial import lock as lockmod
-from mercurial import util
-from mercurial import commands
-
-cmdtable = {}
-command = cmdutil.command(cmdtable)
-
-
-@contextlib.contextmanager
-def timed(ui, caption):
- ostart = os.times()
- cstart = time.time()
- yield
- cstop = time.time()
- ostop = os.times()
- wall = cstop - cstart
- user = ostop[0] - ostart[0]
- sys = ostop[1] - ostart[1]
- comb = user + sys
- ui.write("%s: wall %f comb %f user %f sys %f\n"
- % (caption, wall, comb, user, sys))
-
-def obsmarkerchainfrom(obsstore, nodes):
- """return all marker chain starting from node
-
- Starting from mean "use as successors"."""
- # XXX need something smarter for descendant of bumped changeset
- seennodes = set(nodes)
- seenmarkers = set()
- pendingnodes = set(nodes)
- precursorsmarkers = obsstore.precursors
- while pendingnodes:
- current = pendingnodes.pop()
- new = set()
- for precmark in precursorsmarkers.get(current, ()):
- if precmark in seenmarkers:
- continue
- seenmarkers.add(precmark)
- new.add(precmark[0])
- yield precmark
- new -= seennodes
- pendingnodes |= new
-
-def stripmarker(ui, repo, markers):
- """remove <markers> from the repo obsstore
-
- The old obsstore content is saved in a `obsstore.prestrip` file
- """
- repo = repo.unfiltered()
- repo.destroying()
- oldmarkers = list(repo.obsstore._all)
- util.rename(repo.sjoin('obsstore'),
- repo.join('obsstore.prestrip'))
- del repo.obsstore # drop the cache
- newstore = repo.obsstore
- assert not newstore # should be empty after rename
- newmarkers = [m for m in oldmarkers if m not in markers]
- tr = repo.transaction('drophack')
- try:
- newstore.add(tr, newmarkers)
- tr.close()
- finally:
- tr.release()
- repo.destroyed()
-
-
-@command('drop', [('r', 'rev', [], 'revision to update')], _('[-r] revs'))
-def cmddrop(ui, repo, *revs, **opts):
- """I'm hacky do not use me!
-
- This command strip a changeset, its precursors and all obsolescence marker
- associated to its chain.
-
- There is no way to limit the extend of the purge yet. You may have to
- repull from other source to get some changeset and obsolescence marker
- back.
-
- This intended for Matt Mackall usage only. do not use me.
- """
- revs = list(revs)
- revs.extend(opts['rev'])
- if not revs:
- revs = ['.']
- # get the changeset
- revs = scmutil.revrange(repo, revs)
- if not revs:
- ui.write_err('no revision to drop\n')
- return 1
- # lock from the beginning to prevent race
- wlock = lock = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- # check they have no children
- if repo.revs('%ld and public()', revs):
- ui.write_err('cannot drop public revision')
- return 1
- if repo.revs('children(%ld) - %ld', revs, revs):
- ui.write_err('cannot drop revision with children')
- return 1
- if repo.revs('. and %ld', revs):
- newrevs = repo.revs('max(::. - %ld)', revs)
- if newrevs:
- assert len(newrevs) == 1
- newrev = newrevs.first()
- else:
- newrev = -1
- commands.update(ui, repo, newrev)
- ui.status(_('working directory now at %s\n') % repo[newrev])
- # get all markers and successors up to root
- nodes = [repo[r].node() for r in revs]
- with timed(ui, 'search obsmarker'):
- markers = set(obsmarkerchainfrom(repo.obsstore, nodes))
- ui.write('%i obsmarkers found\n' % len(markers))
- cl = repo.unfiltered().changelog
- with timed(ui, 'search nodes'):
- allnodes = set(nodes)
- allnodes.update(m[0] for m in markers if cl.hasnode(m[0]))
- ui.write('%i nodes found\n' % len(allnodes))
- cl = repo.changelog
- visiblenodes = set(n for n in allnodes if cl.hasnode(n))
- # check constraint again
- if repo.revs('%ln and public()', visiblenodes):
- ui.write_err('cannot drop public revision')
- return 1
- if repo.revs('children(%ln) - %ln', visiblenodes, visiblenodes):
- ui.write_err('cannot drop revision with children')
- return 1
-
- if markers:
- # strip them
- with timed(ui, 'strip obsmarker'):
- stripmarker(ui, repo, markers)
- # strip the changeset
- with timed(ui, 'strip nodes'):
- repair.strip(ui, repo, list(allnodes), backup="all",
- topic='drophack')
-
- finally:
- lockmod.release(lock, wlock)
-
- # rewrite the whole file.
- # print data.
- # - time to compute the chain
- # - time to strip the changeset
- # - time to strip the obs marker.