mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 07:49:11 +03:00
041a91f971
This class is only needed on case insensitive filesystems, and only for wdir context matches. It allows the user to not match the case of the items in the filesystem- especially for naming directories, which dirstate doesn't handle[1]. Making dirstate handle mismatched directory cases is too expensive[2]. Since dirstate doesn't apply to committed csets, this is only created by overriding basectx.match() in workingctx, and only on icasefs. The default arguments have been dropped, because the ctx must be passed to the matcher in order to function. For operations that can apply to both wdir and some other context, this ends up normalizing the filename to the case as it exists in the filesystem, and using that case for the lookup in the other context. See the diff example in the test. Previously, given a directory with an inexact case: - add worked as expected - diff, forget and status would silently ignore the request - files would exit with 1 - commit, revert and remove would fail (even when the commands leading up to them worked): $ hg ci -m "AbCDef" capsdir1/capsdir abort: CapsDir1/CapsDir: no match under directory! $ hg revert -r '.^' capsdir1/capsdir capsdir1\capsdir: no such file in rev 64dae27060b7 $ hg remove capsdir1/capsdir not removing capsdir1\capsdir: no tracked files [1] Globs are normalized, so that the -I and -X don't need to be specified with a case match. Without that, the second last remove (with -X) removes the files, leaving nothing for the last remove. However, specifying the files as 'glob:**.Txt' does not work. Perhaps this requires 're.IGNORECASE'? There are only a handful of places that create matchers directly, instead of being routed through the context.match() method. Some may benefit from changing over to using ctx.match() as a factory function: revset.checkstatus() revset.contains() revset.filelog() revset._matchfiles() localrepository._loadfilter() ignore.ignore() fileset.subrepo() filemerge._picktool() overrides.addlargefiles() lfcommands.lfconvert() kwtemplate.__init__() eolfile.__init__() eolfile.checkrev() acl.buildmatch() Currently, a toplevel subrepo can be named with an inexact case. However, the path auditor gets in the way of naming _anything_ in the subrepo if the top level case doesn't match. That is trickier to handle, because there's the user provided case, the case in the filesystem, and the case stored in .hgsub. This can be fixed next cycle. --- a/tests/test-subrepo-deep-nested-change.t +++ b/tests/test-subrepo-deep-nested-change.t @@ -170,8 +170,15 @@ R sub1/sub2/test.txt $ hg update -Cq $ touch sub1/sub2/folder/bar +#if icasefs + $ hg addremove Sub1/sub2 + abort: path 'Sub1\sub2' is inside nested repo 'Sub1' + [255] + $ hg -q addremove sub1/sub2 +#else $ hg addremove sub1/sub2 adding sub1/sub2/folder/bar (glob) +#endif $ hg status -S A sub1/sub2/folder/bar ? foo/bar/abc The narrowmatcher class may need to be tweaked when that is fixed. [1] http://www.selenic.com/pipermail/mercurial-devel/2015-April/068183.html [2] http://www.selenic.com/pipermail/mercurial-devel/2015-April/068191.html
224 lines
4.4 KiB
Perl
224 lines
4.4 KiB
Perl
$ hg init a
|
|
$ cd a
|
|
$ echo a > a
|
|
$ hg add -n
|
|
adding a
|
|
$ hg st
|
|
? a
|
|
$ hg add
|
|
adding a
|
|
$ hg st
|
|
A a
|
|
$ hg forget a
|
|
$ hg add
|
|
adding a
|
|
$ hg st
|
|
A a
|
|
|
|
$ echo b > b
|
|
$ hg add -n b
|
|
$ hg st
|
|
A a
|
|
? b
|
|
$ hg add b
|
|
$ hg st
|
|
A a
|
|
A b
|
|
|
|
should fail
|
|
|
|
$ hg add b
|
|
b already tracked!
|
|
$ hg st
|
|
A a
|
|
A b
|
|
|
|
#if no-windows
|
|
$ echo foo > con.xml
|
|
$ hg --config ui.portablefilenames=jump add con.xml
|
|
abort: ui.portablefilenames value is invalid ('jump')
|
|
[255]
|
|
$ hg --config ui.portablefilenames=abort add con.xml
|
|
abort: filename contains 'con', which is reserved on Windows: 'con.xml'
|
|
[255]
|
|
$ hg st
|
|
A a
|
|
A b
|
|
? con.xml
|
|
$ hg add con.xml
|
|
warning: filename contains 'con', which is reserved on Windows: 'con.xml'
|
|
$ hg st
|
|
A a
|
|
A b
|
|
A con.xml
|
|
$ hg forget con.xml
|
|
$ rm con.xml
|
|
#endif
|
|
|
|
#if eol-in-paths
|
|
$ echo bla > 'hello:world'
|
|
$ hg --config ui.portablefilenames=abort add
|
|
adding hello:world
|
|
abort: filename contains ':', which is reserved on Windows: 'hello:world'
|
|
[255]
|
|
$ hg st
|
|
A a
|
|
A b
|
|
? hello:world
|
|
$ hg --config ui.portablefilenames=ignore add
|
|
adding hello:world
|
|
$ hg st
|
|
A a
|
|
A b
|
|
A hello:world
|
|
#endif
|
|
|
|
$ hg ci -m 0 --traceback
|
|
|
|
should fail
|
|
|
|
$ hg add a
|
|
a already tracked!
|
|
|
|
$ echo aa > a
|
|
$ hg ci -m 1
|
|
$ hg up 0
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ echo aaa > a
|
|
$ hg ci -m 2
|
|
created new head
|
|
|
|
$ hg merge
|
|
merging a
|
|
warning: conflicts during merge.
|
|
merging a incomplete! (edit conflicts, 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]
|
|
$ hg st
|
|
M a
|
|
? a.orig
|
|
|
|
should fail
|
|
|
|
$ hg add a
|
|
a already tracked!
|
|
$ hg st
|
|
M a
|
|
? a.orig
|
|
$ hg resolve -m a
|
|
(no more unresolved files)
|
|
$ hg ci -m merge
|
|
|
|
Issue683: peculiarity with hg revert of an removed then added file
|
|
|
|
$ hg forget a
|
|
$ hg add a
|
|
$ hg st
|
|
? a.orig
|
|
$ hg rm a
|
|
$ hg st
|
|
R a
|
|
? a.orig
|
|
$ echo a > a
|
|
$ hg add a
|
|
$ hg st
|
|
M a
|
|
? a.orig
|
|
|
|
Forgotten file can be added back (as either clean or modified)
|
|
|
|
$ hg forget b
|
|
$ hg add b
|
|
$ hg st -A b
|
|
C b
|
|
$ hg forget b
|
|
$ echo modified > b
|
|
$ hg add b
|
|
$ hg st -A b
|
|
M b
|
|
$ hg revert -qC b
|
|
|
|
$ hg add c && echo "unexpected addition of missing file"
|
|
c: * (glob)
|
|
[1]
|
|
$ echo c > c
|
|
$ hg add d c && echo "unexpected addition of missing file"
|
|
d: * (glob)
|
|
[1]
|
|
$ hg st
|
|
M a
|
|
A c
|
|
? a.orig
|
|
$ hg up -C
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
forget and get should have the right order: added but missing dir should be
|
|
forgotten before file with same name is added
|
|
|
|
$ echo file d > d
|
|
$ hg add d
|
|
$ hg ci -md
|
|
$ hg rm d
|
|
$ mkdir d
|
|
$ echo a > d/a
|
|
$ hg add d/a
|
|
$ rm -r d
|
|
$ hg up -C
|
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
$ cat d
|
|
file d
|
|
|
|
Test that adding a directory doesn't require case matching (issue4578)
|
|
#if icasefs
|
|
$ mkdir -p CapsDir1/CapsDir
|
|
$ echo abc > CapsDir1/CapsDir/AbC.txt
|
|
$ mkdir CapsDir1/CapsDir/SubDir
|
|
$ echo def > CapsDir1/CapsDir/SubDir/Def.txt
|
|
|
|
$ hg add capsdir1/capsdir
|
|
adding CapsDir1/CapsDir/AbC.txt (glob)
|
|
adding CapsDir1/CapsDir/SubDir/Def.txt (glob)
|
|
|
|
$ hg forget capsdir1/capsdir/abc.txt
|
|
removing CapsDir1/CapsDir/AbC.txt (glob)
|
|
|
|
$ hg forget capsdir1/capsdir
|
|
removing CapsDir1/CapsDir/SubDir/Def.txt (glob)
|
|
|
|
$ hg add capsdir1
|
|
adding CapsDir1/CapsDir/AbC.txt (glob)
|
|
adding CapsDir1/CapsDir/SubDir/Def.txt (glob)
|
|
|
|
$ hg ci -m "AbCDef" capsdir1/capsdir
|
|
|
|
$ hg status -A capsdir1/capsdir
|
|
C CapsDir1/CapsDir/AbC.txt
|
|
C CapsDir1/CapsDir/SubDir/Def.txt
|
|
|
|
$ hg files capsdir1/capsdir
|
|
CapsDir1/CapsDir/AbC.txt (glob)
|
|
CapsDir1/CapsDir/SubDir/Def.txt (glob)
|
|
|
|
$ echo xyz > CapsDir1/CapsDir/SubDir/Def.txt
|
|
$ hg ci -m xyz capsdir1/capsdir/subdir/def.txt
|
|
|
|
$ hg revert -r '.^' capsdir1/capsdir
|
|
reverting CapsDir1/CapsDir/SubDir/Def.txt (glob)
|
|
|
|
$ hg diff capsdir1/capsdir
|
|
diff -r 5112e00e781d CapsDir1/CapsDir/SubDir/Def.txt
|
|
--- a/CapsDir1/CapsDir/SubDir/Def.txt Thu Jan 01 00:00:00 1970 +0000
|
|
+++ b/CapsDir1/CapsDir/SubDir/Def.txt * +0000 (glob)
|
|
@@ -1,1 +1,1 @@
|
|
-xyz
|
|
+def
|
|
|
|
$ hg remove -f 'glob:**.txt' -X capsdir1/capsdir
|
|
$ hg remove -f 'glob:**.txt' -I capsdir1/capsdir
|
|
removing CapsDir1/CapsDir/AbC.txt (glob)
|
|
removing CapsDir1/CapsDir/SubDir/Def.txt (glob)
|
|
#endif
|
|
|
|
$ cd ..
|