mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 08:47:12 +03:00
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:
parent
99a8e89d15
commit
76979321e3
@ -47,6 +47,7 @@ from mercurial import (
|
|||||||
pycompat,
|
pycompat,
|
||||||
registrar,
|
registrar,
|
||||||
scmutil,
|
scmutil,
|
||||||
|
treestate,
|
||||||
txnutil,
|
txnutil,
|
||||||
util,
|
util,
|
||||||
)
|
)
|
||||||
@ -646,6 +647,13 @@ def migrate(ui, repo, version):
|
|||||||
# to treedirstate
|
# to treedirstate
|
||||||
newmap = treedirstatemap(ui, vfs, repo.root, importmap=repo.dirstate._map)
|
newmap = treedirstatemap(ui, vfs, repo.root, importmap=repo.dirstate._map)
|
||||||
repo.requirements.add("treedirstate")
|
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:
|
elif wanted == 0 and current == 1:
|
||||||
# treedirstate -> flat dirstate
|
# treedirstate -> flat dirstate
|
||||||
repo.dirstate._map.writeflat()
|
repo.dirstate._map.writeflat()
|
||||||
@ -873,12 +881,24 @@ cmdtable = {}
|
|||||||
command = registrar.command(cmdtable)
|
command = registrar.command(cmdtable)
|
||||||
|
|
||||||
|
|
||||||
@command("debugtreedirstate", [], "hg debugtreedirstate [on|off|status|repack|cleanup]")
|
@command(
|
||||||
def debugtreedirstate(ui, repo, cmd, **opts):
|
"debugtreedirstate|debugtreestate",
|
||||||
"""manage treedirstate"""
|
[],
|
||||||
if cmd == "on":
|
"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)
|
migrate(ui, repo, 1)
|
||||||
elif cmd == "off":
|
elif cmd in ["v0", "off"]:
|
||||||
migrate(ui, repo, 0)
|
migrate(ui, repo, 0)
|
||||||
cleanup(ui, repo, debug=ui.debug)
|
cleanup(ui, repo, debug=ui.debug)
|
||||||
elif cmd == "repack":
|
elif cmd == "repack":
|
||||||
@ -887,15 +907,18 @@ def debugtreedirstate(ui, repo, cmd, **opts):
|
|||||||
elif cmd == "cleanup":
|
elif cmd == "cleanup":
|
||||||
cleanup(ui, repo, debug=ui.debug)
|
cleanup(ui, repo, debug=ui.debug)
|
||||||
elif cmd == "status":
|
elif cmd == "status":
|
||||||
|
dmap = repo.dirstate._map
|
||||||
if istreedirstate(repo):
|
if istreedirstate(repo):
|
||||||
ui.status(
|
ui.status(
|
||||||
_(
|
_("dirstate v1 (using dirstate.tree.%s, %s files tracked)\n")
|
||||||
"treedirstate enabled "
|
% (dmap._treeid, len(dmap))
|
||||||
+ "(using dirstate.tree.%s, %s files tracked)"
|
)
|
||||||
)
|
elif "treestate" in repo.requirements:
|
||||||
% (repo.dirstate._map._treeid, len(repo.dirstate._map))
|
ui.status(
|
||||||
|
_("dirstate v2 (using treestate/%s, offset %s, %s files tracked)\n")
|
||||||
|
% (dmap._filename, dmap._rootid, len(dmap))
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
ui.status(_("treedirstate not enabled"))
|
ui.status(_("dirstate v0 (flat dirstate, %s files tracked)\n") % len(dmap))
|
||||||
else:
|
else:
|
||||||
raise error.Abort("unrecognised command: %s" % cmd)
|
raise error.Abort("unrecognised command: %s" % cmd)
|
||||||
|
@ -69,14 +69,24 @@ class treestatemap(object):
|
|||||||
and an offset.
|
and an offset.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ui, vfs, root):
|
def __init__(self, ui, vfs, root, importdirstate=None):
|
||||||
self._ui = ui
|
self._ui = ui
|
||||||
self._vfs = vfs
|
self._vfs = vfs
|
||||||
self._root = root
|
self._root = root
|
||||||
# The original dirstate lazily reads content for performance.
|
if importdirstate:
|
||||||
# But our dirstate map is lazy anyway. So "_read" during init
|
# Import from an old dirstate
|
||||||
# should be fine.
|
self.clear()
|
||||||
self._read()
|
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
|
@property
|
||||||
def copymap(self):
|
def copymap(self):
|
||||||
|
86
tests/test-dirstate-migrate.t
Normal file
86
tests/test-dirstate-migrate.t
Normal 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)
|
Loading…
Reference in New Issue
Block a user