mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 06:47:41 +03:00
treestate: make treestate a hard requirement
Summary: We want to delete all the non-treestate dirstate implementations. Let's start throwing an exception if treestate is not enabled. We temporarily have a bypass in case we break an important usecase in the process. This also sets the standard new repo to be created in treestate mode, but adding treestate to newreporequirements. Reviewed By: quark-zju Differential Revision: D19204621 fbshipit-source-id: 61c0c69ce6e559615ef570d2343bea78c1b5d5ee
This commit is contained in:
parent
a7aeb5d7a6
commit
898149fa37
@ -770,7 +770,6 @@ def perfdirs(ui, repo, **opts):
|
||||
|
||||
def d():
|
||||
dirstate.hasdir("a")
|
||||
del dirstate._map._dirs
|
||||
|
||||
timer(d)
|
||||
fm.end()
|
||||
@ -796,7 +795,6 @@ def perfdirstatedirs(ui, repo, **opts):
|
||||
|
||||
def d():
|
||||
repo.dirstate.hasdir("a")
|
||||
del repo.dirstate._map._dirs
|
||||
|
||||
timer(d)
|
||||
fm.end()
|
||||
@ -810,7 +808,7 @@ def perfdirstatefoldmap(ui, repo, **opts):
|
||||
|
||||
def d():
|
||||
dirstate._map.filefoldmap.get("a")
|
||||
del dirstate._map.filefoldmap
|
||||
dirstate._map.filefoldmap.clear()
|
||||
|
||||
timer(d)
|
||||
fm.end()
|
||||
@ -824,8 +822,7 @@ def perfdirfoldmap(ui, repo, **opts):
|
||||
|
||||
def d():
|
||||
dirstate._map.dirfoldmap.get("a")
|
||||
del dirstate._map.dirfoldmap
|
||||
del dirstate._map._dirs
|
||||
dirstate._map.dirfoldmap.clear()
|
||||
|
||||
timer(d)
|
||||
fm.end()
|
||||
|
@ -903,6 +903,12 @@ class localrepository(object):
|
||||
return self._eden_dirstate
|
||||
|
||||
istreestate = "treestate" in self.requirements
|
||||
# Block nontreestate repos entirely. Add a config to bypass in case we
|
||||
# break something.
|
||||
if not istreestate and self.ui.configbool("treestate", "required", True):
|
||||
raise errormod.RequirementError(
|
||||
"legacy dirstate implementations are no longer supported"
|
||||
)
|
||||
istreedirstate = "treedirstate" in self.requirements
|
||||
|
||||
return dirstate.dirstate(
|
||||
@ -2805,11 +2811,8 @@ def newreporequirements(repo):
|
||||
% compengine,
|
||||
hint=_('run "hg debuginstall" to list available ' "compression engines"),
|
||||
)
|
||||
dirstateversion = ui.configint("format", "dirstate")
|
||||
if dirstateversion == 1:
|
||||
requirements.add("treedirstate")
|
||||
elif dirstateversion == 2:
|
||||
requirements.add("treestate")
|
||||
|
||||
requirements.add("treestate")
|
||||
|
||||
# zlib is the historical default and doesn't need an explicit requirement.
|
||||
if compengine != "zlib":
|
||||
|
@ -127,6 +127,7 @@ New errors are not allowed. Warnings are strongly discouraged.
|
||||
undocumented: ssl.signal_status (bool) [True]
|
||||
undocumented: ssl.timeout (int) [10]
|
||||
undocumented: treemanifest.verifyautocreate (bool)
|
||||
undocumented: treestate.required (bool) [True]
|
||||
undocumented: ui.editor.chunkselector (str)
|
||||
undocumented: ui.hyperlink (bool)
|
||||
undocumented: workingcopy.enablerustwalker (bool)
|
||||
|
@ -558,13 +558,13 @@ Test clone from the repository in (emulated) revlog format 0 (issue4203):
|
||||
$ mkdir -p src/.hg
|
||||
$ echo foo > src/foo
|
||||
$ hg -R src add src/foo
|
||||
abort: repo is corrupted: 00changelog.i
|
||||
abort: legacy dirstate implementations are no longer supported!
|
||||
[255]
|
||||
$ hg -R src commit -m '#0'
|
||||
abort: repo is corrupted: 00changelog.i
|
||||
abort: legacy dirstate implementations are no longer supported!
|
||||
[255]
|
||||
$ hg -R src log -q
|
||||
abort: repo is corrupted: 00changelog.i
|
||||
abort: legacy dirstate implementations are no longer supported!
|
||||
[255]
|
||||
$ hg clone -U -q src dst
|
||||
abort: repo is corrupted: 00changelog.i
|
||||
|
@ -11,7 +11,6 @@ Set vars:
|
||||
Prepare repo:
|
||||
|
||||
$ hg init
|
||||
$ hg debugtreedirstate off
|
||||
|
||||
$ echo this is file a > a
|
||||
$ hg add a
|
||||
|
@ -1,92 +0,0 @@
|
||||
#chg-compatible
|
||||
|
||||
$ 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) (no-fsmonitor !)
|
||||
dirstate v2 (using treestate*, offset *, 5 files tracked) (glob) (fsmonitor !)
|
||||
==== 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) (no-fsmonitor !)
|
||||
dirstate v2 (using treestate*, offset *, 5 files tracked) (glob) (fsmonitor !)
|
||||
==== Migrating dirstate v2 to v0 ====
|
||||
M modified
|
||||
R removed
|
||||
! deleted
|
||||
? untracked
|
||||
dirstate v2 (using treestate*, offset *, 4 files tracked) (glob) (no-fsmonitor !)
|
||||
dirstate v2 (using treestate*, offset *, 5 files tracked) (glob) (fsmonitor !)
|
||||
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) (no-fsmonitor !)
|
||||
dirstate v2 (using treestate*, offset *, 5 files tracked) (glob) (fsmonitor !)
|
||||
M modified
|
||||
R removed
|
||||
! deleted
|
||||
? untracked
|
||||
dirstate v1 (using dirstate.tree*, 4 files tracked) (glob)
|
@ -1,22 +1,6 @@
|
||||
#chg-compatible
|
||||
|
||||
#chg-compatible
|
||||
|
||||
#chg-compatible
|
||||
|
||||
#testcases v0 v1 v2
|
||||
|
||||
#if v0
|
||||
$ setconfig format.dirstate=0
|
||||
#endif
|
||||
|
||||
#if v1
|
||||
$ setconfig format.dirstate=1
|
||||
#endif
|
||||
|
||||
#if v2
|
||||
$ setconfig format.dirstate=2
|
||||
#endif
|
||||
|
||||
------ Test dirstate._dirs refcounting
|
||||
|
||||
@ -63,21 +47,6 @@ Prepare test repo:
|
||||
adding a
|
||||
$ hg ci -m1
|
||||
|
||||
#if no-v2
|
||||
Set mtime of a into the future:
|
||||
|
||||
$ touch -t 202101011200 a
|
||||
|
||||
Status must not set a's entry to unset (issue1790):
|
||||
|
||||
$ hg status
|
||||
$ hg debugstate
|
||||
n 644 2 2021-01-01 12:00:00 a
|
||||
|
||||
Note: issue1790 is about thg compatibility. In this case, setting mtime to
|
||||
"unset" is also correct since "a" needs to be checked.
|
||||
#endif
|
||||
|
||||
Test modulo storage/comparison of absurd dates:
|
||||
|
||||
#if no-aix
|
||||
|
@ -1,19 +0,0 @@
|
||||
#require fsmonitor
|
||||
|
||||
$ setconfig fsmonitor.warn-fresh-instance=true
|
||||
$ newrepo
|
||||
|
||||
A warning is printed for the first use
|
||||
|
||||
$ hg status --debug
|
||||
warning: watchman has recently started (pid *) - operation will be slower than usual (glob)
|
||||
poststatusfixup decides to wait for wlock since watchman reported fresh instance
|
||||
|
||||
$ hg status --debug
|
||||
|
||||
Verify that we can fallback to walking
|
||||
- Migrate the dirstate to reset the clock
|
||||
$ hg debugtreestate v0
|
||||
$ hg debugtreestate on
|
||||
$ hg status --config fsmonitor.walk_on_invalidate=True --debug
|
||||
fsmonitor: fallback to core status, no clock
|
@ -16,7 +16,7 @@ sh % "hg add a"
|
||||
sh % "hg commit -m test"
|
||||
sh % "rm .hg/requires"
|
||||
sh % "hg tip" == r"""
|
||||
abort: index 00changelog.i is corrupted!
|
||||
abort: legacy dirstate implementations are no longer supported!
|
||||
[255]"""
|
||||
sh % "echo indoor-pool" > ".hg/requires"
|
||||
sh % "hg tip" == r"""
|
||||
|
@ -1,211 +0,0 @@
|
||||
#chg-compatible
|
||||
|
||||
$ setconfig extensions.treemanifest=!
|
||||
Setup
|
||||
|
||||
$ setconfig format.dirstate=1
|
||||
$ setconfig treestate.mingcage=0
|
||||
$ hg init repo
|
||||
$ cd repo
|
||||
$ echo base > base
|
||||
$ hg add base
|
||||
$ hg debugdirstate
|
||||
a 0 -1 unset base
|
||||
$ hg commit -m "base"
|
||||
$ hg debugdirstate
|
||||
n 644 5 * base (glob)
|
||||
|
||||
Create path-conflicting dirstates
|
||||
|
||||
$ hg up -q 0
|
||||
$ echo a > a
|
||||
$ hg add a
|
||||
$ hg commit -m a
|
||||
$ hg bookmark a
|
||||
$ hg up -q 0
|
||||
$ mkdir a
|
||||
$ echo a/a > a/a
|
||||
$ hg add a/a
|
||||
$ hg commit -m a/a
|
||||
$ hg bookmark a/a
|
||||
$ hg up -q a
|
||||
$ hg status
|
||||
$ hg rm a
|
||||
$ hg status
|
||||
R a
|
||||
$ hg merge --force a/a
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
(branch merge, don't forget to commit)
|
||||
$ hg status
|
||||
M a/a
|
||||
R a
|
||||
$ hg rm --force a/a
|
||||
$ hg status
|
||||
R a
|
||||
R a/a
|
||||
$ hg up -Cq 0
|
||||
|
||||
Attempt to create a path conflict in the manifest
|
||||
|
||||
$ echo b > b
|
||||
$ hg add b
|
||||
$ hg commit -m b
|
||||
$ rm b
|
||||
$ mkdir b
|
||||
$ echo b/b > b/b
|
||||
$ hg add b/b
|
||||
abort: file 'b' in dirstate clashes with 'b/b'
|
||||
[255]
|
||||
$ rm -rf b
|
||||
$ hg up -Cq 0
|
||||
|
||||
Test warning when creating files that might give a casefold collision
|
||||
|
||||
#if no-icasefs
|
||||
$ echo data > FiLeNaMe
|
||||
$ hg add FiLeNaMe
|
||||
$ echo data > FILENAME
|
||||
$ hg add FILENAME
|
||||
warning: possible case-folding collision for FILENAME
|
||||
$ rm -f FiLeNaMe FILENAME
|
||||
$ hg up -Cq 0
|
||||
#endif
|
||||
|
||||
Test dirfoldmap and filefoldmap on case insensitive filesystems
|
||||
|
||||
#if icasefs
|
||||
$ mkdir -p dirA/dirB/dirC
|
||||
$ echo file1 > dira/File1
|
||||
$ echo file2 > dira/dirb/FILE2
|
||||
$ echo file3 > dira/dirb/dirc/FiLe3
|
||||
$ echo file4 > dira/dirb/dirc/file4
|
||||
$ hg add DIRA
|
||||
adding dirA/File1
|
||||
adding dirA/dirB/FILE2
|
||||
adding dirA/dirB/dirC/FiLe3
|
||||
adding dirA/dirB/dirC/file4
|
||||
$ hg status
|
||||
A dirA/File1
|
||||
A dirA/dirB/FILE2
|
||||
A dirA/dirB/dirC/FiLe3
|
||||
A dirA/dirB/dirC/file4
|
||||
$ hg forget dira/DIRB
|
||||
removing dirA/dirB/FILE2
|
||||
removing dirA/dirB/dirC/FiLe3
|
||||
removing dirA/dirB/dirC/file4
|
||||
$ hg status
|
||||
A dirA/File1
|
||||
? dirA/dirB/FILE2
|
||||
? dirA/dirB/dirC/FiLe3
|
||||
? dirA/dirB/dirC/file4
|
||||
$ hg add dira/dirb/file2
|
||||
$ hg status
|
||||
A dirA/File1
|
||||
A dirA/dirB/FILE2
|
||||
? dirA/dirB/dirC/FiLe3
|
||||
? dirA/dirB/dirC/file4
|
||||
$ rm -rf dirA
|
||||
#endif
|
||||
|
||||
Test autorepack
|
||||
|
||||
$ ls .hg/dirstate.tree.*
|
||||
.hg/dirstate.tree.* (glob)
|
||||
$ echo data > file
|
||||
|
||||
After the first repack, the old trees are kept around by the transaction undo backups.
|
||||
$ hg add file --config treestate.minrepackthreshold=1 --config treestate.repackfactor=0 --debug | grep -v 'in use by'
|
||||
adding file
|
||||
auto-repacking treedirstate
|
||||
$ ls .hg/dirstate.tree.*
|
||||
.hg/dirstate.tree.* (glob)
|
||||
.hg/dirstate.tree.* (glob)
|
||||
|
||||
After the second repack, the old trees are still kept around.
|
||||
$ hg forget file --config treestate.minrepackthreshold=1 --config treestate.repackfactor=0 --debug | grep -v 'in use by'
|
||||
removing file
|
||||
auto-repacking treedirstate
|
||||
$ ls .hg/dirstate.tree.*
|
||||
.hg/dirstate.tree.* (glob)
|
||||
.hg/dirstate.tree.* (glob)
|
||||
.hg/dirstate.tree.* (glob)
|
||||
|
||||
On the third repack, the original tree is removed.
|
||||
$ hg add file --config treestate.minrepackthreshold=1 --config treestate.repackfactor=0 --debug | grep -v 'in use by'
|
||||
adding file
|
||||
auto-repacking treedirstate
|
||||
removing old unreferenced dirstate tree * (glob)
|
||||
$ ls .hg/dirstate.tree.*
|
||||
.hg/dirstate.tree.* (glob)
|
||||
.hg/dirstate.tree.* (glob)
|
||||
.hg/dirstate.tree.* (glob)
|
||||
|
||||
On the fourth repack, the second tree is removed.
|
||||
$ hg forget file --config treestate.minrepackthreshold=1 --config treestate.repackfactor=0 --debug | grep -v 'in use by'
|
||||
removing file
|
||||
auto-repacking treedirstate
|
||||
removing old unreferenced dirstate tree * (glob)
|
||||
$ ls .hg/dirstate.tree.*
|
||||
.hg/dirstate.tree.* (glob)
|
||||
.hg/dirstate.tree.* (glob)
|
||||
.hg/dirstate.tree.* (glob)
|
||||
|
||||
Test downgrade on pull
|
||||
|
||||
$ for f in 1 2 3 4 5 ; do mkdir dir$f ; echo $f > dir$f/file$f ; hg add dir$f/file$f ; done
|
||||
$ echo x > a
|
||||
$ hg add a
|
||||
$ hg commit -m "add files"
|
||||
$ cd ..
|
||||
$ hg clone repo clone
|
||||
updating to branch default
|
||||
7 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
$ cd clone
|
||||
$ hg merge 1
|
||||
merging a
|
||||
warning: 1 conflicts while merging a! (edit, then use 'hg resolve --mark')
|
||||
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
|
||||
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
|
||||
[1]
|
||||
$ echo data > newfile
|
||||
$ hg add newfile
|
||||
$ hg rm dir3/file3
|
||||
$ grep treedirstate .hg/requires
|
||||
treedirstate
|
||||
$ hg pull --config treestate.automigrate=true --config format.dirstate=0
|
||||
downgrading dirstate format...
|
||||
pulling from $TESTTMP/repo (glob)
|
||||
searching for changes
|
||||
no changes found
|
||||
$ hg debugdirstate
|
||||
m 0 -2 * a (glob)
|
||||
n 644 5 * base (glob)
|
||||
n 644 2 * dir1/file1 (glob)
|
||||
n 644 2 * dir2/file2 (glob)
|
||||
r 0 0 * dir3/file3 (glob)
|
||||
n 644 2 * dir4/file4 (glob)
|
||||
n 644 2 * dir5/file5 (glob)
|
||||
a 0 -1 * newfile (glob)
|
||||
$ grep treedirstate .hg/requires
|
||||
[1]
|
||||
|
||||
Test upgrade on pull
|
||||
|
||||
$ hg pull --config treestate.automigrate=true --config format.dirstate=1
|
||||
please wait while we migrate dirstate format to version 1
|
||||
this will make your hg commands faster...
|
||||
pulling from $TESTTMP/repo (glob)
|
||||
searching for changes
|
||||
no changes found
|
||||
$ hg debugdirstate
|
||||
m 0 -2 * a (glob)
|
||||
n 644 5 * base (glob)
|
||||
n 644 2 * dir1/file1 (glob)
|
||||
n 644 2 * dir2/file2 (glob)
|
||||
r 0 0 * dir3/file3 (glob)
|
||||
n 644 2 * dir4/file4 (glob)
|
||||
n 644 2 * dir5/file5 (glob)
|
||||
a 0 -1 * newfile (glob)
|
||||
$ grep treedirstate .hg/requires
|
||||
treedirstate
|
||||
|
@ -1,48 +0,0 @@
|
||||
#require fsmonitor
|
||||
$ setconfig extensions.treemanifest=!
|
||||
|
||||
Fsmonitor is required for treestate to track untracked files.
|
||||
|
||||
Nonnormalset, otherparentset, copymap might have reference to untracked files.
|
||||
They should be filtered out when downgrading from treestate to treedirstate.
|
||||
|
||||
Create a treestate repo
|
||||
|
||||
$ hg init repo1 --config format.dirstate=2
|
||||
$ cd repo1
|
||||
$ touch x
|
||||
|
||||
Write the untracked file to treestate
|
||||
|
||||
$ hg status
|
||||
? x
|
||||
$ hg debugtree
|
||||
dirstate v2 (* 1 files tracked) (glob)
|
||||
|
||||
Downgrade to treedirstate
|
||||
|
||||
$ hg debugtree v1
|
||||
|
||||
Check nonnormalset
|
||||
|
||||
$ hg debugshell --command 'print(repr(sorted(repo.dirstate._map.nonnormalset)))'
|
||||
[]
|
||||
|
||||
Check downgrade with "hg pull"
|
||||
|
||||
$ hg init $TESTTMP/repo2 --config format.dirstate=2
|
||||
$ cd $TESTTMP/repo2
|
||||
$ touch x
|
||||
$ hg ci -m init -A x -q
|
||||
|
||||
$ hg init $TESTTMP/repo3 --config format.dirstate=2
|
||||
$ cd $TESTTMP/repo3
|
||||
$ hg pull ../repo2 --config format.dirstate=1 --config treestate.automigrate=true --config extensions.rebase= --rebase -q
|
||||
|
||||
fsmonitor state is invalidated after upgrade
|
||||
|
||||
$ ls .hg/fsmonitor.state
|
||||
.hg/fsmonitor.state
|
||||
$ hg pull ../repo2 --config format.dirstate=2 --config treestate.automigrate=true --config extensions.rebase= --rebase -q
|
||||
$ [ -f .hg/fsmonitor.state ]
|
||||
[1]
|
@ -457,7 +457,7 @@ test revlog format 0
|
||||
$ revlog-formatv0.py
|
||||
$ cd formatv0
|
||||
$ hg verify
|
||||
abort: repo is corrupted: 00changelog.i
|
||||
abort: legacy dirstate implementations are no longer supported!
|
||||
[255]
|
||||
$ cd ..
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user