visibility: make enabling or disabling of tracking a command

Summary:
Rather than implicitly upgrading or downgrading a repo based on the
`visibility.tracking` config option, add a new `hg debugvisibility` command to
do this explicitly.

Reviewed By: DurhamG

Differential Revision: D14871231

fbshipit-source-id: 73f4648408b3eca9ac12bd77e54d2d37ee342069
This commit is contained in:
Mark Thomas 2019-04-11 02:40:06 -07:00 committed by Facebook Github Bot
parent fb42aba542
commit d803ebb3c7
11 changed files with 90 additions and 103 deletions

View File

@ -1,4 +1,4 @@
# debugmutation.py - command processing for debugmutation* commands
# debugmutation.py - command processing for debug commands for mutation and visbility
#
# Copyright 2019 Facebook, Inc.
#
@ -7,7 +7,7 @@
from __future__ import absolute_import
from .. import mutation, node as nodemod, pycompat, registrar, scmutil, util
from .. import mutation, node as nodemod, pycompat, registrar, scmutil, util, visibility
from ..i18n import _
@ -183,3 +183,25 @@ def debugmutationfromobsmarkers(ui, repo, **opts):
with repo.lock():
count = mutation.recordentries(repo, entries, skipexisting=False)
repo.ui.write(_("wrote %s entries\n") % count)
@command("debugvisibility", [], subonly=True)
def debugvisibility(ui, repo):
"""control visibility tracking"""
subcmd = debugvisibility.subcommand()
@subcmd("start", [])
def debugvisibilitystart(ui, repo):
"""start tracking commit visibility explicitly"""
visibility.starttracking(repo)
return 0
@subcmd("stop", [])
def debugvisibilitystop(ui, repo):
"""stop tracking commit visibility explicitly"""
visibility.stoptracking(repo)
return 0

View File

@ -506,7 +506,7 @@ coreconfigitem("ui", "enableincomingoutgoing", default=True)
coreconfigitem("unsafe", "filtersuspectsymlink", default=True)
coreconfigitem("unsafe", "wvfsauditorcache", default=False)
coreconfigitem("verify", "skipflags", default=None)
coreconfigitem("visibility", "tracking", default="auto")
coreconfigitem("visibility", "enabled", default=False)
coreconfigitem("web", "allowbz2", default=False)
coreconfigitem("web", "allowgz", default=False)
coreconfigitem("web", "allow-pull", alias=[("web", "allowpull")], default=True)

View File

@ -2325,29 +2325,15 @@ User interface controls.
``visibility``
--------------
Controls how Mercurial determines commit visibility.
Controls how Mercurial determines commit visibility. Mercurial
can optionally track which commits are visible explicitly, or it
can determine them implicitly from obsolescence markers.
``forceobsolete``
Force the use of obsolescence information for visibility, even if
the ``visibleheads`` requirement is set in the repo.
``tracking``
Whether to track commit visibility. (default: auto)
``off``
Use obsolescence markers to determine visibility. Only commits
that have not been obsoleted are visible.
``on``
Explicitly track visibility of commits using a set of visible
heads. Only commits that are ancestors of the visible heads are
visible. This adds the ``visibleheads`` requirement to the
repository store, so it cannot be used by versions of Mercurial
that do not track visibleheads.
``auto``
Use visible heads if the repository store has the ``visibleheads``
requirement, otherwise use ``obsolescence``.
``enabled``
Set to true to use explicit tracking of commit visibility if
the ``visibleheads`` requirement is set in the repo. If False,
or if the ``visibleheads`` requirement is not set in the repo,
then obsolescence markers will be used to determine visibility.
``web``

View File

@ -774,7 +774,7 @@ class localrepository(object):
@storecache("visibleheads")
def _visibleheads(self):
return visibility.makevisibleheads(self.ui, self)
return visibility.visibleheads(self.ui, self)
@storecache("obsstore")
def obsstore(self):
@ -2656,4 +2656,9 @@ def newreporequirements(repo):
def newrepostorerequirements(repo):
return set()
ui = repo.ui
requirements = set()
if ui.configbool("visibility", "enabled"):
requirements.add("visibleheads")
return requirements

View File

