From 23fe5a77806f715c863fc70ee3e94e0372c2b149 Mon Sep 17 00:00:00 2001 From: Mark Thomas Date: Wed, 11 Dec 2019 03:47:48 -0800 Subject: [PATCH] reset: add visibility tracking support Summary: The `reset` extension does its own obsmarker creation, rather than going through `scmutil.cleanupnodes`. This means it doesn't support new-style visibility tracking. Fix this by making it use `scmutil.cleanupnodes`. This isn't completely straightforward: * The revset it uses to work out what to prune might accidentally include public commits (e.g. when you reset to a different public branch). Make sure these are filtered. * The tests originally had strip and obsmarker based tests. The strip tests, when converted to obsmarkers and using `scmutil.cleanupnodes` stop working because they strip and revive the same commit over and over, which is an edge case that obsmarkers can't handle well. Fix this by restoring the strip tests as strip tests. A separate test handles the new-style visibility. * Reset's behaviour is still a bit wonky. If an ancestor of the source commit has other (non-bookmarked) descendants, then reset will try to prune those commits. New-style visibility will ignore this, and this is tested in the new test. Reviewed By: farnz Differential Revision: D18912817 fbshipit-source-id: cc115333407cf67d339c24fcd0807ddedce2660d --- eden/scm/edenscm/hgext/reset.py | 37 ++++------------ eden/scm/tests/test-fb-hgext-reset-t.py | 57 +++++++++++++++++++------ eden/scm/tests/test-visibility-reset.t | 48 +++++++++++++++++++++ 3 files changed, 102 insertions(+), 40 deletions(-) create mode 100644 eden/scm/tests/test-visibility-reset.t diff --git a/eden/scm/edenscm/hgext/reset.py b/eden/scm/edenscm/hgext/reset.py index da6eecfb68..f89a3107c9 100644 --- a/eden/scm/edenscm/hgext/reset.py +++ b/eden/scm/edenscm/hgext/reset.py @@ -25,7 +25,7 @@ from edenscm.mercurial import ( scmutil, visibility, ) -from edenscm.mercurial.i18n import _ +from edenscm.mercurial.i18n import _, _n from edenscm.mercurial.node import hex @@ -34,18 +34,6 @@ command = registrar.command(cmdtable) testedwith = "ships-with-fb-hgext" -def _isobsstoreenabled(repo): - return obsolete.isenabled(repo, obsolete.createmarkersopt) - - -def _isahash(rev): - try: - binascii.unhexlify(rev) - return True - except TypeError: - return False - - @command( "reset", [ @@ -235,18 +223,11 @@ def _deleteunreachable(repo, ctx): keepheads += " + remotenames()" except KeyError: pass - hiderevs = repo.revs("::%s - ::(%r)", ctx.rev(), keepheads) - if hiderevs: - lock = None - try: - lock = repo.lock() - if _isobsstoreenabled(repo): - markers = [] - for rev in hiderevs: - markers.append((repo[rev], ())) - obsolete.createmarkers(repo, markers) - repo.ui.status(_("%d changesets pruned\n") % len(hiderevs)) - else: - repair.strip(repo.ui, repo, [repo.changelog.node(r) for r in hiderevs]) - finally: - lockmod.release(lock) + hidenodes = list(repo.nodes("(draft() & ::%s) - ::(%r)", ctx.rev(), keepheads)) + if hidenodes: + with repo.lock(): + scmutil.cleanupnodes(repo, hidenodes, "reset") + repo.ui.status( + _n("%d changeset hidden\n", "%d changesets hidden\n", len(hidenodes)) + % len(hidenodes) + ) diff --git a/eden/scm/tests/test-fb-hgext-reset-t.py b/eden/scm/tests/test-fb-hgext-reset-t.py index b0af54069b..bf0386347c 100644 --- a/eden/scm/tests/test-fb-hgext-reset-t.py +++ b/eden/scm/tests/test-fb-hgext-reset-t.py @@ -12,6 +12,8 @@ from testutil.dott import feature, sh, testtmp # noqa: F401 sh % "cat" << r""" [extensions] reset= +[experimental] +evolution= """ >> "$HGRCPATH" sh % "hg init repo" @@ -29,7 +31,9 @@ sh % "hg log -G -T '{node|short} {bookmarks}\\n'" == r""" @ 66ee28d0328c foo | o b292c1e3311f""" -sh % "hg reset '.^'" == "1 changesets pruned" +sh % "hg reset '.^'" == r""" + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/66ee28d0328c-b6ee89e7-reset.hg + 1 changeset hidden""" sh % "hg log -G -T '{node|short} {bookmarks}\\n'" == "@ b292c1e3311f foo" sh % "hg diff" == r""" diff -r b292c1e3311f x @@ -42,14 +46,23 @@ sh % "hg diff" == r""" # Clean reset should overwrite all changes sh % "hg commit -qAm y" -sh % "hg reset --clean '.^'" == "1 changesets pruned" + +sh % "hg reset --clean '.^'" == r""" + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/66ee28d0328c-b6ee89e7-reset.hg + 1 changeset hidden""" sh % "hg diff" # Reset should recover from backup bundles (with correct phase) sh % "hg log -G -T '{node|short} {bookmarks}\\n'" == "@ b292c1e3311f foo" sh % "hg phase -p b292c1e3311f" -sh % "hg reset --clean 66ee28d0328c" +sh % "hg reset --clean 66ee28d0328c" == r""" + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + new changesets 66ee28d0328c""" sh % "hg log -G -T '{node|short} {bookmarks} {phase}\\n'" == r""" @ 66ee28d0328c foo draft | @@ -99,19 +112,35 @@ sh % "hg up tip" == r""" 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (leaving bookmark foo)""" sh % "hg book -d foo" -sh % "hg reset '.^'" == "1 changesets pruned" +sh % "hg reset '.^'" == r""" + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/66ee28d0328c-b6ee89e7-reset.hg + 1 changeset hidden""" sh % "hg book foo" # Reset to bookmark with - in the name -sh % "hg reset 66ee28d0328c" +sh % "hg reset 66ee28d0328c" == r""" + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + new changesets 66ee28d0328c""" sh % "hg book foo-bar -r '.^'" -sh % "hg reset foo-bar" == "1 changesets pruned" +sh % "hg reset foo-bar" == r""" + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/66ee28d0328c-b6ee89e7-reset.hg + 1 changeset hidden""" sh % "hg book -d foo-bar" # Verify file status after reset -sh % "hg reset -C 66ee28d0328c" +sh % "hg reset -C 66ee28d0328c" == r""" + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + new changesets 66ee28d0328c""" sh % "touch toberemoved" sh % "hg commit -qAm 'add file for removal'" sh % "echo z" >> "x" @@ -119,12 +148,16 @@ sh % "touch tobeadded" sh % "hg add tobeadded" sh % "hg rm toberemoved" sh % "hg commit -m 'to be reset'" -sh % "hg reset '.^'" == "1 changesets pruned" +sh % "hg reset '.^'" == r""" + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d36bf00ac47e-375e6009-reset.hg + 1 changeset hidden""" sh % "hg status" == r""" M x ! toberemoved ? tobeadded""" -sh % "hg reset -C 66ee28d0328c" == "1 changesets pruned" +sh % "hg reset -C 66ee28d0328c" == r""" + saved backup bundle to $TESTTMP/repo/.hg/strip-backup/34fb347b2aae-c2a02721-reset.hg + 1 changeset hidden""" # Reset + Obsolete tests @@ -146,7 +179,7 @@ sh % "hg log -G -T '{node|short} {bookmarks}\\n'" == r""" # Reset prunes commits -sh % "hg reset -C '66ee28d0328c^'" == "2 changesets pruned" +sh % "hg reset -C '66ee28d0328c^'" == "2 changesets hidden" sh % "hg log -r 66ee28d0328c" == r""" abort: hidden revision '66ee28d0328c'! (use --hidden to access hidden revisions) @@ -161,9 +194,9 @@ sh % "hg log -G -T '{node|short} {bookmarks}\\n'" == r""" o b292c1e3311f""" # Reset to the commit your on is a no-op sh % "hg status" -sh % "hg log -r . -T '{rev}\\n'" == "4" +sh % "hg log -r . -T '{rev}\\n'" == "2" sh % "hg reset ." -sh % "hg log -r . -T '{rev}\\n'" == "4" +sh % "hg log -r . -T '{rev}\\n'" == "2" sh % "hg debugdirstate" == r""" n 644 0 * a (glob) n 644 0 * tobeadded (glob) diff --git a/eden/scm/tests/test-visibility-reset.t b/eden/scm/tests/test-visibility-reset.t new file mode 100644 index 0000000000..32dcb9d229 --- /dev/null +++ b/eden/scm/tests/test-visibility-reset.t @@ -0,0 +1,48 @@ +#chg-compatible + + $ enable amend rebase reset + $ setconfig experimental.evolution= + $ setconfig visibility.enabled=true + $ setconfig mutation.record=true mutation.enabled=true mutation.date="0 0" + + $ newrepo + $ drawdag << EOS + > E F + > |/ + > C D + > |/ + > B + > | + > A + > EOS + $ hg up -q $E + $ hg bookmark test-bookmark + $ tglogm + o 5: ee481a2a1e69 'F' + | + | @ 4: 78d2dca436b2 'E' test-bookmark + |/ + | o 3: be0ef73c17ad 'D' + | | + o | 2: 26805aba1e60 'C' + |/ + o 1: 112478962961 'B' + | + o 0: 426bada5c675 'A' + + $ hg reset -C $D + 2 changesets hidden + +Note that reset tried to hide 'C', but this was ignored because of 'F'. + + $ tglogm + o 5: ee481a2a1e69 'F' + | + | @ 3: be0ef73c17ad 'D' test-bookmark + | | + o | 2: 26805aba1e60 'C' + |/ + o 1: 112478962961 'B' + | + o 0: 426bada5c675 'A' +