diff --git a/hgext3rd/fbamend/__init__.py b/hgext3rd/fbamend/__init__.py --- a/hgext3rd/fbamend/__init__.py +++ b/hgext3rd/fbamend/__init__.py @@ -67,6 +67,7 @@ common, fold, hiddenoverride, + hide, metaedit, movement, prune, @@ -84,6 +85,7 @@ command = registrar.command(cmdtable) cmdtable.update(fold.cmdtable) +cmdtable.update(hide.cmdtable) cmdtable.update(metaedit.cmdtable) cmdtable.update(movement.cmdtable) cmdtable.update(prune.cmdtable) diff --git a/hgext3rd/fbamend/hide.py b/hgext3rd/fbamend/hide.py new file mode 100644 --- /dev/null +++ b/hgext3rd/fbamend/hide.py @@ -0,0 +1,91 @@ +# hide.py - simple an user-friendly commands to hide and unhide commits +# +# Copyright 2011 Peter Arrenbrecht +# Logilab SA +# Pierre-Yves David +# Patrick Mezard +# Copyright 2017 Facebook, Inc. +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. +from __future__ import absolute_import +from mercurial import ( + bookmarks as bookmarksmod, + commands, + error, + lock as lockmod, + obsolete, + registrar, + scmutil, +) +from mercurial.i18n import _ + +cmdtable = {} +command = registrar.command(cmdtable) + +@command('^hide', [('r', 'rev', [], _("revisions to hide"))]) +def hide(ui, repo, *revs, **opts): + """hide changesets and their descendants + + Hidden changesets are still accessible by their hashes which can be found + in ``hg journal``. + + If a parent of the working directory is hidden, then the working directory + will automatically be updated to the most recent available ancestor of the + hidden parent. + + If there is a bookmark pointing to the commit it will be removed. + """ + revs = list(revs) + opts.pop('rev', []) + revs = set(scmutil.revrange(repo, revs)) + revs = repo.revs("(%ld)::", revs) + + if not revs: + raise error.Abort(_('nothing to hide')) + + wlock = lock = tr = None + + try: + wlock = repo.wlock() + lock = repo.lock() + tr = repo.transaction('hide') + # revs to be hidden + hrevs = [] + for r in revs: + cr = repo[r] + if not cr.mutable(): + raise error.Abort(_('cannot hide immutable changeset: %s') % cr, + hint="see 'hg help phases' for details") + hrevs.append(cr) + if not hrevs: + raise error.Abort('nothing to hide') + + wdp = repo['.'] + newnode = wdp + + while newnode in hrevs: + newnode = newnode.parents()[0] + + if newnode.node() != wdp.node(): + commands.update(ui, repo, newnode.rev()) + ui.status(_('working directory now at %s\n') + % ui.label(str(newnode), 'evolve.node')) + + # create markers + obsolete.createmarkers(repo, [(r, []) for r in hrevs], + operation='hide') + ui.status(_('%i changesets hidden\n') % len(hrevs)) + + # remove bookmarks pointing to hidden changesets + hnodes = [r.node() for r in hrevs] + bookmarks = [] + for book, node in bookmarksmod.listbinbookmarks(repo): + if node in hnodes: + bookmarks.append(book) + bookmarksmod.delete(repo, tr, bookmarks) + if len(bookmarks) > 0: + ui.status(_('%i bookmarks removed\n') % len(bookmarks)) + + tr.close() + finally: + lockmod.release(tr, lock, wlock) diff --git a/tests/test-fbamend-hide.t b/tests/test-fbamend-hide.t new file mode 100644 --- /dev/null +++ b/tests/test-fbamend-hide.t @@ -0,0 +1,62 @@ + $ cat >> $HGRCPATH << EOF + > [extensions] + > fbamend=$TESTDIR/../hgext3rd/fbamend + > drawdag=$RUNTESTDIR/drawdag.py + > [experimental] + > evolution = createmarkers, allowunstable + > EOF + +Create repo + $ hg init + $ hg debugdrawdag <<'EOS' + > E + > | + > C D + > |/ + > B + > | + > A + > EOS + $ rm .hg/localtags + + $ hg book -r 2 cat + $ hg book -r 1 dog + $ hg update 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ hg log -G -T '{rev} {desc} {bookmarks}\n' + o 4 E + | + | o 3 D + | | + o | 2 C cat + |/ + o 1 B dog + | + @ 0 A + + +Hide a single commit + $ hg hide 3 + 1 changesets hidden + $ hg log -G -T '{rev} {desc} {bookmarks}\n' + o 4 E + | + o 2 C cat + | + o 1 B dog + | + @ 0 A + + +Hide multiple commits with bookmarks on them, hide wc parent + $ hg update 1 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg hide . + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + working directory now at 426bada5c675 + 3 changesets hidden + 2 bookmarks removed + $ hg log -G -T '{rev} {desc} {bookmarks}\n' + @ 0 A +