@ -9,16 +9,32 @@ from __future__ import absolute_import
import errno
from edenscm.mercurial import error, node, util
from edenscm.mercurial.i18n import _
from edenscm.mercurial import error, node
def _convertfromobsolete(repo):
"""convert obsolete markers into a set of visible heads"""
with repo.ui.configoverride(
{("mutation", "enabled"): False}, "convertfromobsolete"
{("mutation", "enabled"): False, ("visibility", "enabled"): False},
"convertfromobsolete",
):
return set(repo.unfiltered().nodes("heads((not public()) - obsolete())"))
return set(repo.unfiltered().nodes("heads((not public()) - hidden())"))
def starttracking(repo):
if "visibleheads" not in repo.storerequirements:
with repo.lock():
repo.storerequirements.add("visibleheads")
repo._writestorerequirements()
def stoptracking(repo):
if "visibleheads" in repo.storerequirements:
with repo.lock():
repo.storerequirements.discard("visibleheads")
repo._writestorerequirements()
if repo.svfs.lexists("visibleheads"):
repo.svfs.tryunlink("visibleheads")
# Supported file format version.
@ -145,71 +161,42 @@ class visibleheads(object):
return hidden
def makevisibleheads(ui, repo):
tracking = ui.config("visibility", "tracking", "auto")
if tracking != "auto":
trackingbool = util.parsebool(tracking)
if trackingbool is None:
raise error.ConfigError(
_("visibility.tracking not valid ('%s' is not 'auto' or boolean)")
% tracking
)
if trackingbool:
if "visibleheads" not in repo.storerequirements:
repo.storerequirements.add("visibleheads")
with repo.lock():
repo._writestorerequirements()
else:
if "visibleheads" in repo.storerequirements:
repo.storerequirements.remove("visibleheads")
with repo.lock():
repo._writestorerequirements()
if repo.svfs.lexists("visibleheads"):
repo.svfs.tryunlink("visibleheads")
if "visibleheads" in repo.storerequirements:
return visibleheads(ui, repo)
else:
return None
def add(repo, newnodes):
vh = repo._visibleheads
if vh is not None:
if tracking(repo):
with repo.lock(), repo.transaction("update-visibility") as tr:
vh.add(repo, newnodes, tr)
repo._visibleheads.add(repo, newnodes, tr)
def remove(repo, oldnodes):
vh = repo._visibleheads
if vh is not None:
if tracking(repo):
with repo.lock(), repo.transaction("update-visibility") as tr:
vh.remove(repo, oldnodes, tr)
repo._visibleheads.remove(repo, oldnodes, tr)
def phaseadjust(repo, tr, newdraft=None, newpublic=None):
vh = repo._visibleheads
if vh is not None:
vh.phaseadjust(repo, tr, newdraft, newpublic)
if tracking(repo):
repo._visibleheads.phaseadjust(repo, tr, newdraft, newpublic)
def heads(repo):
vh = repo._visibleheads
if vh is not None:
return vh.heads
return None
if tracking(repo):
return repo._visibleheads.heads
def invisiblerevs(repo):
"""Returns the invisible mutable revs in this repo"""
vh = repo._visibleheads
if vh is not None:
return vh.invisiblerevs(repo)
return None
if tracking(repo):
return repo._visibleheads.invisiblerevs(repo)
def tracking(repo):
return repo._visibleheads is not None
return "visibleheads" in repo.storerequirements
def enabled(repo):
return tracking(repo) and not repo.ui.configbool("visibility", "forceobsolete")
# TODO(mbthomas): support bundlerepo
from . import bundlerepo # avoid import cycle
if isinstance(repo, bundlerepo.bundlerepository):
return False
return tracking(repo) and repo.ui.configbool("visibility", "enabled")

View File

@ -136,6 +136,7 @@ Show debug commands if there are no other candidates
debugtreestate
debugupdatecaches
debugupgraderepo
debugvisibility
debugwalk
debugwireargs
@ -331,6 +332,7 @@ Show all commands + options
debugtreestate:
debugupdatecaches:
debugupgraderepo: optimize, run
debugvisibility:
debugwalk: include, exclude
debugwireargs: three, four, five, ssh, remotecmd, insecure
files: rev, print0, include, exclude, template

View File

@ -1047,6 +1047,8 @@ Test list of internal help commands
warm all known caches in the repository
debugupgraderepo
upgrade a repository to use different features
debugvisibility
control visibility tracking
debugwalk show how files match on given patterns
debugwireargs
(no help text available)

View File

@ -1,14 +1,7 @@
$ enable amend rebase histedit fbhistedit
We need obsmarkers for now, to allow unstable commits
$ enable obsstore
$ cat >> $HGRCPATH <<EOF
> [mutation]
> record=true
> enabled=true
> date=0 0
> EOF
$ setconfig experimental.evolution=
$ setconfig visibility.enabled=true
$ setconfig mutation.record=true mutation.enabled=true mutation.date="0 0"
$ . "$TESTDIR/library.sh"
$ . "$TESTDIR/infinitepush/library.sh"

View File

@ -1,16 +1,12 @@
#testcases nostackpush stackpush
$ enable pushrebase amend
$ setconfig experimental.evolution=
$ setconfig visibility.enabled=true
$ setconfig mutation.record=true mutation.enabled=true mutation.date="0 0"
$ cat >> $HGRCPATH <<EOF
> [ui]
> ssh = python "$RUNTESTDIR/dummyssh"
> [mutation]
> record=true
> enabled=true
> date=0 0
> [visibility]
> tracking=on
> [templatealias]
> sl_mutation_names = dict(amend="Amended as", rebase="Rebased to", split="Split into", fold="Folded into", histedit="Histedited to", rewrite="Rewritten into", land="Landed as", pushrebase="Pushed as")
> sl_mutations = "{join(mutations % '({get(sl_mutation_names, operation, "Rewritten using {operation} into")} {join(successors % "{node|short}", ", ")})', ' ')}"

View File

@ -1,16 +1,10 @@
$ enable amend rebase histedit fbhistedit phabdiff
$ setconfig ui.ssh="$PYTHON \"$TESTDIR/dummyssh\""
$ setconfig ui.ssh="$PYTHON \"$TESTDIR/dummyssh\"" ui.interactive=true
$ setconfig experimental.evolution=
$ setconfig visibility.enabled=true
$ setconfig mutation.record=true mutation.enabled=true mutation.date="0 0"
$ cat >> $HGRCPATH <<EOF
> [mutation]
> record=true
> enabled=true
> date=0 0
> [visibility]
> tracking=on
> [ui]
> interactive = true
> [templatealias]
> sl_mutation_names = dict(amend="Amended as", rebase="Rebased to", split="Split into", fold="Folded into", histedit="Histedited to", rewrite="Rewritten into", land="Landed as")
> sl_mutations = "{join(mutations % '({get(sl_mutation_names, operation, "Rewritten using {operation} into")} {join(successors % "{node|short}", ", ")})', ' ')}"

View File

@ -1,6 +1,6 @@
$ enable amend rebase undo
$ setconfig experimental.evolution=
$ setconfig visibility.tracking=on
$ setconfig visibility.enabled=true
$ setconfig mutation.record=true mutation.enabled=true mutation.date="0 0"
$ setconfig hint.ack=undo
$ cat >> $HGRCPATH <<EOF