treedirstate: make debugtreedirstate support treestate migration

Summary: This allows us to dogfood the new treestate.

Reviewed By: markbt

Differential Revision: D7912559

fbshipit-source-id: bfb30cd9989460b0eae859aeed402bd92776ab0a
This commit is contained in:
Jun Wu 2018-06-13 17:49:36 -07:00 committed by Facebook Github Bot
parent 99a8e89d15
commit 76979321e3
3 changed files with 135 additions and 16 deletions

View File

@ -47,6 +47,7 @@ from mercurial import (
pycompat,
registrar,
scmutil,
treestate,
txnutil,
util,
)
@ -646,6 +647,13 @@ def migrate(ui, repo, version):
# to treedirstate
newmap = treedirstatemap(ui, vfs, repo.root, importmap=repo.dirstate._map)
repo.requirements.add("treedirstate")
elif wanted == 2 and current in [0, 1]:
# to treestate
vfs.makedirs("treestate")
newmap = treestate.treestatemap(
ui, vfs, repo.root, importdirstate=repo.dirstate
)
repo.requirements.add("treestate")
elif wanted == 0 and current == 1:
# treedirstate -> flat dirstate
repo.dirstate._map.writeflat()
@ -873,12 +881,24 @@ cmdtable = {}
command = registrar.command(cmdtable)
@command("debugtreedirstate", [], "hg debugtreedirstate [on|off|status|repack|cleanup]")
def debugtreedirstate(ui, repo, cmd, **opts):
"""manage treedirstate"""
if cmd == "on":
@command(
"debugtreedirstate|debugtreestate",
[],
"hg debugtreedirstate [on|off|status|repack|cleanup|v0|v1|v2]",
)
def debugtreedirstate(ui, repo, cmd="status", **opts):
"""manage treedirstate
v0/off: migrate to flat dirstate
v1: migrate to treedirstate
v2: migrate to treestate
on: migrate to the latest version (v2)
"""
if cmd in ["v2", "on"]:
migrate(ui, repo, 2)
elif cmd == "v1":
migrate(ui, repo, 1)
elif cmd == "off":
elif cmd in ["v0", "off"]:
migrate(ui, repo, 0)
cleanup(ui, repo, debug=ui.debug)
elif cmd == "repack":
@ -887,15 +907,18 @@ def debugtreedirstate(ui, repo, cmd, **opts):
elif cmd == "cleanup":
cleanup(ui, repo, debug=ui.debug)
elif cmd == "status":
dmap = repo.dirstate._map
if istreedirstate(repo):
ui.status(
_(
"treedirstate enabled "
+ "(using dirstate.tree.%s, %s files tracked)"
)
% (repo.dirstate._map._treeid, len(repo.dirstate._map))
_("dirstate v1 (using dirstate.tree.%s, %s files tracked)\n")
% (dmap._treeid, len(dmap))
)
elif "treestate" in repo.requirements:
ui.status(
_("dirstate v2 (using treestate/%s, offset %s, %s files tracked)\n")
% (dmap._filename, dmap._rootid, len(dmap))
)
else:
ui.status(_("treedirstate not enabled"))
ui.status(_("dirstate v0 (flat dirstate, %s files tracked)\n") % len(dmap))
else:
raise error.Abort("unrecognised command: %s" % cmd)

View File

@ -69,14 +69,24 @@ class treestatemap(object):
and an offset.
"""
def __init__(self, ui, vfs, root):
def __init__(self, ui, vfs, root, importdirstate=None):
self._ui = ui
self._vfs = vfs
self._root = root
# The original dirstate lazily reads content for performance.
# But our dirstate map is lazy anyway. So "_read" during init
# should be fine.
self._read()
if importdirstate:
# Import from an old dirstate
self.clear()
self._parents = importdirstate.parents()
self._tree.importmap(importdirstate._map)
# Import copymap
copymap = importdirstate.copies()
for dest, src in copymap.iteritems():
self.copy(src, dest)
else:
# The original dirstate lazily reads content for performance.
# But our dirstate map is lazy anyway. So "_read" during init
# should be fine.
self._read()
@property
def copymap(self):

View File

@ -0,0 +1,86 @@
$ for src in 0 1 2; do
> for dst in 0 1 2; do
> [ $src = $dst ] && continue
> echo ==== Migrating dirstate v$src to v$dst ====
> cd $TESTTMP
> setconfig format.dirstate=$src
> newrepo
> touch normal modified removed deleted
> hg ci -A . -q -m init
> hg rm removed
> rm deleted
> touch untracked
> echo 1 > modified
> hg status
> hg debugtreestate status
> hg debugtreestate v$dst
> hg status
> hg debugtreestate status
> done
> done
==== Migrating dirstate v0 to v1 ====
M modified
R removed
! deleted
? untracked
dirstate v0 (flat dirstate, 4 files tracked)
M modified
R removed
! deleted
? untracked
dirstate v1 (using dirstate.tree.*, 4 files tracked) (glob)
==== Migrating dirstate v0 to v2 ====
M modified
R removed
! deleted
? untracked
dirstate v0 (flat dirstate, 4 files tracked)
M modified
R removed
! deleted
? untracked
dirstate v2 (using treestate*, offset *, 4 files tracked) (glob)
==== Migrating dirstate v1 to v0 ====
M modified
R removed
! deleted
? untracked
dirstate v1 (using dirstate.tree*, 4 files tracked) (glob)
M modified
R removed
! deleted
? untracked
dirstate v0 (flat dirstate, 4 files tracked)
==== Migrating dirstate v1 to v2 ====
M modified
R removed
! deleted
? untracked
dirstate v1 (using dirstate.tree*, 4 files tracked) (glob)
M modified
R removed
! deleted
? untracked
dirstate v2 (using treestate* offset *, 4 files tracked) (glob)
==== Migrating dirstate v2 to v0 ====
M modified
R removed
! deleted
? untracked
dirstate v2 (using treestate*, offset *, 4 files tracked) (glob)
M modified
R removed
! deleted
? untracked
dirstate v0 (flat dirstate, 4 files tracked)
==== Migrating dirstate v2 to v1 ====
M modified
R removed
! deleted
? untracked
dirstate v2 (using treestate*, offset *, 4 files tracked) (glob)
M modified
R removed
! deleted
? untracked
dirstate v1 (using dirstate.tree*, 4 files tracked) (glob)