##// END OF EJS Templates
dirstate-v2: Add a variant of some tests, that uses the new format...
Simon Sapin -
r48056:6763913f default
parent child Browse files
Show More
@@ -1,244 +1,250 b''
1 #testcases dirstate-v1 dirstate-v1-tree
1 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
2
2
3 #if dirstate-v1-tree
3 #if dirstate-v1-tree
4 #require rust
4 #require rust
5 $ echo '[experimental]' >> $HGRCPATH
5 $ echo '[experimental]' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
7 #endif
7 #endif
8
8
9 #if dirstate-v2
10 #require rust
11 $ echo '[format]' >> $HGRCPATH
12 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
13 #endif
14
9 $ hg init repo
15 $ hg init repo
10 $ cd repo
16 $ cd repo
11 $ echo a > a
17 $ echo a > a
12 $ hg add a
18 $ hg add a
13 $ hg commit -m test
19 $ hg commit -m test
14
20
15 Do we ever miss a sub-second change?:
21 Do we ever miss a sub-second change?:
16
22
17 $ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
23 $ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
18 > hg co -qC 0
24 > hg co -qC 0
19 > echo b > a
25 > echo b > a
20 > hg st
26 > hg st
21 > done
27 > done
22 M a
28 M a
23 M a
29 M a
24 M a
30 M a
25 M a
31 M a
26 M a
32 M a
27 M a
33 M a
28 M a
34 M a
29 M a
35 M a
30 M a
36 M a
31 M a
37 M a
32 M a
38 M a
33 M a
39 M a
34 M a
40 M a
35 M a
41 M a
36 M a
42 M a
37 M a
43 M a
38 M a
44 M a
39 M a
45 M a
40 M a
46 M a
41 M a
47 M a
42
48
43 $ echo test > b
49 $ echo test > b
44 $ mkdir dir1
50 $ mkdir dir1
45 $ echo test > dir1/c
51 $ echo test > dir1/c
46 $ echo test > d
52 $ echo test > d
47
53
48 $ echo test > e
54 $ echo test > e
49 #if execbit
55 #if execbit
50 A directory will typically have the execute bit -- make sure it doesn't get
56 A directory will typically have the execute bit -- make sure it doesn't get
51 confused with a file with the exec bit set
57 confused with a file with the exec bit set
52 $ chmod +x e
58 $ chmod +x e
53 #endif
59 #endif
54
60
55 $ hg add b dir1 d e
61 $ hg add b dir1 d e
56 adding dir1/c
62 adding dir1/c
57 $ hg commit -m test2
63 $ hg commit -m test2
58
64
59 $ cat >> $TESTTMP/dirstaterace.py << EOF
65 $ cat >> $TESTTMP/dirstaterace.py << EOF
60 > from mercurial import (
66 > from mercurial import (
61 > context,
67 > context,
62 > extensions,
68 > extensions,
63 > )
69 > )
64 > def extsetup(ui):
70 > def extsetup(ui):
65 > extensions.wrapfunction(context.workingctx, '_checklookup', overridechecklookup)
71 > extensions.wrapfunction(context.workingctx, '_checklookup', overridechecklookup)
66 > def overridechecklookup(orig, self, files):
72 > def overridechecklookup(orig, self, files):
67 > # make an update that changes the dirstate from underneath
73 > # make an update that changes the dirstate from underneath
68 > self._repo.ui.system(br"sh '$TESTTMP/dirstaterace.sh'",
74 > self._repo.ui.system(br"sh '$TESTTMP/dirstaterace.sh'",
69 > cwd=self._repo.root)
75 > cwd=self._repo.root)
70 > return orig(self, files)
76 > return orig(self, files)
71 > EOF
77 > EOF
72
78
73 $ hg debugrebuilddirstate
79 $ hg debugrebuilddirstate
74 $ hg debugdirstate
80 $ hg debugdirstate
75 n 0 -1 unset a
81 n 0 -1 unset a
76 n 0 -1 unset b
82 n 0 -1 unset b
77 n 0 -1 unset d
83 n 0 -1 unset d
78 n 0 -1 unset dir1/c
84 n 0 -1 unset dir1/c
79 n 0 -1 unset e
85 n 0 -1 unset e
80
86
81 XXX Note that this returns M for files that got replaced by directories. This is
87 XXX Note that this returns M for files that got replaced by directories. This is
82 definitely a bug, but the fix for that is hard and the next status run is fine
88 definitely a bug, but the fix for that is hard and the next status run is fine
83 anyway.
89 anyway.
84
90
85 $ cat > $TESTTMP/dirstaterace.sh <<EOF
91 $ cat > $TESTTMP/dirstaterace.sh <<EOF
86 > rm b && rm -r dir1 && rm d && mkdir d && rm e && mkdir e
92 > rm b && rm -r dir1 && rm d && mkdir d && rm e && mkdir e
87 > EOF
93 > EOF
88
94
89 $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py
95 $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py
90 M d
96 M d
91 M e
97 M e
92 ! b
98 ! b
93 ! dir1/c
99 ! dir1/c
94 $ hg debugdirstate
100 $ hg debugdirstate
95 n 644 2 * a (glob)
101 n 644 2 * a (glob)
96 n 0 -1 unset b
102 n 0 -1 unset b
97 n 0 -1 unset d
103 n 0 -1 unset d
98 n 0 -1 unset dir1/c
104 n 0 -1 unset dir1/c
99 n 0 -1 unset e
105 n 0 -1 unset e
100
106
101 $ hg status
107 $ hg status
102 ! b
108 ! b
103 ! d
109 ! d
104 ! dir1/c
110 ! dir1/c
105 ! e
111 ! e
106
112
107 $ rmdir d e
113 $ rmdir d e
108 $ hg update -C -q .
114 $ hg update -C -q .
109
115
110 Test that dirstate changes aren't written out at the end of "hg
116 Test that dirstate changes aren't written out at the end of "hg
111 status", if .hg/dirstate is already changed simultaneously before
117 status", if .hg/dirstate is already changed simultaneously before
112 acquisition of wlock in workingctx._poststatusfixup().
118 acquisition of wlock in workingctx._poststatusfixup().
113
119
114 This avoidance is important to keep consistency of dirstate in race
120 This avoidance is important to keep consistency of dirstate in race
115 condition (see issue5584 for detail).
121 condition (see issue5584 for detail).
116
122
117 $ hg parents -q
123 $ hg parents -q
118 1:* (glob)
124 1:* (glob)
119
125
120 $ hg debugrebuilddirstate
126 $ hg debugrebuilddirstate
121 $ hg debugdirstate
127 $ hg debugdirstate
122 n 0 -1 unset a
128 n 0 -1 unset a
123 n 0 -1 unset b
129 n 0 -1 unset b
124 n 0 -1 unset d
130 n 0 -1 unset d
125 n 0 -1 unset dir1/c
131 n 0 -1 unset dir1/c
126 n 0 -1 unset e
132 n 0 -1 unset e
127
133
128 $ cat > $TESTTMP/dirstaterace.sh <<EOF
134 $ cat > $TESTTMP/dirstaterace.sh <<EOF
129 > # This script assumes timetable of typical issue5584 case below:
135 > # This script assumes timetable of typical issue5584 case below:
130 > #
136 > #
131 > # 1. "hg status" loads .hg/dirstate
137 > # 1. "hg status" loads .hg/dirstate
132 > # 2. "hg status" confirms clean-ness of FILE
138 > # 2. "hg status" confirms clean-ness of FILE
133 > # 3. "hg update -C 0" updates the working directory simultaneously
139 > # 3. "hg update -C 0" updates the working directory simultaneously
134 > # (FILE is removed, and FILE is dropped from .hg/dirstate)
140 > # (FILE is removed, and FILE is dropped from .hg/dirstate)
135 > # 4. "hg status" acquires wlock
141 > # 4. "hg status" acquires wlock
136 > # (.hg/dirstate is re-loaded = no FILE entry in dirstate)
142 > # (.hg/dirstate is re-loaded = no FILE entry in dirstate)
137 > # 5. "hg status" marks FILE in dirstate as clean
143 > # 5. "hg status" marks FILE in dirstate as clean
138 > # (FILE entry is added to in-memory dirstate)
144 > # (FILE entry is added to in-memory dirstate)
139 > # 6. "hg status" writes dirstate changes into .hg/dirstate
145 > # 6. "hg status" writes dirstate changes into .hg/dirstate
140 > # (FILE entry is written into .hg/dirstate)
146 > # (FILE entry is written into .hg/dirstate)
141 > #
147 > #
142 > # To reproduce similar situation easily and certainly, #2 and #3
148 > # To reproduce similar situation easily and certainly, #2 and #3
143 > # are swapped. "hg cat" below ensures #2 on "hg status" side.
149 > # are swapped. "hg cat" below ensures #2 on "hg status" side.
144 >
150 >
145 > hg update -q -C 0
151 > hg update -q -C 0
146 > hg cat -r 1 b > b
152 > hg cat -r 1 b > b
147 > EOF
153 > EOF
148
154
149 "hg status" below should excludes "e", of which exec flag is set, for
155 "hg status" below should excludes "e", of which exec flag is set, for
150 portability of test scenario, because unsure but missing "e" is
156 portability of test scenario, because unsure but missing "e" is
151 treated differently in _checklookup() according to runtime platform.
157 treated differently in _checklookup() according to runtime platform.
152
158
153 - "missing(!)" on POSIX, "pctx[f].cmp(self[f])" raises ENOENT
159 - "missing(!)" on POSIX, "pctx[f].cmp(self[f])" raises ENOENT
154 - "modified(M)" on Windows, "self.flags(f) != pctx.flags(f)" is True
160 - "modified(M)" on Windows, "self.flags(f) != pctx.flags(f)" is True
155
161
156 $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py --debug -X path:e
162 $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py --debug -X path:e
157 skip updating dirstate: identity mismatch
163 skip updating dirstate: identity mismatch
158 M a
164 M a
159 ! d
165 ! d
160 ! dir1/c
166 ! dir1/c
161
167
162 $ hg parents -q
168 $ hg parents -q
163 0:* (glob)
169 0:* (glob)
164 $ hg files
170 $ hg files
165 a
171 a
166 $ hg debugdirstate
172 $ hg debugdirstate
167 n * * * a (glob)
173 n * * * a (glob)
168
174
169 $ rm b
175 $ rm b
170
176
171 #if fsmonitor
177 #if fsmonitor
172
178
173 Create fsmonitor state.
179 Create fsmonitor state.
174
180
175 $ hg status
181 $ hg status
176 $ f --type .hg/fsmonitor.state
182 $ f --type .hg/fsmonitor.state
177 .hg/fsmonitor.state: file
183 .hg/fsmonitor.state: file
178
184
179 Test that invalidating fsmonitor state in the middle (which doesn't require the
185 Test that invalidating fsmonitor state in the middle (which doesn't require the
180 wlock) causes the fsmonitor update to be skipped.
186 wlock) causes the fsmonitor update to be skipped.
181 hg debugrebuilddirstate ensures that the dirstaterace hook will be called, but
187 hg debugrebuilddirstate ensures that the dirstaterace hook will be called, but
182 it also invalidates the fsmonitor state. So back it up and restore it.
188 it also invalidates the fsmonitor state. So back it up and restore it.
183
189
184 $ mv .hg/fsmonitor.state .hg/fsmonitor.state.tmp
190 $ mv .hg/fsmonitor.state .hg/fsmonitor.state.tmp
185 $ hg debugrebuilddirstate
191 $ hg debugrebuilddirstate
186 $ mv .hg/fsmonitor.state.tmp .hg/fsmonitor.state
192 $ mv .hg/fsmonitor.state.tmp .hg/fsmonitor.state
187
193
188 $ cat > $TESTTMP/dirstaterace.sh <<EOF
194 $ cat > $TESTTMP/dirstaterace.sh <<EOF
189 > rm .hg/fsmonitor.state
195 > rm .hg/fsmonitor.state
190 > EOF
196 > EOF
191
197
192 $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py --debug
198 $ hg status --config extensions.dirstaterace=$TESTTMP/dirstaterace.py --debug
193 skip updating fsmonitor.state: identity mismatch
199 skip updating fsmonitor.state: identity mismatch
194 $ f .hg/fsmonitor.state
200 $ f .hg/fsmonitor.state
195 .hg/fsmonitor.state: file not found
201 .hg/fsmonitor.state: file not found
196
202
197 #endif
203 #endif
198
204
199 Set up a rebase situation for issue5581.
205 Set up a rebase situation for issue5581.
200
206
201 $ echo c2 > a
207 $ echo c2 > a
202 $ echo c2 > b
208 $ echo c2 > b
203 $ hg add b
209 $ hg add b
204 $ hg commit -m c2
210 $ hg commit -m c2
205 created new head
211 created new head
206 $ echo c3 >> a
212 $ echo c3 >> a
207 $ hg commit -m c3
213 $ hg commit -m c3
208 $ hg update 2
214 $ hg update 2
209 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 $ echo c4 >> a
216 $ echo c4 >> a
211 $ echo c4 >> b
217 $ echo c4 >> b
212 $ hg commit -m c4
218 $ hg commit -m c4
213 created new head
219 created new head
214
220
215 Configure a merge tool that runs status in the middle of the rebase. The goal of
221 Configure a merge tool that runs status in the middle of the rebase. The goal of
216 the status call is to trigger a potential bug if fsmonitor's state is written
222 the status call is to trigger a potential bug if fsmonitor's state is written
217 even though the wlock is held by another process. The output of 'hg status' in
223 even though the wlock is held by another process. The output of 'hg status' in
218 the merge tool goes to /dev/null because we're more interested in the results of
224 the merge tool goes to /dev/null because we're more interested in the results of
219 'hg status' run after the rebase.
225 'hg status' run after the rebase.
220
226
221 $ cat >> $TESTTMP/mergetool-race.sh << EOF
227 $ cat >> $TESTTMP/mergetool-race.sh << EOF
222 > echo "custom merge tool"
228 > echo "custom merge tool"
223 > printf "c2\nc3\nc4\n" > \$1
229 > printf "c2\nc3\nc4\n" > \$1
224 > hg --cwd "$TESTTMP/repo" status > /dev/null
230 > hg --cwd "$TESTTMP/repo" status > /dev/null
225 > echo "custom merge tool end"
231 > echo "custom merge tool end"
226 > EOF
232 > EOF
227 $ cat >> $HGRCPATH << EOF
233 $ cat >> $HGRCPATH << EOF
228 > [extensions]
234 > [extensions]
229 > rebase =
235 > rebase =
230 > [merge-tools]
236 > [merge-tools]
231 > test.executable=sh
237 > test.executable=sh
232 > test.args=$TESTTMP/mergetool-race.sh \$output
238 > test.args=$TESTTMP/mergetool-race.sh \$output
233 > EOF
239 > EOF
234
240
235 $ hg rebase -s . -d 3 --tool test
241 $ hg rebase -s . -d 3 --tool test
236 rebasing 4:b08445fd6b2a tip "c4"
242 rebasing 4:b08445fd6b2a tip "c4"
237 merging a
243 merging a
238 custom merge tool
244 custom merge tool
239 custom merge tool end
245 custom merge tool end
240 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/* (glob)
246 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/* (glob)
241
247
242 This hg status should be empty, whether or not fsmonitor is enabled (issue5581).
248 This hg status should be empty, whether or not fsmonitor is enabled (issue5581).
243
249
244 $ hg status
250 $ hg status
@@ -1,45 +1,51 b''
1 #testcases dirstate-v1 dirstate-v1-tree
1 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
2
2
3 #if dirstate-v1-tree
3 #if dirstate-v1-tree
4 #require rust
4 #require rust
5 $ echo '[experimental]' >> $HGRCPATH
5 $ echo '[experimental]' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
7 #endif
7 #endif
8
8
9 #if dirstate-v2
10 #require rust
11 $ echo '[format]' >> $HGRCPATH
12 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
13 #endif
14
9 Checking the size/permissions/file-type of files stored in the
15 Checking the size/permissions/file-type of files stored in the
10 dirstate after an update where the files are changed concurrently
16 dirstate after an update where the files are changed concurrently
11 outside of hg's control.
17 outside of hg's control.
12
18
13 $ hg init repo
19 $ hg init repo
14 $ cd repo
20 $ cd repo
15 $ echo a > a
21 $ echo a > a
16 $ hg commit -qAm _
22 $ hg commit -qAm _
17 $ echo aa > a
23 $ echo aa > a
18 $ hg commit -m _
24 $ hg commit -m _
19
25
20 $ hg debugdirstate --no-dates
26 $ hg debugdirstate --no-dates
21 n 644 3 (set |unset) a (re)
27 n 644 3 (set |unset) a (re)
22
28
23 $ cat >> $TESTTMP/dirstaterace.py << EOF
29 $ cat >> $TESTTMP/dirstaterace.py << EOF
24 > from mercurial import (
30 > from mercurial import (
25 > extensions,
31 > extensions,
26 > merge,
32 > merge,
27 > )
33 > )
28 > def extsetup(ui):
34 > def extsetup(ui):
29 > extensions.wrapfunction(merge, 'applyupdates', wrap)
35 > extensions.wrapfunction(merge, 'applyupdates', wrap)
30 > def wrap(orig, *args, **kwargs):
36 > def wrap(orig, *args, **kwargs):
31 > res = orig(*args, **kwargs)
37 > res = orig(*args, **kwargs)
32 > with open("a", "w"):
38 > with open("a", "w"):
33 > pass # just truncate the file
39 > pass # just truncate the file
34 > return res
40 > return res
35 > EOF
41 > EOF
36
42
37 Do an update where file 'a' is changed between hg writing it to disk
43 Do an update where file 'a' is changed between hg writing it to disk
38 and hg writing the dirstate. The dirstate is correct nonetheless, and
44 and hg writing the dirstate. The dirstate is correct nonetheless, and
39 so hg status correctly shows a as clean.
45 so hg status correctly shows a as clean.
40
46
41 $ hg up -r 0 --config extensions.race=$TESTTMP/dirstaterace.py
47 $ hg up -r 0 --config extensions.race=$TESTTMP/dirstaterace.py
42 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 $ hg debugdirstate --no-dates
49 $ hg debugdirstate --no-dates
44 n 644 2 (set |unset) a (re)
50 n 644 2 (set |unset) a (re)
45 $ echo a > a; hg status; hg diff
51 $ echo a > a; hg status; hg diff
@@ -1,102 +1,108 b''
1 #testcases dirstate-v1 dirstate-v1-tree
1 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
2
2
3 #if dirstate-v1-tree
3 #if dirstate-v1-tree
4 #require rust
4 #require rust
5 $ echo '[experimental]' >> $HGRCPATH
5 $ echo '[experimental]' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
7 #endif
7 #endif
8
8
9 #if dirstate-v2
10 #require rust
11 $ echo '[format]' >> $HGRCPATH
12 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
13 #endif
14
9 ------ Test dirstate._dirs refcounting
15 ------ Test dirstate._dirs refcounting
10
16
11 $ hg init t
17 $ hg init t
12 $ cd t
18 $ cd t
13 $ mkdir -p a/b/c/d
19 $ mkdir -p a/b/c/d
14 $ touch a/b/c/d/x
20 $ touch a/b/c/d/x
15 $ touch a/b/c/d/y
21 $ touch a/b/c/d/y
16 $ touch a/b/c/d/z
22 $ touch a/b/c/d/z
17 $ hg ci -Am m
23 $ hg ci -Am m
18 adding a/b/c/d/x
24 adding a/b/c/d/x
19 adding a/b/c/d/y
25 adding a/b/c/d/y
20 adding a/b/c/d/z
26 adding a/b/c/d/z
21 $ hg mv a z
27 $ hg mv a z
22 moving a/b/c/d/x to z/b/c/d/x
28 moving a/b/c/d/x to z/b/c/d/x
23 moving a/b/c/d/y to z/b/c/d/y
29 moving a/b/c/d/y to z/b/c/d/y
24 moving a/b/c/d/z to z/b/c/d/z
30 moving a/b/c/d/z to z/b/c/d/z
25
31
26 Test name collisions
32 Test name collisions
27
33
28 $ rm z/b/c/d/x
34 $ rm z/b/c/d/x
29 $ mkdir z/b/c/d/x
35 $ mkdir z/b/c/d/x
30 $ touch z/b/c/d/x/y
36 $ touch z/b/c/d/x/y
31 $ hg add z/b/c/d/x/y
37 $ hg add z/b/c/d/x/y
32 abort: file 'z/b/c/d/x' in dirstate clashes with 'z/b/c/d/x/y'
38 abort: file 'z/b/c/d/x' in dirstate clashes with 'z/b/c/d/x/y'
33 [255]
39 [255]
34 $ rm -rf z/b/c/d
40 $ rm -rf z/b/c/d
35 $ touch z/b/c/d
41 $ touch z/b/c/d
36 $ hg add z/b/c/d
42 $ hg add z/b/c/d
37 abort: directory 'z/b/c/d' already in dirstate
43 abort: directory 'z/b/c/d' already in dirstate
38 [255]
44 [255]
39
45
40 $ cd ..
46 $ cd ..
41
47
42 Issue1790: dirstate entry locked into unset if file mtime is set into
48 Issue1790: dirstate entry locked into unset if file mtime is set into
43 the future
49 the future
44
50
45 Prepare test repo:
51 Prepare test repo:
46
52
47 $ hg init u
53 $ hg init u
48 $ cd u
54 $ cd u
49 $ echo a > a
55 $ echo a > a
50 $ hg add
56 $ hg add
51 adding a
57 adding a
52 $ hg ci -m1
58 $ hg ci -m1
53
59
54 Set mtime of a into the future:
60 Set mtime of a into the future:
55
61
56 $ touch -t 202101011200 a
62 $ touch -t 202101011200 a
57
63
58 Status must not set a's entry to unset (issue1790):
64 Status must not set a's entry to unset (issue1790):
59
65
60 $ hg status
66 $ hg status
61 $ hg debugstate
67 $ hg debugstate
62 n 644 2 2021-01-01 12:00:00 a
68 n 644 2 2021-01-01 12:00:00 a
63
69
64 Test modulo storage/comparison of absurd dates:
70 Test modulo storage/comparison of absurd dates:
65
71
66 #if no-aix
72 #if no-aix
67 $ touch -t 195001011200 a
73 $ touch -t 195001011200 a
68 $ hg st
74 $ hg st
69 $ hg debugstate
75 $ hg debugstate
70 n 644 2 2018-01-19 15:14:08 a
76 n 644 2 2018-01-19 15:14:08 a
71 #endif
77 #endif
72
78
73 Verify that exceptions during a dirstate change leave the dirstate
79 Verify that exceptions during a dirstate change leave the dirstate
74 coherent (issue4353)
80 coherent (issue4353)
75
81
76 $ cat > ../dirstateexception.py <<EOF
82 $ cat > ../dirstateexception.py <<EOF
77 > from __future__ import absolute_import
83 > from __future__ import absolute_import
78 > from mercurial import (
84 > from mercurial import (
79 > error,
85 > error,
80 > extensions,
86 > extensions,
81 > mergestate as mergestatemod,
87 > mergestate as mergestatemod,
82 > )
88 > )
83 >
89 >
84 > def wraprecordupdates(*args):
90 > def wraprecordupdates(*args):
85 > raise error.Abort(b"simulated error while recording dirstateupdates")
91 > raise error.Abort(b"simulated error while recording dirstateupdates")
86 >
92 >
87 > def reposetup(ui, repo):
93 > def reposetup(ui, repo):
88 > extensions.wrapfunction(mergestatemod, 'recordupdates',
94 > extensions.wrapfunction(mergestatemod, 'recordupdates',
89 > wraprecordupdates)
95 > wraprecordupdates)
90 > EOF
96 > EOF
91
97
92 $ hg rm a
98 $ hg rm a
93 $ hg commit -m 'rm a'
99 $ hg commit -m 'rm a'
94 $ echo "[extensions]" >> .hg/hgrc
100 $ echo "[extensions]" >> .hg/hgrc
95 $ echo "dirstateex=../dirstateexception.py" >> .hg/hgrc
101 $ echo "dirstateex=../dirstateexception.py" >> .hg/hgrc
96 $ hg up 0
102 $ hg up 0
97 abort: simulated error while recording dirstateupdates
103 abort: simulated error while recording dirstateupdates
98 [255]
104 [255]
99 $ hg log -r . -T '{rev}\n'
105 $ hg log -r . -T '{rev}\n'
100 1
106 1
101 $ hg status
107 $ hg status
102 ? a
108 ? a
@@ -1,398 +1,404 b''
1 #testcases dirstate-v1 dirstate-v1-tree
1 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
2
2
3 #if dirstate-v1-tree
3 #if dirstate-v1-tree
4 #require rust
4 #require rust
5 $ echo '[experimental]' >> $HGRCPATH
5 $ echo '[experimental]' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
7 #endif
7 #endif
8
8
9 #if dirstate-v2
10 #require rust
11 $ echo '[format]' >> $HGRCPATH
12 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
13 #endif
14
9 $ hg init ignorerepo
15 $ hg init ignorerepo
10 $ cd ignorerepo
16 $ cd ignorerepo
11
17
12 debugignore with no hgignore should be deterministic:
18 debugignore with no hgignore should be deterministic:
13 $ hg debugignore
19 $ hg debugignore
14 <nevermatcher>
20 <nevermatcher>
15
21
16 Issue562: .hgignore requires newline at end:
22 Issue562: .hgignore requires newline at end:
17
23
18 $ touch foo
24 $ touch foo
19 $ touch bar
25 $ touch bar
20 $ touch baz
26 $ touch baz
21 $ cat > makeignore.py <<EOF
27 $ cat > makeignore.py <<EOF
22 > f = open(".hgignore", "w")
28 > f = open(".hgignore", "w")
23 > f.write("ignore\n")
29 > f.write("ignore\n")
24 > f.write("foo\n")
30 > f.write("foo\n")
25 > # No EOL here
31 > # No EOL here
26 > f.write("bar")
32 > f.write("bar")
27 > f.close()
33 > f.close()
28 > EOF
34 > EOF
29
35
30 $ "$PYTHON" makeignore.py
36 $ "$PYTHON" makeignore.py
31
37
32 Should display baz only:
38 Should display baz only:
33
39
34 $ hg status
40 $ hg status
35 ? baz
41 ? baz
36
42
37 $ rm foo bar baz .hgignore makeignore.py
43 $ rm foo bar baz .hgignore makeignore.py
38
44
39 $ touch a.o
45 $ touch a.o
40 $ touch a.c
46 $ touch a.c
41 $ touch syntax
47 $ touch syntax
42 $ mkdir dir
48 $ mkdir dir
43 $ touch dir/a.o
49 $ touch dir/a.o
44 $ touch dir/b.o
50 $ touch dir/b.o
45 $ touch dir/c.o
51 $ touch dir/c.o
46
52
47 $ hg add dir/a.o
53 $ hg add dir/a.o
48 $ hg commit -m 0
54 $ hg commit -m 0
49 $ hg add dir/b.o
55 $ hg add dir/b.o
50
56
51 $ hg status
57 $ hg status
52 A dir/b.o
58 A dir/b.o
53 ? a.c
59 ? a.c
54 ? a.o
60 ? a.o
55 ? dir/c.o
61 ? dir/c.o
56 ? syntax
62 ? syntax
57
63
58 $ echo "*.o" > .hgignore
64 $ echo "*.o" > .hgignore
59 $ hg status
65 $ hg status
60 abort: $TESTTMP/ignorerepo/.hgignore: invalid pattern (relre): *.o (glob)
66 abort: $TESTTMP/ignorerepo/.hgignore: invalid pattern (relre): *.o (glob)
61 [255]
67 [255]
62
68
63 Ensure given files are relative to cwd
69 Ensure given files are relative to cwd
64
70
65 $ echo "dir/.*\.o" > .hgignore
71 $ echo "dir/.*\.o" > .hgignore
66 $ hg status -i
72 $ hg status -i
67 I dir/c.o
73 I dir/c.o
68
74
69 $ hg debugignore dir/c.o dir/missing.o
75 $ hg debugignore dir/c.o dir/missing.o
70 dir/c.o is ignored
76 dir/c.o is ignored
71 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
77 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
72 dir/missing.o is ignored
78 dir/missing.o is ignored
73 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
79 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
74 $ cd dir
80 $ cd dir
75 $ hg debugignore c.o missing.o
81 $ hg debugignore c.o missing.o
76 c.o is ignored
82 c.o is ignored
77 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
83 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
78 missing.o is ignored
84 missing.o is ignored
79 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
85 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
80
86
81 For icasefs, inexact matches also work, except for missing files
87 For icasefs, inexact matches also work, except for missing files
82
88
83 #if icasefs
89 #if icasefs
84 $ hg debugignore c.O missing.O
90 $ hg debugignore c.O missing.O
85 c.o is ignored
91 c.o is ignored
86 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
92 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: 'dir/.*\.o') (glob)
87 missing.O is not ignored
93 missing.O is not ignored
88 #endif
94 #endif
89
95
90 $ cd ..
96 $ cd ..
91
97
92 $ echo ".*\.o" > .hgignore
98 $ echo ".*\.o" > .hgignore
93 $ hg status
99 $ hg status
94 A dir/b.o
100 A dir/b.o
95 ? .hgignore
101 ? .hgignore
96 ? a.c
102 ? a.c
97 ? syntax
103 ? syntax
98
104
99 Ensure that comments work:
105 Ensure that comments work:
100
106
101 $ touch 'foo#bar' 'quux#' 'quu0#'
107 $ touch 'foo#bar' 'quux#' 'quu0#'
102 #if no-windows
108 #if no-windows
103 $ touch 'baz\' 'baz\wat' 'ba0\#wat' 'ba1\\' 'ba1\\wat' 'quu0\'
109 $ touch 'baz\' 'baz\wat' 'ba0\#wat' 'ba1\\' 'ba1\\wat' 'quu0\'
104 #endif
110 #endif
105
111
106 $ cat <<'EOF' >> .hgignore
112 $ cat <<'EOF' >> .hgignore
107 > # full-line comment
113 > # full-line comment
108 > # whitespace-only comment line
114 > # whitespace-only comment line
109 > syntax# pattern, no whitespace, then comment
115 > syntax# pattern, no whitespace, then comment
110 > a.c # pattern, then whitespace, then comment
116 > a.c # pattern, then whitespace, then comment
111 > baz\\# # (escaped) backslash, then comment
117 > baz\\# # (escaped) backslash, then comment
112 > ba0\\\#w # (escaped) backslash, escaped comment character, then comment
118 > ba0\\\#w # (escaped) backslash, escaped comment character, then comment
113 > ba1\\\\# # (escaped) backslashes, then comment
119 > ba1\\\\# # (escaped) backslashes, then comment
114 > foo\#b # escaped comment character
120 > foo\#b # escaped comment character
115 > quux\## escaped comment character at end of name
121 > quux\## escaped comment character at end of name
116 > EOF
122 > EOF
117 $ hg status
123 $ hg status
118 A dir/b.o
124 A dir/b.o
119 ? .hgignore
125 ? .hgignore
120 ? quu0#
126 ? quu0#
121 ? quu0\ (no-windows !)
127 ? quu0\ (no-windows !)
122
128
123 $ cat <<'EOF' > .hgignore
129 $ cat <<'EOF' > .hgignore
124 > .*\.o
130 > .*\.o
125 > syntax: glob
131 > syntax: glob
126 > syntax# pattern, no whitespace, then comment
132 > syntax# pattern, no whitespace, then comment
127 > a.c # pattern, then whitespace, then comment
133 > a.c # pattern, then whitespace, then comment
128 > baz\\#* # (escaped) backslash, then comment
134 > baz\\#* # (escaped) backslash, then comment
129 > ba0\\\#w* # (escaped) backslash, escaped comment character, then comment
135 > ba0\\\#w* # (escaped) backslash, escaped comment character, then comment
130 > ba1\\\\#* # (escaped) backslashes, then comment
136 > ba1\\\\#* # (escaped) backslashes, then comment
131 > foo\#b* # escaped comment character
137 > foo\#b* # escaped comment character
132 > quux\## escaped comment character at end of name
138 > quux\## escaped comment character at end of name
133 > quu0[\#]# escaped comment character inside [...]
139 > quu0[\#]# escaped comment character inside [...]
134 > EOF
140 > EOF
135 $ hg status
141 $ hg status
136 A dir/b.o
142 A dir/b.o
137 ? .hgignore
143 ? .hgignore
138 ? ba1\\wat (no-windows !)
144 ? ba1\\wat (no-windows !)
139 ? baz\wat (no-windows !)
145 ? baz\wat (no-windows !)
140 ? quu0\ (no-windows !)
146 ? quu0\ (no-windows !)
141
147
142 $ rm 'foo#bar' 'quux#' 'quu0#'
148 $ rm 'foo#bar' 'quux#' 'quu0#'
143 #if no-windows
149 #if no-windows
144 $ rm 'baz\' 'baz\wat' 'ba0\#wat' 'ba1\\' 'ba1\\wat' 'quu0\'
150 $ rm 'baz\' 'baz\wat' 'ba0\#wat' 'ba1\\' 'ba1\\wat' 'quu0\'
145 #endif
151 #endif
146
152
147 Check that '^\.' does not ignore the root directory:
153 Check that '^\.' does not ignore the root directory:
148
154
149 $ echo "^\." > .hgignore
155 $ echo "^\." > .hgignore
150 $ hg status
156 $ hg status
151 A dir/b.o
157 A dir/b.o
152 ? a.c
158 ? a.c
153 ? a.o
159 ? a.o
154 ? dir/c.o
160 ? dir/c.o
155 ? syntax
161 ? syntax
156
162
157 Test that patterns from ui.ignore options are read:
163 Test that patterns from ui.ignore options are read:
158
164
159 $ echo > .hgignore
165 $ echo > .hgignore
160 $ cat >> $HGRCPATH << EOF
166 $ cat >> $HGRCPATH << EOF
161 > [ui]
167 > [ui]
162 > ignore.other = $TESTTMP/ignorerepo/.hg/testhgignore
168 > ignore.other = $TESTTMP/ignorerepo/.hg/testhgignore
163 > EOF
169 > EOF
164 $ echo "glob:**.o" > .hg/testhgignore
170 $ echo "glob:**.o" > .hg/testhgignore
165 $ hg status
171 $ hg status
166 A dir/b.o
172 A dir/b.o
167 ? .hgignore
173 ? .hgignore
168 ? a.c
174 ? a.c
169 ? syntax
175 ? syntax
170
176
171 empty out testhgignore
177 empty out testhgignore
172 $ echo > .hg/testhgignore
178 $ echo > .hg/testhgignore
173
179
174 Test relative ignore path (issue4473):
180 Test relative ignore path (issue4473):
175
181
176 $ cat >> $HGRCPATH << EOF
182 $ cat >> $HGRCPATH << EOF
177 > [ui]
183 > [ui]
178 > ignore.relative = .hg/testhgignorerel
184 > ignore.relative = .hg/testhgignorerel
179 > EOF
185 > EOF
180 $ echo "glob:*.o" > .hg/testhgignorerel
186 $ echo "glob:*.o" > .hg/testhgignorerel
181 $ cd dir
187 $ cd dir
182 $ hg status
188 $ hg status
183 A dir/b.o
189 A dir/b.o
184 ? .hgignore
190 ? .hgignore
185 ? a.c
191 ? a.c
186 ? syntax
192 ? syntax
187 $ hg debugignore
193 $ hg debugignore
188 <includematcher includes='.*\\.o(?:/|$)'>
194 <includematcher includes='.*\\.o(?:/|$)'>
189
195
190 $ cd ..
196 $ cd ..
191 $ echo > .hg/testhgignorerel
197 $ echo > .hg/testhgignorerel
192 $ echo "syntax: glob" > .hgignore
198 $ echo "syntax: glob" > .hgignore
193 $ echo "re:.*\.o" >> .hgignore
199 $ echo "re:.*\.o" >> .hgignore
194 $ hg status
200 $ hg status
195 A dir/b.o
201 A dir/b.o
196 ? .hgignore
202 ? .hgignore
197 ? a.c
203 ? a.c
198 ? syntax
204 ? syntax
199
205
200 $ echo "syntax: invalid" > .hgignore
206 $ echo "syntax: invalid" > .hgignore
201 $ hg status
207 $ hg status
202 $TESTTMP/ignorerepo/.hgignore: ignoring invalid syntax 'invalid'
208 $TESTTMP/ignorerepo/.hgignore: ignoring invalid syntax 'invalid'
203 A dir/b.o
209 A dir/b.o
204 ? .hgignore
210 ? .hgignore
205 ? a.c
211 ? a.c
206 ? a.o
212 ? a.o
207 ? dir/c.o
213 ? dir/c.o
208 ? syntax
214 ? syntax
209
215
210 $ echo "syntax: glob" > .hgignore
216 $ echo "syntax: glob" > .hgignore
211 $ echo "*.o" >> .hgignore
217 $ echo "*.o" >> .hgignore
212 $ hg status
218 $ hg status
213 A dir/b.o
219 A dir/b.o
214 ? .hgignore
220 ? .hgignore
215 ? a.c
221 ? a.c
216 ? syntax
222 ? syntax
217
223
218 $ echo "relglob:syntax*" > .hgignore
224 $ echo "relglob:syntax*" > .hgignore
219 $ hg status
225 $ hg status
220 A dir/b.o
226 A dir/b.o
221 ? .hgignore
227 ? .hgignore
222 ? a.c
228 ? a.c
223 ? a.o
229 ? a.o
224 ? dir/c.o
230 ? dir/c.o
225
231
226 $ echo "relglob:*" > .hgignore
232 $ echo "relglob:*" > .hgignore
227 $ hg status
233 $ hg status
228 A dir/b.o
234 A dir/b.o
229
235
230 $ cd dir
236 $ cd dir
231 $ hg status .
237 $ hg status .
232 A b.o
238 A b.o
233
239
234 $ hg debugignore
240 $ hg debugignore
235 <includematcher includes='.*(?:/|$)'>
241 <includematcher includes='.*(?:/|$)'>
236
242
237 $ hg debugignore b.o
243 $ hg debugignore b.o
238 b.o is ignored
244 b.o is ignored
239 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: '*') (glob)
245 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 1: '*') (glob)
240
246
241 $ cd ..
247 $ cd ..
242
248
243 Check patterns that match only the directory
249 Check patterns that match only the directory
244
250
245 "(fsmonitor !)" below assumes that fsmonitor is enabled with
251 "(fsmonitor !)" below assumes that fsmonitor is enabled with
246 "walk_on_invalidate = false" (default), which doesn't involve
252 "walk_on_invalidate = false" (default), which doesn't involve
247 re-walking whole repository at detection of .hgignore change.
253 re-walking whole repository at detection of .hgignore change.
248
254
249 $ echo "^dir\$" > .hgignore
255 $ echo "^dir\$" > .hgignore
250 $ hg status
256 $ hg status
251 A dir/b.o
257 A dir/b.o
252 ? .hgignore
258 ? .hgignore
253 ? a.c
259 ? a.c
254 ? a.o
260 ? a.o
255 ? dir/c.o (fsmonitor !)
261 ? dir/c.o (fsmonitor !)
256 ? syntax
262 ? syntax
257
263
258 Check recursive glob pattern matches no directories (dir/**/c.o matches dir/c.o)
264 Check recursive glob pattern matches no directories (dir/**/c.o matches dir/c.o)
259
265
260 $ echo "syntax: glob" > .hgignore
266 $ echo "syntax: glob" > .hgignore
261 $ echo "dir/**/c.o" >> .hgignore
267 $ echo "dir/**/c.o" >> .hgignore
262 $ touch dir/c.o
268 $ touch dir/c.o
263 $ mkdir dir/subdir
269 $ mkdir dir/subdir
264 $ touch dir/subdir/c.o
270 $ touch dir/subdir/c.o
265 $ hg status
271 $ hg status
266 A dir/b.o
272 A dir/b.o
267 ? .hgignore
273 ? .hgignore
268 ? a.c
274 ? a.c
269 ? a.o
275 ? a.o
270 ? syntax
276 ? syntax
271 $ hg debugignore a.c
277 $ hg debugignore a.c
272 a.c is not ignored
278 a.c is not ignored
273 $ hg debugignore dir/c.o
279 $ hg debugignore dir/c.o
274 dir/c.o is ignored
280 dir/c.o is ignored
275 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 2: 'dir/**/c.o') (glob)
281 (ignore rule in $TESTTMP/ignorerepo/.hgignore, line 2: 'dir/**/c.o') (glob)
276
282
277 Check rooted globs
283 Check rooted globs
278
284
279 $ hg purge --all --config extensions.purge=
285 $ hg purge --all --config extensions.purge=
280 $ echo "syntax: rootglob" > .hgignore
286 $ echo "syntax: rootglob" > .hgignore
281 $ echo "a/*.ext" >> .hgignore
287 $ echo "a/*.ext" >> .hgignore
282 $ for p in a b/a aa; do mkdir -p $p; touch $p/b.ext; done
288 $ for p in a b/a aa; do mkdir -p $p; touch $p/b.ext; done
283 $ hg status -A 'set:**.ext'
289 $ hg status -A 'set:**.ext'
284 ? aa/b.ext
290 ? aa/b.ext
285 ? b/a/b.ext
291 ? b/a/b.ext
286 I a/b.ext
292 I a/b.ext
287
293
288 Check using 'include:' in ignore file
294 Check using 'include:' in ignore file
289
295
290 $ hg purge --all --config extensions.purge=
296 $ hg purge --all --config extensions.purge=
291 $ touch foo.included
297 $ touch foo.included
292
298
293 $ echo ".*.included" > otherignore
299 $ echo ".*.included" > otherignore
294 $ hg status -I "include:otherignore"
300 $ hg status -I "include:otherignore"
295 ? foo.included
301 ? foo.included
296
302
297 $ echo "include:otherignore" >> .hgignore
303 $ echo "include:otherignore" >> .hgignore
298 $ hg status
304 $ hg status
299 A dir/b.o
305 A dir/b.o
300 ? .hgignore
306 ? .hgignore
301 ? otherignore
307 ? otherignore
302
308
303 Check recursive uses of 'include:'
309 Check recursive uses of 'include:'
304
310
305 $ echo "include:nested/ignore" >> otherignore
311 $ echo "include:nested/ignore" >> otherignore
306 $ mkdir nested nested/more
312 $ mkdir nested nested/more
307 $ echo "glob:*ignore" > nested/ignore
313 $ echo "glob:*ignore" > nested/ignore
308 $ echo "rootglob:a" >> nested/ignore
314 $ echo "rootglob:a" >> nested/ignore
309 $ touch a nested/a nested/more/a
315 $ touch a nested/a nested/more/a
310 $ hg status
316 $ hg status
311 A dir/b.o
317 A dir/b.o
312 ? nested/a
318 ? nested/a
313 ? nested/more/a
319 ? nested/more/a
314 $ rm a nested/a nested/more/a
320 $ rm a nested/a nested/more/a
315
321
316 $ cp otherignore goodignore
322 $ cp otherignore goodignore
317 $ echo "include:badignore" >> otherignore
323 $ echo "include:badignore" >> otherignore
318 $ hg status
324 $ hg status
319 skipping unreadable pattern file 'badignore': $ENOENT$
325 skipping unreadable pattern file 'badignore': $ENOENT$
320 A dir/b.o
326 A dir/b.o
321
327
322 $ mv goodignore otherignore
328 $ mv goodignore otherignore
323
329
324 Check using 'include:' while in a non-root directory
330 Check using 'include:' while in a non-root directory
325
331
326 $ cd ..
332 $ cd ..
327 $ hg -R ignorerepo status
333 $ hg -R ignorerepo status
328 A dir/b.o
334 A dir/b.o
329 $ cd ignorerepo
335 $ cd ignorerepo
330
336
331 Check including subincludes
337 Check including subincludes
332
338
333 $ hg revert -q --all
339 $ hg revert -q --all
334 $ hg purge --all --config extensions.purge=
340 $ hg purge --all --config extensions.purge=
335 $ echo ".hgignore" > .hgignore
341 $ echo ".hgignore" > .hgignore
336 $ mkdir dir1 dir2
342 $ mkdir dir1 dir2
337 $ touch dir1/file1 dir1/file2 dir2/file1 dir2/file2
343 $ touch dir1/file1 dir1/file2 dir2/file1 dir2/file2
338 $ echo "subinclude:dir2/.hgignore" >> .hgignore
344 $ echo "subinclude:dir2/.hgignore" >> .hgignore
339 $ echo "glob:file*2" > dir2/.hgignore
345 $ echo "glob:file*2" > dir2/.hgignore
340 $ hg status
346 $ hg status
341 ? dir1/file1
347 ? dir1/file1
342 ? dir1/file2
348 ? dir1/file2
343 ? dir2/file1
349 ? dir2/file1
344
350
345 Check including subincludes with other patterns
351 Check including subincludes with other patterns
346
352
347 $ echo "subinclude:dir1/.hgignore" >> .hgignore
353 $ echo "subinclude:dir1/.hgignore" >> .hgignore
348
354
349 $ mkdir dir1/subdir
355 $ mkdir dir1/subdir
350 $ touch dir1/subdir/file1
356 $ touch dir1/subdir/file1
351 $ echo "rootglob:f?le1" > dir1/.hgignore
357 $ echo "rootglob:f?le1" > dir1/.hgignore
352 $ hg status
358 $ hg status
353 ? dir1/file2
359 ? dir1/file2
354 ? dir1/subdir/file1
360 ? dir1/subdir/file1
355 ? dir2/file1
361 ? dir2/file1
356 $ rm dir1/subdir/file1
362 $ rm dir1/subdir/file1
357
363
358 $ echo "regexp:f.le1" > dir1/.hgignore
364 $ echo "regexp:f.le1" > dir1/.hgignore
359 $ hg status
365 $ hg status
360 ? dir1/file2
366 ? dir1/file2
361 ? dir2/file1
367 ? dir2/file1
362
368
363 Check multiple levels of sub-ignores
369 Check multiple levels of sub-ignores
364
370
365 $ touch dir1/subdir/subfile1 dir1/subdir/subfile3 dir1/subdir/subfile4
371 $ touch dir1/subdir/subfile1 dir1/subdir/subfile3 dir1/subdir/subfile4
366 $ echo "subinclude:subdir/.hgignore" >> dir1/.hgignore
372 $ echo "subinclude:subdir/.hgignore" >> dir1/.hgignore
367 $ echo "glob:subfil*3" >> dir1/subdir/.hgignore
373 $ echo "glob:subfil*3" >> dir1/subdir/.hgignore
368
374
369 $ hg status
375 $ hg status
370 ? dir1/file2
376 ? dir1/file2
371 ? dir1/subdir/subfile4
377 ? dir1/subdir/subfile4
372 ? dir2/file1
378 ? dir2/file1
373
379
374 Check include subignore at the same level
380 Check include subignore at the same level
375
381
376 $ mv dir1/subdir/.hgignore dir1/.hgignoretwo
382 $ mv dir1/subdir/.hgignore dir1/.hgignoretwo
377 $ echo "regexp:f.le1" > dir1/.hgignore
383 $ echo "regexp:f.le1" > dir1/.hgignore
378 $ echo "subinclude:.hgignoretwo" >> dir1/.hgignore
384 $ echo "subinclude:.hgignoretwo" >> dir1/.hgignore
379 $ echo "glob:file*2" > dir1/.hgignoretwo
385 $ echo "glob:file*2" > dir1/.hgignoretwo
380
386
381 $ hg status | grep file2
387 $ hg status | grep file2
382 [1]
388 [1]
383 $ hg debugignore dir1/file2
389 $ hg debugignore dir1/file2
384 dir1/file2 is ignored
390 dir1/file2 is ignored
385 (ignore rule in dir2/.hgignore, line 1: 'file*2')
391 (ignore rule in dir2/.hgignore, line 1: 'file*2')
386
392
387 #if windows
393 #if windows
388
394
389 Windows paths are accepted on input
395 Windows paths are accepted on input
390
396
391 $ rm dir1/.hgignore
397 $ rm dir1/.hgignore
392 $ echo "dir1/file*" >> .hgignore
398 $ echo "dir1/file*" >> .hgignore
393 $ hg debugignore "dir1\file2"
399 $ hg debugignore "dir1\file2"
394 dir1/file2 is ignored
400 dir1/file2 is ignored
395 (ignore rule in $TESTTMP\ignorerepo\.hgignore, line 4: 'dir1/file*')
401 (ignore rule in $TESTTMP\ignorerepo\.hgignore, line 4: 'dir1/file*')
396 $ hg up -qC .
402 $ hg up -qC .
397
403
398 #endif
404 #endif
@@ -1,87 +1,93 b''
1 #require unix-permissions no-root reporevlogstore
1 #require unix-permissions no-root reporevlogstore
2
2
3 #testcases dirstate-v1 dirstate-v1-tree
3 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
4
4
5 #if dirstate-v1-tree
5 #if dirstate-v1-tree
6 #require rust
6 #require rust
7 $ echo '[experimental]' >> $HGRCPATH
7 $ echo '[experimental]' >> $HGRCPATH
8 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
8 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
9 #endif
9 #endif
10
10
11 #if dirstate-v2
12 #require rust
13 $ echo '[format]' >> $HGRCPATH
14 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
15 #endif
16
11 $ hg init t
17 $ hg init t
12 $ cd t
18 $ cd t
13
19
14 $ echo foo > a
20 $ echo foo > a
15 $ hg add a
21 $ hg add a
16
22
17 $ hg commit -m "1"
23 $ hg commit -m "1"
18
24
19 $ hg verify
25 $ hg verify
20 checking changesets
26 checking changesets
21 checking manifests
27 checking manifests
22 crosschecking files in changesets and manifests
28 crosschecking files in changesets and manifests
23 checking files
29 checking files
24 checked 1 changesets with 1 changes to 1 files
30 checked 1 changesets with 1 changes to 1 files
25
31
26 $ chmod -r .hg/store/data/a.i
32 $ chmod -r .hg/store/data/a.i
27
33
28 $ hg verify
34 $ hg verify
29 checking changesets
35 checking changesets
30 checking manifests
36 checking manifests
31 crosschecking files in changesets and manifests
37 crosschecking files in changesets and manifests
32 checking files
38 checking files
33 abort: Permission denied: '$TESTTMP/t/.hg/store/data/a.i'
39 abort: Permission denied: '$TESTTMP/t/.hg/store/data/a.i'
34 [255]
40 [255]
35
41
36 $ chmod +r .hg/store/data/a.i
42 $ chmod +r .hg/store/data/a.i
37
43
38 $ hg verify
44 $ hg verify
39 checking changesets
45 checking changesets
40 checking manifests
46 checking manifests
41 crosschecking files in changesets and manifests
47 crosschecking files in changesets and manifests
42 checking files
48 checking files
43 checked 1 changesets with 1 changes to 1 files
49 checked 1 changesets with 1 changes to 1 files
44
50
45 $ chmod -w .hg/store/data/a.i
51 $ chmod -w .hg/store/data/a.i
46
52
47 $ echo barber > a
53 $ echo barber > a
48 $ hg commit -m "2"
54 $ hg commit -m "2"
49 trouble committing a!
55 trouble committing a!
50 abort: Permission denied: '$TESTTMP/t/.hg/store/data/a.i'
56 abort: Permission denied: '$TESTTMP/t/.hg/store/data/a.i'
51 [255]
57 [255]
52
58
53 $ chmod -w .
59 $ chmod -w .
54
60
55 $ hg diff --nodates
61 $ hg diff --nodates
56 diff -r 2a18120dc1c9 a
62 diff -r 2a18120dc1c9 a
57 --- a/a
63 --- a/a
58 +++ b/a
64 +++ b/a
59 @@ -1,1 +1,1 @@
65 @@ -1,1 +1,1 @@
60 -foo
66 -foo
61 +barber
67 +barber
62
68
63 $ chmod +w .
69 $ chmod +w .
64
70
65 $ chmod +w .hg/store/data/a.i
71 $ chmod +w .hg/store/data/a.i
66 $ mkdir dir
72 $ mkdir dir
67 $ touch dir/a
73 $ touch dir/a
68 $ hg status
74 $ hg status
69 M a
75 M a
70 ? dir/a
76 ? dir/a
71 $ chmod -rx dir
77 $ chmod -rx dir
72
78
73 #if no-fsmonitor
79 #if no-fsmonitor
74
80
75 (fsmonitor makes "hg status" avoid accessing to "dir")
81 (fsmonitor makes "hg status" avoid accessing to "dir")
76
82
77 $ hg status
83 $ hg status
78 dir: Permission denied
84 dir: Permission denied
79 M a
85 M a
80
86
81 #endif
87 #endif
82
88
83 Reenable perm to allow deletion:
89 Reenable perm to allow deletion:
84
90
85 $ chmod +rx dir
91 $ chmod +rx dir
86
92
87 $ cd ..
93 $ cd ..
@@ -1,350 +1,356 b''
1 #testcases dirstate-v1 dirstate-v1-tree
1 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
2
2
3 #if dirstate-v1-tree
3 #if dirstate-v1-tree
4 #require rust
4 #require rust
5 $ echo '[experimental]' >> $HGRCPATH
5 $ echo '[experimental]' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
7 #endif
7 #endif
8
8
9 #if dirstate-v2
10 #require rust
11 $ echo '[format]' >> $HGRCPATH
12 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
13 #endif
14
9 init
15 init
10
16
11 $ hg init t
17 $ hg init t
12 $ cd t
18 $ cd t
13
19
14 setup
20 setup
15
21
16 $ echo r1 > r1
22 $ echo r1 > r1
17 $ hg ci -qAmr1 -d'0 0'
23 $ hg ci -qAmr1 -d'0 0'
18 $ mkdir directory
24 $ mkdir directory
19 $ echo r2 > directory/r2
25 $ echo r2 > directory/r2
20 $ hg ci -qAmr2 -d'1 0'
26 $ hg ci -qAmr2 -d'1 0'
21 $ echo 'ignored' > .hgignore
27 $ echo 'ignored' > .hgignore
22 $ hg ci -qAmr3 -d'2 0'
28 $ hg ci -qAmr3 -d'2 0'
23
29
24 purge without the extension
30 purge without the extension
25
31
26 $ hg st
32 $ hg st
27 $ touch foo
33 $ touch foo
28 $ hg purge
34 $ hg purge
29 permanently delete 1 unkown files? (yN) n
35 permanently delete 1 unkown files? (yN) n
30 abort: removal cancelled
36 abort: removal cancelled
31 [250]
37 [250]
32 $ hg st
38 $ hg st
33 ? foo
39 ? foo
34 $ hg purge --no-confirm
40 $ hg purge --no-confirm
35 $ hg st
41 $ hg st
36
42
37 now enabling the extension
43 now enabling the extension
38
44
39 $ cat <<EOF >> $HGRCPATH
45 $ cat <<EOF >> $HGRCPATH
40 > [extensions]
46 > [extensions]
41 > purge =
47 > purge =
42 > EOF
48 > EOF
43
49
44 delete an empty directory
50 delete an empty directory
45
51
46 $ mkdir empty_dir
52 $ mkdir empty_dir
47 $ hg purge -p -v
53 $ hg purge -p -v
48 empty_dir
54 empty_dir
49 $ hg purge --confirm
55 $ hg purge --confirm
50 permanently delete at least 1 empty directories? (yN) n
56 permanently delete at least 1 empty directories? (yN) n
51 abort: removal cancelled
57 abort: removal cancelled
52 [250]
58 [250]
53 $ hg purge -v
59 $ hg purge -v
54 removing directory empty_dir
60 removing directory empty_dir
55 $ ls -A
61 $ ls -A
56 .hg
62 .hg
57 .hgignore
63 .hgignore
58 directory
64 directory
59 r1
65 r1
60
66
61 delete an untracked directory
67 delete an untracked directory
62
68
63 $ mkdir untracked_dir
69 $ mkdir untracked_dir
64 $ touch untracked_dir/untracked_file1
70 $ touch untracked_dir/untracked_file1
65 $ touch untracked_dir/untracked_file2
71 $ touch untracked_dir/untracked_file2
66 $ hg purge -p
72 $ hg purge -p
67 untracked_dir/untracked_file1
73 untracked_dir/untracked_file1
68 untracked_dir/untracked_file2
74 untracked_dir/untracked_file2
69 $ hg purge -v
75 $ hg purge -v
70 removing file untracked_dir/untracked_file1
76 removing file untracked_dir/untracked_file1
71 removing file untracked_dir/untracked_file2
77 removing file untracked_dir/untracked_file2
72 removing directory untracked_dir
78 removing directory untracked_dir
73 $ ls -A
79 $ ls -A
74 .hg
80 .hg
75 .hgignore
81 .hgignore
76 directory
82 directory
77 r1
83 r1
78
84
79 delete an untracked file
85 delete an untracked file
80
86
81 $ touch untracked_file
87 $ touch untracked_file
82 $ touch untracked_file_readonly
88 $ touch untracked_file_readonly
83 $ "$PYTHON" <<EOF
89 $ "$PYTHON" <<EOF
84 > import os
90 > import os
85 > import stat
91 > import stat
86 > f = 'untracked_file_readonly'
92 > f = 'untracked_file_readonly'
87 > os.chmod(f, stat.S_IMODE(os.stat(f).st_mode) & ~stat.S_IWRITE)
93 > os.chmod(f, stat.S_IMODE(os.stat(f).st_mode) & ~stat.S_IWRITE)
88 > EOF
94 > EOF
89 $ hg purge -p
95 $ hg purge -p
90 untracked_file
96 untracked_file
91 untracked_file_readonly
97 untracked_file_readonly
92 $ hg purge --confirm
98 $ hg purge --confirm
93 permanently delete 2 unkown files? (yN) n
99 permanently delete 2 unkown files? (yN) n
94 abort: removal cancelled
100 abort: removal cancelled
95 [250]
101 [250]
96 $ hg purge -v
102 $ hg purge -v
97 removing file untracked_file
103 removing file untracked_file
98 removing file untracked_file_readonly
104 removing file untracked_file_readonly
99 $ ls -A
105 $ ls -A
100 .hg
106 .hg
101 .hgignore
107 .hgignore
102 directory
108 directory
103 r1
109 r1
104
110
105 delete an untracked file in a tracked directory
111 delete an untracked file in a tracked directory
106
112
107 $ touch directory/untracked_file
113 $ touch directory/untracked_file
108 $ hg purge -p
114 $ hg purge -p
109 directory/untracked_file
115 directory/untracked_file
110 $ hg purge -v
116 $ hg purge -v
111 removing file directory/untracked_file
117 removing file directory/untracked_file
112 $ ls -A
118 $ ls -A
113 .hg
119 .hg
114 .hgignore
120 .hgignore
115 directory
121 directory
116 r1
122 r1
117
123
118 delete nested directories
124 delete nested directories
119
125
120 $ mkdir -p untracked_directory/nested_directory
126 $ mkdir -p untracked_directory/nested_directory
121 $ hg purge -p
127 $ hg purge -p
122 untracked_directory/nested_directory
128 untracked_directory/nested_directory
123 $ hg purge -v
129 $ hg purge -v
124 removing directory untracked_directory/nested_directory
130 removing directory untracked_directory/nested_directory
125 removing directory untracked_directory
131 removing directory untracked_directory
126 $ ls -A
132 $ ls -A
127 .hg
133 .hg
128 .hgignore
134 .hgignore
129 directory
135 directory
130 r1
136 r1
131
137
132 delete nested directories from a subdir
138 delete nested directories from a subdir
133
139
134 $ mkdir -p untracked_directory/nested_directory
140 $ mkdir -p untracked_directory/nested_directory
135 $ cd directory
141 $ cd directory
136 $ hg purge -p
142 $ hg purge -p
137 untracked_directory/nested_directory
143 untracked_directory/nested_directory
138 $ hg purge -v
144 $ hg purge -v
139 removing directory untracked_directory/nested_directory
145 removing directory untracked_directory/nested_directory
140 removing directory untracked_directory
146 removing directory untracked_directory
141 $ cd ..
147 $ cd ..
142 $ ls -A
148 $ ls -A
143 .hg
149 .hg
144 .hgignore
150 .hgignore
145 directory
151 directory
146 r1
152 r1
147
153
148 delete only part of the tree
154 delete only part of the tree
149
155
150 $ mkdir -p untracked_directory/nested_directory
156 $ mkdir -p untracked_directory/nested_directory
151 $ touch directory/untracked_file
157 $ touch directory/untracked_file
152 $ cd directory
158 $ cd directory
153 $ hg purge -p ../untracked_directory
159 $ hg purge -p ../untracked_directory
154 untracked_directory/nested_directory
160 untracked_directory/nested_directory
155 $ hg purge --confirm
161 $ hg purge --confirm
156 permanently delete 1 unkown files? (yN) n
162 permanently delete 1 unkown files? (yN) n
157 abort: removal cancelled
163 abort: removal cancelled
158 [250]
164 [250]
159 $ hg purge -v ../untracked_directory
165 $ hg purge -v ../untracked_directory
160 removing directory untracked_directory/nested_directory
166 removing directory untracked_directory/nested_directory
161 removing directory untracked_directory
167 removing directory untracked_directory
162 $ cd ..
168 $ cd ..
163 $ ls -A
169 $ ls -A
164 .hg
170 .hg
165 .hgignore
171 .hgignore
166 directory
172 directory
167 r1
173 r1
168 $ ls directory/untracked_file
174 $ ls directory/untracked_file
169 directory/untracked_file
175 directory/untracked_file
170 $ rm directory/untracked_file
176 $ rm directory/untracked_file
171
177
172 skip ignored files if -i or --all not specified
178 skip ignored files if -i or --all not specified
173
179
174 $ touch ignored
180 $ touch ignored
175 $ hg purge -p
181 $ hg purge -p
176 $ hg purge --confirm
182 $ hg purge --confirm
177 $ hg purge -v
183 $ hg purge -v
178 $ touch untracked_file
184 $ touch untracked_file
179 $ ls
185 $ ls
180 directory
186 directory
181 ignored
187 ignored
182 r1
188 r1
183 untracked_file
189 untracked_file
184 $ hg purge -p -i
190 $ hg purge -p -i
185 ignored
191 ignored
186 $ hg purge --confirm -i
192 $ hg purge --confirm -i
187 permanently delete 1 ignored files? (yN) n
193 permanently delete 1 ignored files? (yN) n
188 abort: removal cancelled
194 abort: removal cancelled
189 [250]
195 [250]
190 $ hg purge -v -i
196 $ hg purge -v -i
191 removing file ignored
197 removing file ignored
192 $ ls -A
198 $ ls -A
193 .hg
199 .hg
194 .hgignore
200 .hgignore
195 directory
201 directory
196 r1
202 r1
197 untracked_file
203 untracked_file
198 $ touch ignored
204 $ touch ignored
199 $ hg purge -p --all
205 $ hg purge -p --all
200 ignored
206 ignored
201 untracked_file
207 untracked_file
202 $ hg purge --confirm --all
208 $ hg purge --confirm --all
203 permanently delete 1 unkown and 1 ignored files? (yN) n
209 permanently delete 1 unkown and 1 ignored files? (yN) n
204 abort: removal cancelled
210 abort: removal cancelled
205 [250]
211 [250]
206 $ hg purge -v --all
212 $ hg purge -v --all
207 removing file ignored
213 removing file ignored
208 removing file untracked_file
214 removing file untracked_file
209 $ ls
215 $ ls
210 directory
216 directory
211 r1
217 r1
212
218
213 abort with missing files until we support name mangling filesystems
219 abort with missing files until we support name mangling filesystems
214
220
215 $ touch untracked_file
221 $ touch untracked_file
216 $ rm r1
222 $ rm r1
217
223
218 hide error messages to avoid changing the output when the text changes
224 hide error messages to avoid changing the output when the text changes
219
225
220 $ hg purge -p 2> /dev/null
226 $ hg purge -p 2> /dev/null
221 untracked_file
227 untracked_file
222 $ hg st
228 $ hg st
223 ! r1
229 ! r1
224 ? untracked_file
230 ? untracked_file
225
231
226 $ hg purge -p
232 $ hg purge -p
227 untracked_file
233 untracked_file
228 $ hg purge -v 2> /dev/null
234 $ hg purge -v 2> /dev/null
229 removing file untracked_file
235 removing file untracked_file
230 $ hg st
236 $ hg st
231 ! r1
237 ! r1
232
238
233 $ hg purge -v
239 $ hg purge -v
234 $ hg revert --all --quiet
240 $ hg revert --all --quiet
235 $ hg st -a
241 $ hg st -a
236
242
237 tracked file in ignored directory (issue621)
243 tracked file in ignored directory (issue621)
238
244
239 $ echo directory >> .hgignore
245 $ echo directory >> .hgignore
240 $ hg ci -m 'ignore directory'
246 $ hg ci -m 'ignore directory'
241 $ touch untracked_file
247 $ touch untracked_file
242 $ hg purge -p
248 $ hg purge -p
243 untracked_file
249 untracked_file
244 $ hg purge -v
250 $ hg purge -v
245 removing file untracked_file
251 removing file untracked_file
246
252
247 skip excluded files
253 skip excluded files
248
254
249 $ touch excluded_file
255 $ touch excluded_file
250 $ hg purge -p -X excluded_file
256 $ hg purge -p -X excluded_file
251 $ hg purge -v -X excluded_file
257 $ hg purge -v -X excluded_file
252 $ ls -A
258 $ ls -A
253 .hg
259 .hg
254 .hgignore
260 .hgignore
255 directory
261 directory
256 excluded_file
262 excluded_file
257 r1
263 r1
258 $ rm excluded_file
264 $ rm excluded_file
259
265
260 skip files in excluded dirs
266 skip files in excluded dirs
261
267
262 $ mkdir excluded_dir
268 $ mkdir excluded_dir
263 $ touch excluded_dir/file
269 $ touch excluded_dir/file
264 $ hg purge -p -X excluded_dir
270 $ hg purge -p -X excluded_dir
265 $ hg purge -v -X excluded_dir
271 $ hg purge -v -X excluded_dir
266 $ ls -A
272 $ ls -A
267 .hg
273 .hg
268 .hgignore
274 .hgignore
269 directory
275 directory
270 excluded_dir
276 excluded_dir
271 r1
277 r1
272 $ ls excluded_dir
278 $ ls excluded_dir
273 file
279 file
274 $ rm -R excluded_dir
280 $ rm -R excluded_dir
275
281
276 skip excluded empty dirs
282 skip excluded empty dirs
277
283
278 $ mkdir excluded_dir
284 $ mkdir excluded_dir
279 $ hg purge -p -X excluded_dir
285 $ hg purge -p -X excluded_dir
280 $ hg purge -v -X excluded_dir
286 $ hg purge -v -X excluded_dir
281 $ ls -A
287 $ ls -A
282 .hg
288 .hg
283 .hgignore
289 .hgignore
284 directory
290 directory
285 excluded_dir
291 excluded_dir
286 r1
292 r1
287 $ rmdir excluded_dir
293 $ rmdir excluded_dir
288
294
289 skip patterns
295 skip patterns
290
296
291 $ mkdir .svn
297 $ mkdir .svn
292 $ touch .svn/foo
298 $ touch .svn/foo
293 $ mkdir directory/.svn
299 $ mkdir directory/.svn
294 $ touch directory/.svn/foo
300 $ touch directory/.svn/foo
295 $ hg purge -p -X .svn -X '*/.svn'
301 $ hg purge -p -X .svn -X '*/.svn'
296 $ hg purge -p -X re:.*.svn
302 $ hg purge -p -X re:.*.svn
297
303
298 $ rm -R .svn directory r1
304 $ rm -R .svn directory r1
299
305
300 only remove files
306 only remove files
301
307
302 $ mkdir -p empty_dir dir
308 $ mkdir -p empty_dir dir
303 $ touch untracked_file dir/untracked_file
309 $ touch untracked_file dir/untracked_file
304 $ hg purge -p --files
310 $ hg purge -p --files
305 dir/untracked_file
311 dir/untracked_file
306 untracked_file
312 untracked_file
307 $ hg purge -v --files
313 $ hg purge -v --files
308 removing file dir/untracked_file
314 removing file dir/untracked_file
309 removing file untracked_file
315 removing file untracked_file
310 $ ls -A
316 $ ls -A
311 .hg
317 .hg
312 .hgignore
318 .hgignore
313 dir
319 dir
314 empty_dir
320 empty_dir
315 $ ls dir
321 $ ls dir
316
322
317 only remove dirs
323 only remove dirs
318
324
319 $ mkdir -p empty_dir dir
325 $ mkdir -p empty_dir dir
320 $ touch untracked_file dir/untracked_file
326 $ touch untracked_file dir/untracked_file
321 $ hg purge -p --dirs
327 $ hg purge -p --dirs
322 empty_dir
328 empty_dir
323 $ hg purge -v --dirs
329 $ hg purge -v --dirs
324 removing directory empty_dir
330 removing directory empty_dir
325 $ ls -A
331 $ ls -A
326 .hg
332 .hg
327 .hgignore
333 .hgignore
328 dir
334 dir
329 untracked_file
335 untracked_file
330 $ ls dir
336 $ ls dir
331 untracked_file
337 untracked_file
332
338
333 remove both files and dirs
339 remove both files and dirs
334
340
335 $ mkdir -p empty_dir dir
341 $ mkdir -p empty_dir dir
336 $ touch untracked_file dir/untracked_file
342 $ touch untracked_file dir/untracked_file
337 $ hg purge -p --files --dirs
343 $ hg purge -p --files --dirs
338 dir/untracked_file
344 dir/untracked_file
339 untracked_file
345 untracked_file
340 empty_dir
346 empty_dir
341 $ hg purge -v --files --dirs
347 $ hg purge -v --files --dirs
342 removing file dir/untracked_file
348 removing file dir/untracked_file
343 removing file untracked_file
349 removing file untracked_file
344 removing directory empty_dir
350 removing directory empty_dir
345 removing directory dir
351 removing directory dir
346 $ ls -A
352 $ ls -A
347 .hg
353 .hg
348 .hgignore
354 .hgignore
349
355
350 $ cd ..
356 $ cd ..
@@ -1,871 +1,883 b''
1 #testcases dirstate-v1 dirstate-v1-tree
1 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
2
3 #if no-rust
4 $ hg init repo0 --config format.exp-dirstate-v2=1
5 abort: dirstate v2 format requested by config but not supported (requires Rust extensions)
6 [255]
7 #endif
2
8
3 #if dirstate-v1-tree
9 #if dirstate-v1-tree
4 #require rust
10 #require rust
5 $ echo '[experimental]' >> $HGRCPATH
11 $ echo '[experimental]' >> $HGRCPATH
6 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
12 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
7 #endif
13 #endif
8
14
15 #if dirstate-v2
16 #require rust
17 $ echo '[format]' >> $HGRCPATH
18 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
19 #endif
20
9 $ hg init repo1
21 $ hg init repo1
10 $ cd repo1
22 $ cd repo1
11 $ mkdir a b a/1 b/1 b/2
23 $ mkdir a b a/1 b/1 b/2
12 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
24 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
13
25
14 hg status in repo root:
26 hg status in repo root:
15
27
16 $ hg status
28 $ hg status
17 ? a/1/in_a_1
29 ? a/1/in_a_1
18 ? a/in_a
30 ? a/in_a
19 ? b/1/in_b_1
31 ? b/1/in_b_1
20 ? b/2/in_b_2
32 ? b/2/in_b_2
21 ? b/in_b
33 ? b/in_b
22 ? in_root
34 ? in_root
23
35
24 hg status . in repo root:
36 hg status . in repo root:
25
37
26 $ hg status .
38 $ hg status .
27 ? a/1/in_a_1
39 ? a/1/in_a_1
28 ? a/in_a
40 ? a/in_a
29 ? b/1/in_b_1
41 ? b/1/in_b_1
30 ? b/2/in_b_2
42 ? b/2/in_b_2
31 ? b/in_b
43 ? b/in_b
32 ? in_root
44 ? in_root
33
45
34 $ hg status --cwd a
46 $ hg status --cwd a
35 ? a/1/in_a_1
47 ? a/1/in_a_1
36 ? a/in_a
48 ? a/in_a
37 ? b/1/in_b_1
49 ? b/1/in_b_1
38 ? b/2/in_b_2
50 ? b/2/in_b_2
39 ? b/in_b
51 ? b/in_b
40 ? in_root
52 ? in_root
41 $ hg status --cwd a .
53 $ hg status --cwd a .
42 ? 1/in_a_1
54 ? 1/in_a_1
43 ? in_a
55 ? in_a
44 $ hg status --cwd a ..
56 $ hg status --cwd a ..
45 ? 1/in_a_1
57 ? 1/in_a_1
46 ? in_a
58 ? in_a
47 ? ../b/1/in_b_1
59 ? ../b/1/in_b_1
48 ? ../b/2/in_b_2
60 ? ../b/2/in_b_2
49 ? ../b/in_b
61 ? ../b/in_b
50 ? ../in_root
62 ? ../in_root
51
63
52 $ hg status --cwd b
64 $ hg status --cwd b
53 ? a/1/in_a_1
65 ? a/1/in_a_1
54 ? a/in_a
66 ? a/in_a
55 ? b/1/in_b_1
67 ? b/1/in_b_1
56 ? b/2/in_b_2
68 ? b/2/in_b_2
57 ? b/in_b
69 ? b/in_b
58 ? in_root
70 ? in_root
59 $ hg status --cwd b .
71 $ hg status --cwd b .
60 ? 1/in_b_1
72 ? 1/in_b_1
61 ? 2/in_b_2
73 ? 2/in_b_2
62 ? in_b
74 ? in_b
63 $ hg status --cwd b ..
75 $ hg status --cwd b ..
64 ? ../a/1/in_a_1
76 ? ../a/1/in_a_1
65 ? ../a/in_a
77 ? ../a/in_a
66 ? 1/in_b_1
78 ? 1/in_b_1
67 ? 2/in_b_2
79 ? 2/in_b_2
68 ? in_b
80 ? in_b
69 ? ../in_root
81 ? ../in_root
70
82
71 $ hg status --cwd a/1
83 $ hg status --cwd a/1
72 ? a/1/in_a_1
84 ? a/1/in_a_1
73 ? a/in_a
85 ? a/in_a
74 ? b/1/in_b_1
86 ? b/1/in_b_1
75 ? b/2/in_b_2
87 ? b/2/in_b_2
76 ? b/in_b
88 ? b/in_b
77 ? in_root
89 ? in_root
78 $ hg status --cwd a/1 .
90 $ hg status --cwd a/1 .
79 ? in_a_1
91 ? in_a_1
80 $ hg status --cwd a/1 ..
92 $ hg status --cwd a/1 ..
81 ? in_a_1
93 ? in_a_1
82 ? ../in_a
94 ? ../in_a
83
95
84 $ hg status --cwd b/1
96 $ hg status --cwd b/1
85 ? a/1/in_a_1
97 ? a/1/in_a_1
86 ? a/in_a
98 ? a/in_a
87 ? b/1/in_b_1
99 ? b/1/in_b_1
88 ? b/2/in_b_2
100 ? b/2/in_b_2
89 ? b/in_b
101 ? b/in_b
90 ? in_root
102 ? in_root
91 $ hg status --cwd b/1 .
103 $ hg status --cwd b/1 .
92 ? in_b_1
104 ? in_b_1
93 $ hg status --cwd b/1 ..
105 $ hg status --cwd b/1 ..
94 ? in_b_1
106 ? in_b_1
95 ? ../2/in_b_2
107 ? ../2/in_b_2
96 ? ../in_b
108 ? ../in_b
97
109
98 $ hg status --cwd b/2
110 $ hg status --cwd b/2
99 ? a/1/in_a_1
111 ? a/1/in_a_1
100 ? a/in_a
112 ? a/in_a
101 ? b/1/in_b_1
113 ? b/1/in_b_1
102 ? b/2/in_b_2
114 ? b/2/in_b_2
103 ? b/in_b
115 ? b/in_b
104 ? in_root
116 ? in_root
105 $ hg status --cwd b/2 .
117 $ hg status --cwd b/2 .
106 ? in_b_2
118 ? in_b_2
107 $ hg status --cwd b/2 ..
119 $ hg status --cwd b/2 ..
108 ? ../1/in_b_1
120 ? ../1/in_b_1
109 ? in_b_2
121 ? in_b_2
110 ? ../in_b
122 ? ../in_b
111
123
112 combining patterns with root and patterns without a root works
124 combining patterns with root and patterns without a root works
113
125
114 $ hg st a/in_a re:.*b$
126 $ hg st a/in_a re:.*b$
115 ? a/in_a
127 ? a/in_a
116 ? b/in_b
128 ? b/in_b
117
129
118 tweaking defaults works
130 tweaking defaults works
119 $ hg status --cwd a --config ui.tweakdefaults=yes
131 $ hg status --cwd a --config ui.tweakdefaults=yes
120 ? 1/in_a_1
132 ? 1/in_a_1
121 ? in_a
133 ? in_a
122 ? ../b/1/in_b_1
134 ? ../b/1/in_b_1
123 ? ../b/2/in_b_2
135 ? ../b/2/in_b_2
124 ? ../b/in_b
136 ? ../b/in_b
125 ? ../in_root
137 ? ../in_root
126 $ HGPLAIN=1 hg status --cwd a --config ui.tweakdefaults=yes
138 $ HGPLAIN=1 hg status --cwd a --config ui.tweakdefaults=yes
127 ? a/1/in_a_1 (glob)
139 ? a/1/in_a_1 (glob)
128 ? a/in_a (glob)
140 ? a/in_a (glob)
129 ? b/1/in_b_1 (glob)
141 ? b/1/in_b_1 (glob)
130 ? b/2/in_b_2 (glob)
142 ? b/2/in_b_2 (glob)
131 ? b/in_b (glob)
143 ? b/in_b (glob)
132 ? in_root
144 ? in_root
133 $ HGPLAINEXCEPT=tweakdefaults hg status --cwd a --config ui.tweakdefaults=yes
145 $ HGPLAINEXCEPT=tweakdefaults hg status --cwd a --config ui.tweakdefaults=yes
134 ? 1/in_a_1
146 ? 1/in_a_1
135 ? in_a
147 ? in_a
136 ? ../b/1/in_b_1
148 ? ../b/1/in_b_1
137 ? ../b/2/in_b_2
149 ? ../b/2/in_b_2
138 ? ../b/in_b
150 ? ../b/in_b
139 ? ../in_root (glob)
151 ? ../in_root (glob)
140
152
141 relative paths can be requested
153 relative paths can be requested
142
154
143 $ hg status --cwd a --config ui.relative-paths=yes
155 $ hg status --cwd a --config ui.relative-paths=yes
144 ? 1/in_a_1
156 ? 1/in_a_1
145 ? in_a
157 ? in_a
146 ? ../b/1/in_b_1
158 ? ../b/1/in_b_1
147 ? ../b/2/in_b_2
159 ? ../b/2/in_b_2
148 ? ../b/in_b
160 ? ../b/in_b
149 ? ../in_root
161 ? ../in_root
150
162
151 $ hg status --cwd a . --config ui.relative-paths=legacy
163 $ hg status --cwd a . --config ui.relative-paths=legacy
152 ? 1/in_a_1
164 ? 1/in_a_1
153 ? in_a
165 ? in_a
154 $ hg status --cwd a . --config ui.relative-paths=no
166 $ hg status --cwd a . --config ui.relative-paths=no
155 ? a/1/in_a_1
167 ? a/1/in_a_1
156 ? a/in_a
168 ? a/in_a
157
169
158 commands.status.relative overrides ui.relative-paths
170 commands.status.relative overrides ui.relative-paths
159
171
160 $ cat >> $HGRCPATH <<EOF
172 $ cat >> $HGRCPATH <<EOF
161 > [ui]
173 > [ui]
162 > relative-paths = False
174 > relative-paths = False
163 > [commands]
175 > [commands]
164 > status.relative = True
176 > status.relative = True
165 > EOF
177 > EOF
166 $ hg status --cwd a
178 $ hg status --cwd a
167 ? 1/in_a_1
179 ? 1/in_a_1
168 ? in_a
180 ? in_a
169 ? ../b/1/in_b_1
181 ? ../b/1/in_b_1
170 ? ../b/2/in_b_2
182 ? ../b/2/in_b_2
171 ? ../b/in_b
183 ? ../b/in_b
172 ? ../in_root
184 ? ../in_root
173 $ HGPLAIN=1 hg status --cwd a
185 $ HGPLAIN=1 hg status --cwd a
174 ? a/1/in_a_1 (glob)
186 ? a/1/in_a_1 (glob)
175 ? a/in_a (glob)
187 ? a/in_a (glob)
176 ? b/1/in_b_1 (glob)
188 ? b/1/in_b_1 (glob)
177 ? b/2/in_b_2 (glob)
189 ? b/2/in_b_2 (glob)
178 ? b/in_b (glob)
190 ? b/in_b (glob)
179 ? in_root
191 ? in_root
180
192
181 if relative paths are explicitly off, tweakdefaults doesn't change it
193 if relative paths are explicitly off, tweakdefaults doesn't change it
182 $ cat >> $HGRCPATH <<EOF
194 $ cat >> $HGRCPATH <<EOF
183 > [commands]
195 > [commands]
184 > status.relative = False
196 > status.relative = False
185 > EOF
197 > EOF
186 $ hg status --cwd a --config ui.tweakdefaults=yes
198 $ hg status --cwd a --config ui.tweakdefaults=yes
187 ? a/1/in_a_1
199 ? a/1/in_a_1
188 ? a/in_a
200 ? a/in_a
189 ? b/1/in_b_1
201 ? b/1/in_b_1
190 ? b/2/in_b_2
202 ? b/2/in_b_2
191 ? b/in_b
203 ? b/in_b
192 ? in_root
204 ? in_root
193
205
194 $ cd ..
206 $ cd ..
195
207
196 $ hg init repo2
208 $ hg init repo2
197 $ cd repo2
209 $ cd repo2
198 $ touch modified removed deleted ignored
210 $ touch modified removed deleted ignored
199 $ echo "^ignored$" > .hgignore
211 $ echo "^ignored$" > .hgignore
200 $ hg ci -A -m 'initial checkin'
212 $ hg ci -A -m 'initial checkin'
201 adding .hgignore
213 adding .hgignore
202 adding deleted
214 adding deleted
203 adding modified
215 adding modified
204 adding removed
216 adding removed
205 $ touch modified added unknown ignored
217 $ touch modified added unknown ignored
206 $ hg add added
218 $ hg add added
207 $ hg remove removed
219 $ hg remove removed
208 $ rm deleted
220 $ rm deleted
209
221
210 hg status:
222 hg status:
211
223
212 $ hg status
224 $ hg status
213 A added
225 A added
214 R removed
226 R removed
215 ! deleted
227 ! deleted
216 ? unknown
228 ? unknown
217
229
218 hg status modified added removed deleted unknown never-existed ignored:
230 hg status modified added removed deleted unknown never-existed ignored:
219
231
220 $ hg status modified added removed deleted unknown never-existed ignored
232 $ hg status modified added removed deleted unknown never-existed ignored
221 never-existed: * (glob)
233 never-existed: * (glob)
222 A added
234 A added
223 R removed
235 R removed
224 ! deleted
236 ! deleted
225 ? unknown
237 ? unknown
226
238
227 $ hg copy modified copied
239 $ hg copy modified copied
228
240
229 hg status -C:
241 hg status -C:
230
242
231 $ hg status -C
243 $ hg status -C
232 A added
244 A added
233 A copied
245 A copied
234 modified
246 modified
235 R removed
247 R removed
236 ! deleted
248 ! deleted
237 ? unknown
249 ? unknown
238
250
239 hg status -A:
251 hg status -A:
240
252
241 $ hg status -A
253 $ hg status -A
242 A added
254 A added
243 A copied
255 A copied
244 modified
256 modified
245 R removed
257 R removed
246 ! deleted
258 ! deleted
247 ? unknown
259 ? unknown
248 I ignored
260 I ignored
249 C .hgignore
261 C .hgignore
250 C modified
262 C modified
251
263
252 $ hg status -A -T '{status} {path} {node|shortest}\n'
264 $ hg status -A -T '{status} {path} {node|shortest}\n'
253 A added ffff
265 A added ffff
254 A copied ffff
266 A copied ffff
255 R removed ffff
267 R removed ffff
256 ! deleted ffff
268 ! deleted ffff
257 ? unknown ffff
269 ? unknown ffff
258 I ignored ffff
270 I ignored ffff
259 C .hgignore ffff
271 C .hgignore ffff
260 C modified ffff
272 C modified ffff
261
273
262 $ hg status -A -Tjson
274 $ hg status -A -Tjson
263 [
275 [
264 {
276 {
265 "itemtype": "file",
277 "itemtype": "file",
266 "path": "added",
278 "path": "added",
267 "status": "A"
279 "status": "A"
268 },
280 },
269 {
281 {
270 "itemtype": "file",
282 "itemtype": "file",
271 "path": "copied",
283 "path": "copied",
272 "source": "modified",
284 "source": "modified",
273 "status": "A"
285 "status": "A"
274 },
286 },
275 {
287 {
276 "itemtype": "file",
288 "itemtype": "file",
277 "path": "removed",
289 "path": "removed",
278 "status": "R"
290 "status": "R"
279 },
291 },
280 {
292 {
281 "itemtype": "file",
293 "itemtype": "file",
282 "path": "deleted",
294 "path": "deleted",
283 "status": "!"
295 "status": "!"
284 },
296 },
285 {
297 {
286 "itemtype": "file",
298 "itemtype": "file",
287 "path": "unknown",
299 "path": "unknown",
288 "status": "?"
300 "status": "?"
289 },
301 },
290 {
302 {
291 "itemtype": "file",
303 "itemtype": "file",
292 "path": "ignored",
304 "path": "ignored",
293 "status": "I"
305 "status": "I"
294 },
306 },
295 {
307 {
296 "itemtype": "file",
308 "itemtype": "file",
297 "path": ".hgignore",
309 "path": ".hgignore",
298 "status": "C"
310 "status": "C"
299 },
311 },
300 {
312 {
301 "itemtype": "file",
313 "itemtype": "file",
302 "path": "modified",
314 "path": "modified",
303 "status": "C"
315 "status": "C"
304 }
316 }
305 ]
317 ]
306
318
307 $ hg status -A -Tpickle > pickle
319 $ hg status -A -Tpickle > pickle
308 >>> from __future__ import print_function
320 >>> from __future__ import print_function
309 >>> from mercurial import util
321 >>> from mercurial import util
310 >>> pickle = util.pickle
322 >>> pickle = util.pickle
311 >>> data = sorted((x[b'status'].decode(), x[b'path'].decode()) for x in pickle.load(open("pickle", r"rb")))
323 >>> data = sorted((x[b'status'].decode(), x[b'path'].decode()) for x in pickle.load(open("pickle", r"rb")))
312 >>> for s, p in data: print("%s %s" % (s, p))
324 >>> for s, p in data: print("%s %s" % (s, p))
313 ! deleted
325 ! deleted
314 ? pickle
326 ? pickle
315 ? unknown
327 ? unknown
316 A added
328 A added
317 A copied
329 A copied
318 C .hgignore
330 C .hgignore
319 C modified
331 C modified
320 I ignored
332 I ignored
321 R removed
333 R removed
322 $ rm pickle
334 $ rm pickle
323
335
324 $ echo "^ignoreddir$" > .hgignore
336 $ echo "^ignoreddir$" > .hgignore
325 $ mkdir ignoreddir
337 $ mkdir ignoreddir
326 $ touch ignoreddir/file
338 $ touch ignoreddir/file
327
339
328 Test templater support:
340 Test templater support:
329
341
330 $ hg status -AT "[{status}]\t{if(source, '{source} -> ')}{path}\n"
342 $ hg status -AT "[{status}]\t{if(source, '{source} -> ')}{path}\n"
331 [M] .hgignore
343 [M] .hgignore
332 [A] added
344 [A] added
333 [A] modified -> copied
345 [A] modified -> copied
334 [R] removed
346 [R] removed
335 [!] deleted
347 [!] deleted
336 [?] ignored
348 [?] ignored
337 [?] unknown
349 [?] unknown
338 [I] ignoreddir/file
350 [I] ignoreddir/file
339 [C] modified
351 [C] modified
340 $ hg status -AT default
352 $ hg status -AT default
341 M .hgignore
353 M .hgignore
342 A added
354 A added
343 A copied
355 A copied
344 modified
356 modified
345 R removed
357 R removed
346 ! deleted
358 ! deleted
347 ? ignored
359 ? ignored
348 ? unknown
360 ? unknown
349 I ignoreddir/file
361 I ignoreddir/file
350 C modified
362 C modified
351 $ hg status -T compact
363 $ hg status -T compact
352 abort: "status" not in template map
364 abort: "status" not in template map
353 [255]
365 [255]
354
366
355 hg status ignoreddir/file:
367 hg status ignoreddir/file:
356
368
357 $ hg status ignoreddir/file
369 $ hg status ignoreddir/file
358
370
359 hg status -i ignoreddir/file:
371 hg status -i ignoreddir/file:
360
372
361 $ hg status -i ignoreddir/file
373 $ hg status -i ignoreddir/file
362 I ignoreddir/file
374 I ignoreddir/file
363 $ cd ..
375 $ cd ..
364
376
365 Check 'status -q' and some combinations
377 Check 'status -q' and some combinations
366
378
367 $ hg init repo3
379 $ hg init repo3
368 $ cd repo3
380 $ cd repo3
369 $ touch modified removed deleted ignored
381 $ touch modified removed deleted ignored
370 $ echo "^ignored$" > .hgignore
382 $ echo "^ignored$" > .hgignore
371 $ hg commit -A -m 'initial checkin'
383 $ hg commit -A -m 'initial checkin'
372 adding .hgignore
384 adding .hgignore
373 adding deleted
385 adding deleted
374 adding modified
386 adding modified
375 adding removed
387 adding removed
376 $ touch added unknown ignored
388 $ touch added unknown ignored
377 $ hg add added
389 $ hg add added
378 $ echo "test" >> modified
390 $ echo "test" >> modified
379 $ hg remove removed
391 $ hg remove removed
380 $ rm deleted
392 $ rm deleted
381 $ hg copy modified copied
393 $ hg copy modified copied
382
394
383 Specify working directory revision explicitly, that should be the same as
395 Specify working directory revision explicitly, that should be the same as
384 "hg status"
396 "hg status"
385
397
386 $ hg status --change "wdir()"
398 $ hg status --change "wdir()"
387 M modified
399 M modified
388 A added
400 A added
389 A copied
401 A copied
390 R removed
402 R removed
391 ! deleted
403 ! deleted
392 ? unknown
404 ? unknown
393
405
394 Run status with 2 different flags.
406 Run status with 2 different flags.
395 Check if result is the same or different.
407 Check if result is the same or different.
396 If result is not as expected, raise error
408 If result is not as expected, raise error
397
409
398 $ assert() {
410 $ assert() {
399 > hg status $1 > ../a
411 > hg status $1 > ../a
400 > hg status $2 > ../b
412 > hg status $2 > ../b
401 > if diff ../a ../b > /dev/null; then
413 > if diff ../a ../b > /dev/null; then
402 > out=0
414 > out=0
403 > else
415 > else
404 > out=1
416 > out=1
405 > fi
417 > fi
406 > if [ $3 -eq 0 ]; then
418 > if [ $3 -eq 0 ]; then
407 > df="same"
419 > df="same"
408 > else
420 > else
409 > df="different"
421 > df="different"
410 > fi
422 > fi
411 > if [ $out -ne $3 ]; then
423 > if [ $out -ne $3 ]; then
412 > echo "Error on $1 and $2, should be $df."
424 > echo "Error on $1 and $2, should be $df."
413 > fi
425 > fi
414 > }
426 > }
415
427
416 Assert flag1 flag2 [0-same | 1-different]
428 Assert flag1 flag2 [0-same | 1-different]
417
429
418 $ assert "-q" "-mard" 0
430 $ assert "-q" "-mard" 0
419 $ assert "-A" "-marduicC" 0
431 $ assert "-A" "-marduicC" 0
420 $ assert "-qA" "-mardcC" 0
432 $ assert "-qA" "-mardcC" 0
421 $ assert "-qAui" "-A" 0
433 $ assert "-qAui" "-A" 0
422 $ assert "-qAu" "-marducC" 0
434 $ assert "-qAu" "-marducC" 0
423 $ assert "-qAi" "-mardicC" 0
435 $ assert "-qAi" "-mardicC" 0
424 $ assert "-qu" "-u" 0
436 $ assert "-qu" "-u" 0
425 $ assert "-q" "-u" 1
437 $ assert "-q" "-u" 1
426 $ assert "-m" "-a" 1
438 $ assert "-m" "-a" 1
427 $ assert "-r" "-d" 1
439 $ assert "-r" "-d" 1
428 $ cd ..
440 $ cd ..
429
441
430 $ hg init repo4
442 $ hg init repo4
431 $ cd repo4
443 $ cd repo4
432 $ touch modified removed deleted
444 $ touch modified removed deleted
433 $ hg ci -q -A -m 'initial checkin'
445 $ hg ci -q -A -m 'initial checkin'
434 $ touch added unknown
446 $ touch added unknown
435 $ hg add added
447 $ hg add added
436 $ hg remove removed
448 $ hg remove removed
437 $ rm deleted
449 $ rm deleted
438 $ echo x > modified
450 $ echo x > modified
439 $ hg copy modified copied
451 $ hg copy modified copied
440 $ hg ci -m 'test checkin' -d "1000001 0"
452 $ hg ci -m 'test checkin' -d "1000001 0"
441 $ rm *
453 $ rm *
442 $ touch unrelated
454 $ touch unrelated
443 $ hg ci -q -A -m 'unrelated checkin' -d "1000002 0"
455 $ hg ci -q -A -m 'unrelated checkin' -d "1000002 0"
444
456
445 hg status --change 1:
457 hg status --change 1:
446
458
447 $ hg status --change 1
459 $ hg status --change 1
448 M modified
460 M modified
449 A added
461 A added
450 A copied
462 A copied
451 R removed
463 R removed
452
464
453 hg status --change 1 unrelated:
465 hg status --change 1 unrelated:
454
466
455 $ hg status --change 1 unrelated
467 $ hg status --change 1 unrelated
456
468
457 hg status -C --change 1 added modified copied removed deleted:
469 hg status -C --change 1 added modified copied removed deleted:
458
470
459 $ hg status -C --change 1 added modified copied removed deleted
471 $ hg status -C --change 1 added modified copied removed deleted
460 M modified
472 M modified
461 A added
473 A added
462 A copied
474 A copied
463 modified
475 modified
464 R removed
476 R removed
465
477
466 hg status -A --change 1 and revset:
478 hg status -A --change 1 and revset:
467
479
468 $ hg status -A --change '1|1'
480 $ hg status -A --change '1|1'
469 M modified
481 M modified
470 A added
482 A added
471 A copied
483 A copied
472 modified
484 modified
473 R removed
485 R removed
474 C deleted
486 C deleted
475
487
476 $ cd ..
488 $ cd ..
477
489
478 hg status with --rev and reverted changes:
490 hg status with --rev and reverted changes:
479
491
480 $ hg init reverted-changes-repo
492 $ hg init reverted-changes-repo
481 $ cd reverted-changes-repo
493 $ cd reverted-changes-repo
482 $ echo a > file
494 $ echo a > file
483 $ hg add file
495 $ hg add file
484 $ hg ci -m a
496 $ hg ci -m a
485 $ echo b > file
497 $ echo b > file
486 $ hg ci -m b
498 $ hg ci -m b
487
499
488 reverted file should appear clean
500 reverted file should appear clean
489
501
490 $ hg revert -r 0 .
502 $ hg revert -r 0 .
491 reverting file
503 reverting file
492 $ hg status -A --rev 0
504 $ hg status -A --rev 0
493 C file
505 C file
494
506
495 #if execbit
507 #if execbit
496 reverted file with changed flag should appear modified
508 reverted file with changed flag should appear modified
497
509
498 $ chmod +x file
510 $ chmod +x file
499 $ hg status -A --rev 0
511 $ hg status -A --rev 0
500 M file
512 M file
501
513
502 $ hg revert -r 0 .
514 $ hg revert -r 0 .
503 reverting file
515 reverting file
504
516
505 reverted and committed file with changed flag should appear modified
517 reverted and committed file with changed flag should appear modified
506
518
507 $ hg co -C .
519 $ hg co -C .
508 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
520 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
509 $ chmod +x file
521 $ chmod +x file
510 $ hg ci -m 'change flag'
522 $ hg ci -m 'change flag'
511 $ hg status -A --rev 1 --rev 2
523 $ hg status -A --rev 1 --rev 2
512 M file
524 M file
513 $ hg diff -r 1 -r 2
525 $ hg diff -r 1 -r 2
514
526
515 #endif
527 #endif
516
528
517 $ cd ..
529 $ cd ..
518
530
519 hg status of binary file starting with '\1\n', a separator for metadata:
531 hg status of binary file starting with '\1\n', a separator for metadata:
520
532
521 $ hg init repo5
533 $ hg init repo5
522 $ cd repo5
534 $ cd repo5
523 >>> open("010a", r"wb").write(b"\1\nfoo") and None
535 >>> open("010a", r"wb").write(b"\1\nfoo") and None
524 $ hg ci -q -A -m 'initial checkin'
536 $ hg ci -q -A -m 'initial checkin'
525 $ hg status -A
537 $ hg status -A
526 C 010a
538 C 010a
527
539
528 >>> open("010a", r"wb").write(b"\1\nbar") and None
540 >>> open("010a", r"wb").write(b"\1\nbar") and None
529 $ hg status -A
541 $ hg status -A
530 M 010a
542 M 010a
531 $ hg ci -q -m 'modify 010a'
543 $ hg ci -q -m 'modify 010a'
532 $ hg status -A --rev 0:1
544 $ hg status -A --rev 0:1
533 M 010a
545 M 010a
534
546
535 $ touch empty
547 $ touch empty
536 $ hg ci -q -A -m 'add another file'
548 $ hg ci -q -A -m 'add another file'
537 $ hg status -A --rev 1:2 010a
549 $ hg status -A --rev 1:2 010a
538 C 010a
550 C 010a
539
551
540 $ cd ..
552 $ cd ..
541
553
542 test "hg status" with "directory pattern" which matches against files
554 test "hg status" with "directory pattern" which matches against files
543 only known on target revision.
555 only known on target revision.
544
556
545 $ hg init repo6
557 $ hg init repo6
546 $ cd repo6
558 $ cd repo6
547
559
548 $ echo a > a.txt
560 $ echo a > a.txt
549 $ hg add a.txt
561 $ hg add a.txt
550 $ hg commit -m '#0'
562 $ hg commit -m '#0'
551 $ mkdir -p 1/2/3/4/5
563 $ mkdir -p 1/2/3/4/5
552 $ echo b > 1/2/3/4/5/b.txt
564 $ echo b > 1/2/3/4/5/b.txt
553 $ hg add 1/2/3/4/5/b.txt
565 $ hg add 1/2/3/4/5/b.txt
554 $ hg commit -m '#1'
566 $ hg commit -m '#1'
555
567
556 $ hg update -C 0 > /dev/null
568 $ hg update -C 0 > /dev/null
557 $ hg status -A
569 $ hg status -A
558 C a.txt
570 C a.txt
559
571
560 the directory matching against specified pattern should be removed,
572 the directory matching against specified pattern should be removed,
561 because directory existence prevents 'dirstate.walk()' from showing
573 because directory existence prevents 'dirstate.walk()' from showing
562 warning message about such pattern.
574 warning message about such pattern.
563
575
564 $ test ! -d 1
576 $ test ! -d 1
565 $ hg status -A --rev 1 1/2/3/4/5/b.txt
577 $ hg status -A --rev 1 1/2/3/4/5/b.txt
566 R 1/2/3/4/5/b.txt
578 R 1/2/3/4/5/b.txt
567 $ hg status -A --rev 1 1/2/3/4/5
579 $ hg status -A --rev 1 1/2/3/4/5
568 R 1/2/3/4/5/b.txt
580 R 1/2/3/4/5/b.txt
569 $ hg status -A --rev 1 1/2/3
581 $ hg status -A --rev 1 1/2/3
570 R 1/2/3/4/5/b.txt
582 R 1/2/3/4/5/b.txt
571 $ hg status -A --rev 1 1
583 $ hg status -A --rev 1 1
572 R 1/2/3/4/5/b.txt
584 R 1/2/3/4/5/b.txt
573
585
574 $ hg status --config ui.formatdebug=True --rev 1 1
586 $ hg status --config ui.formatdebug=True --rev 1 1
575 status = [
587 status = [
576 {
588 {
577 'itemtype': 'file',
589 'itemtype': 'file',
578 'path': '1/2/3/4/5/b.txt',
590 'path': '1/2/3/4/5/b.txt',
579 'status': 'R'
591 'status': 'R'
580 },
592 },
581 ]
593 ]
582
594
583 #if windows
595 #if windows
584 $ hg --config ui.slash=false status -A --rev 1 1
596 $ hg --config ui.slash=false status -A --rev 1 1
585 R 1\2\3\4\5\b.txt
597 R 1\2\3\4\5\b.txt
586 #endif
598 #endif
587
599
588 $ cd ..
600 $ cd ..
589
601
590 Status after move overwriting a file (issue4458)
602 Status after move overwriting a file (issue4458)
591 =================================================
603 =================================================
592
604
593
605
594 $ hg init issue4458
606 $ hg init issue4458
595 $ cd issue4458
607 $ cd issue4458
596 $ echo a > a
608 $ echo a > a
597 $ echo b > b
609 $ echo b > b
598 $ hg commit -Am base
610 $ hg commit -Am base
599 adding a
611 adding a
600 adding b
612 adding b
601
613
602
614
603 with --force
615 with --force
604
616
605 $ hg mv b --force a
617 $ hg mv b --force a
606 $ hg st --copies
618 $ hg st --copies
607 M a
619 M a
608 b
620 b
609 R b
621 R b
610 $ hg revert --all
622 $ hg revert --all
611 reverting a
623 reverting a
612 undeleting b
624 undeleting b
613 $ rm *.orig
625 $ rm *.orig
614
626
615 without force
627 without force
616
628
617 $ hg rm a
629 $ hg rm a
618 $ hg st --copies
630 $ hg st --copies
619 R a
631 R a
620 $ hg mv b a
632 $ hg mv b a
621 $ hg st --copies
633 $ hg st --copies
622 M a
634 M a
623 b
635 b
624 R b
636 R b
625
637
626 using ui.statuscopies setting
638 using ui.statuscopies setting
627 $ hg st --config ui.statuscopies=true
639 $ hg st --config ui.statuscopies=true
628 M a
640 M a
629 b
641 b
630 R b
642 R b
631 $ hg st --config ui.statuscopies=false
643 $ hg st --config ui.statuscopies=false
632 M a
644 M a
633 R b
645 R b
634 $ hg st --config ui.tweakdefaults=yes
646 $ hg st --config ui.tweakdefaults=yes
635 M a
647 M a
636 b
648 b
637 R b
649 R b
638
650
639 using log status template (issue5155)
651 using log status template (issue5155)
640 $ hg log -Tstatus -r 'wdir()' -C
652 $ hg log -Tstatus -r 'wdir()' -C
641 changeset: 2147483647:ffffffffffff
653 changeset: 2147483647:ffffffffffff
642 parent: 0:8c55c58b4c0e
654 parent: 0:8c55c58b4c0e
643 user: test
655 user: test
644 date: * (glob)
656 date: * (glob)
645 files:
657 files:
646 M a
658 M a
647 b
659 b
648 R b
660 R b
649
661
650 $ hg log -GTstatus -r 'wdir()' -C
662 $ hg log -GTstatus -r 'wdir()' -C
651 o changeset: 2147483647:ffffffffffff
663 o changeset: 2147483647:ffffffffffff
652 | parent: 0:8c55c58b4c0e
664 | parent: 0:8c55c58b4c0e
653 ~ user: test
665 ~ user: test
654 date: * (glob)
666 date: * (glob)
655 files:
667 files:
656 M a
668 M a
657 b
669 b
658 R b
670 R b
659
671
660
672
661 Other "bug" highlight, the revision status does not report the copy information.
673 Other "bug" highlight, the revision status does not report the copy information.
662 This is buggy behavior.
674 This is buggy behavior.
663
675
664 $ hg commit -m 'blah'
676 $ hg commit -m 'blah'
665 $ hg st --copies --change .
677 $ hg st --copies --change .
666 M a
678 M a
667 R b
679 R b
668
680
669 using log status template, the copy information is displayed correctly.
681 using log status template, the copy information is displayed correctly.
670 $ hg log -Tstatus -r. -C
682 $ hg log -Tstatus -r. -C
671 changeset: 1:6685fde43d21
683 changeset: 1:6685fde43d21
672 tag: tip
684 tag: tip
673 user: test
685 user: test
674 date: * (glob)
686 date: * (glob)
675 summary: blah
687 summary: blah
676 files:
688 files:
677 M a
689 M a
678 b
690 b
679 R b
691 R b
680
692
681
693
682 $ cd ..
694 $ cd ..
683
695
684 Make sure .hg doesn't show up even as a symlink
696 Make sure .hg doesn't show up even as a symlink
685
697
686 $ hg init repo0
698 $ hg init repo0
687 $ mkdir symlink-repo0
699 $ mkdir symlink-repo0
688 $ cd symlink-repo0
700 $ cd symlink-repo0
689 $ ln -s ../repo0/.hg
701 $ ln -s ../repo0/.hg
690 $ hg status
702 $ hg status
691
703
692 If the size hasn’t changed but mtime has, status needs to read the contents
704 If the size hasn’t changed but mtime has, status needs to read the contents
693 of the file to check whether it has changed
705 of the file to check whether it has changed
694
706
695 $ echo 1 > a
707 $ echo 1 > a
696 $ echo 1 > b
708 $ echo 1 > b
697 $ touch -t 200102030000 a b
709 $ touch -t 200102030000 a b
698 $ hg commit -Aqm '#0'
710 $ hg commit -Aqm '#0'
699 $ echo 2 > a
711 $ echo 2 > a
700 $ touch -t 200102040000 a b
712 $ touch -t 200102040000 a b
701 $ hg status
713 $ hg status
702 M a
714 M a
703
715
704 Asking specifically for the status of a deleted/removed file
716 Asking specifically for the status of a deleted/removed file
705
717
706 $ rm a
718 $ rm a
707 $ rm b
719 $ rm b
708 $ hg status a
720 $ hg status a
709 ! a
721 ! a
710 $ hg rm a
722 $ hg rm a
711 $ hg rm b
723 $ hg rm b
712 $ hg status a
724 $ hg status a
713 R a
725 R a
714 $ hg commit -qm '#1'
726 $ hg commit -qm '#1'
715 $ hg status a
727 $ hg status a
716 a: $ENOENT$
728 a: $ENOENT$
717
729
718 Check using include flag with pattern when status does not need to traverse
730 Check using include flag with pattern when status does not need to traverse
719 the working directory (issue6483)
731 the working directory (issue6483)
720
732
721 $ cd ..
733 $ cd ..
722 $ hg init issue6483
734 $ hg init issue6483
723 $ cd issue6483
735 $ cd issue6483
724 $ touch a.py b.rs
736 $ touch a.py b.rs
725 $ hg add a.py b.rs
737 $ hg add a.py b.rs
726 $ hg st -aI "*.py"
738 $ hg st -aI "*.py"
727 A a.py
739 A a.py
728
740
729 Also check exclude pattern
741 Also check exclude pattern
730
742
731 $ hg st -aX "*.rs"
743 $ hg st -aX "*.rs"
732 A a.py
744 A a.py
733
745
734 issue6335
746 issue6335
735 When a directory containing a tracked file gets symlinked, as of 5.8
747 When a directory containing a tracked file gets symlinked, as of 5.8
736 `hg st` only gives the correct answer about clean (or deleted) files
748 `hg st` only gives the correct answer about clean (or deleted) files
737 if also listing unknowns.
749 if also listing unknowns.
738 The tree-based dirstate and status algorithm fix this:
750 The tree-based dirstate and status algorithm fix this:
739
751
740 #if symlink no-dirstate-v1
752 #if symlink no-dirstate-v1
741
753
742 $ cd ..
754 $ cd ..
743 $ hg init issue6335
755 $ hg init issue6335
744 $ cd issue6335
756 $ cd issue6335
745 $ mkdir foo
757 $ mkdir foo
746 $ touch foo/a
758 $ touch foo/a
747 $ hg ci -Ama
759 $ hg ci -Ama
748 adding foo/a
760 adding foo/a
749 $ mv foo bar
761 $ mv foo bar
750 $ ln -s bar foo
762 $ ln -s bar foo
751 $ hg status
763 $ hg status
752 ! foo/a
764 ! foo/a
753 ? bar/a
765 ? bar/a
754 ? foo
766 ? foo
755
767
756 $ hg status -c # incorrect output with `dirstate-v1`
768 $ hg status -c # incorrect output with `dirstate-v1`
757 $ hg status -cu
769 $ hg status -cu
758 ? bar/a
770 ? bar/a
759 ? foo
771 ? foo
760 $ hg status -d # incorrect output with `dirstate-v1`
772 $ hg status -d # incorrect output with `dirstate-v1`
761 ! foo/a
773 ! foo/a
762 $ hg status -du
774 $ hg status -du
763 ! foo/a
775 ! foo/a
764 ? bar/a
776 ? bar/a
765 ? foo
777 ? foo
766
778
767 #endif
779 #endif
768
780
769
781
770 Create a repo with files in each possible status
782 Create a repo with files in each possible status
771
783
772 $ cd ..
784 $ cd ..
773 $ hg init repo7
785 $ hg init repo7
774 $ cd repo7
786 $ cd repo7
775 $ mkdir subdir
787 $ mkdir subdir
776 $ touch clean modified deleted removed
788 $ touch clean modified deleted removed
777 $ touch subdir/clean subdir/modified subdir/deleted subdir/removed
789 $ touch subdir/clean subdir/modified subdir/deleted subdir/removed
778 $ echo ignored > .hgignore
790 $ echo ignored > .hgignore
779 $ hg ci -Aqm '#0'
791 $ hg ci -Aqm '#0'
780 $ echo 1 > modified
792 $ echo 1 > modified
781 $ echo 1 > subdir/modified
793 $ echo 1 > subdir/modified
782 $ rm deleted
794 $ rm deleted
783 $ rm subdir/deleted
795 $ rm subdir/deleted
784 $ hg rm removed
796 $ hg rm removed
785 $ hg rm subdir/removed
797 $ hg rm subdir/removed
786 $ touch unknown ignored
798 $ touch unknown ignored
787 $ touch subdir/unknown subdir/ignored
799 $ touch subdir/unknown subdir/ignored
788
800
789 Check the output
801 Check the output
790
802
791 $ hg status
803 $ hg status
792 M modified
804 M modified
793 M subdir/modified
805 M subdir/modified
794 R removed
806 R removed
795 R subdir/removed
807 R subdir/removed
796 ! deleted
808 ! deleted
797 ! subdir/deleted
809 ! subdir/deleted
798 ? subdir/unknown
810 ? subdir/unknown
799 ? unknown
811 ? unknown
800
812
801 $ hg status -mard
813 $ hg status -mard
802 M modified
814 M modified
803 M subdir/modified
815 M subdir/modified
804 R removed
816 R removed
805 R subdir/removed
817 R subdir/removed
806 ! deleted
818 ! deleted
807 ! subdir/deleted
819 ! subdir/deleted
808
820
809 $ hg status -A
821 $ hg status -A
810 M modified
822 M modified
811 M subdir/modified
823 M subdir/modified
812 R removed
824 R removed
813 R subdir/removed
825 R subdir/removed
814 ! deleted
826 ! deleted
815 ! subdir/deleted
827 ! subdir/deleted
816 ? subdir/unknown
828 ? subdir/unknown
817 ? unknown
829 ? unknown
818 I ignored
830 I ignored
819 I subdir/ignored
831 I subdir/ignored
820 C .hgignore
832 C .hgignore
821 C clean
833 C clean
822 C subdir/clean
834 C subdir/clean
823
835
824 Note: `hg status some-name` creates a patternmatcher which is not supported
836 Note: `hg status some-name` creates a patternmatcher which is not supported
825 yet by the Rust implementation of status, but includematcher is supported.
837 yet by the Rust implementation of status, but includematcher is supported.
826 --include is used below for that reason
838 --include is used below for that reason
827
839
828 Remove a directory that contains tracked files
840 Remove a directory that contains tracked files
829
841
830 $ rm -r subdir
842 $ rm -r subdir
831 $ hg status --include subdir
843 $ hg status --include subdir
832 R subdir/removed
844 R subdir/removed
833 ! subdir/clean
845 ! subdir/clean
834 ! subdir/deleted
846 ! subdir/deleted
835 ! subdir/modified
847 ! subdir/modified
836
848
837 … and replace it by a file
849 … and replace it by a file
838
850
839 $ touch subdir
851 $ touch subdir
840 $ hg status --include subdir
852 $ hg status --include subdir
841 R subdir/removed
853 R subdir/removed
842 ! subdir/clean
854 ! subdir/clean
843 ! subdir/deleted
855 ! subdir/deleted
844 ! subdir/modified
856 ! subdir/modified
845 ? subdir
857 ? subdir
846
858
847 Replaced a deleted or removed file with a directory
859 Replaced a deleted or removed file with a directory
848
860
849 $ mkdir deleted removed
861 $ mkdir deleted removed
850 $ touch deleted/1 removed/1
862 $ touch deleted/1 removed/1
851 $ hg status --include deleted --include removed
863 $ hg status --include deleted --include removed
852 R removed
864 R removed
853 ! deleted
865 ! deleted
854 ? deleted/1
866 ? deleted/1
855 ? removed/1
867 ? removed/1
856 $ hg add removed/1
868 $ hg add removed/1
857 $ hg status --include deleted --include removed
869 $ hg status --include deleted --include removed
858 A removed/1
870 A removed/1
859 R removed
871 R removed
860 ! deleted
872 ! deleted
861 ? deleted/1
873 ? deleted/1
862
874
863 Deeply nested files in an ignored directory are still listed on request
875 Deeply nested files in an ignored directory are still listed on request
864
876
865 $ echo ignored-dir >> .hgignore
877 $ echo ignored-dir >> .hgignore
866 $ mkdir ignored-dir
878 $ mkdir ignored-dir
867 $ mkdir ignored-dir/subdir
879 $ mkdir ignored-dir/subdir
868 $ touch ignored-dir/subdir/1
880 $ touch ignored-dir/subdir/1
869 $ hg status --ignored
881 $ hg status --ignored
870 I ignored
882 I ignored
871 I ignored-dir/subdir/1
883 I ignored-dir/subdir/1
@@ -1,283 +1,289 b''
1 #require symlink
1 #require symlink
2
2
3 #testcases dirstate-v1 dirstate-v1-tree
3 #testcases dirstate-v1 dirstate-v1-tree dirstate-v2
4
4
5 #if dirstate-v1-tree
5 #if dirstate-v1-tree
6 #require rust
6 #require rust
7 $ echo '[experimental]' >> $HGRCPATH
7 $ echo '[experimental]' >> $HGRCPATH
8 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
8 $ echo 'dirstate-tree.in-memory=1' >> $HGRCPATH
9 #endif
9 #endif
10
10
11 #if dirstate-v2
12 #require rust
13 $ echo '[format]' >> $HGRCPATH
14 $ echo 'exp-dirstate-v2=1' >> $HGRCPATH
15 #endif
16
11 == tests added in 0.7 ==
17 == tests added in 0.7 ==
12
18
13 $ hg init test-symlinks-0.7; cd test-symlinks-0.7;
19 $ hg init test-symlinks-0.7; cd test-symlinks-0.7;
14 $ touch foo; ln -s foo bar; ln -s nonexistent baz
20 $ touch foo; ln -s foo bar; ln -s nonexistent baz
15
21
16 import with add and addremove -- symlink walking should _not_ screwup.
22 import with add and addremove -- symlink walking should _not_ screwup.
17
23
18 $ hg add
24 $ hg add
19 adding bar
25 adding bar
20 adding baz
26 adding baz
21 adding foo
27 adding foo
22 $ hg forget bar baz foo
28 $ hg forget bar baz foo
23 $ hg addremove
29 $ hg addremove
24 adding bar
30 adding bar
25 adding baz
31 adding baz
26 adding foo
32 adding foo
27
33
28 commit -- the symlink should _not_ appear added to dir state
34 commit -- the symlink should _not_ appear added to dir state
29
35
30 $ hg commit -m 'initial'
36 $ hg commit -m 'initial'
31
37
32 $ touch bomb
38 $ touch bomb
33
39
34 again, symlink should _not_ show up on dir state
40 again, symlink should _not_ show up on dir state
35
41
36 $ hg addremove
42 $ hg addremove
37 adding bomb
43 adding bomb
38
44
39 Assert screamed here before, should go by without consequence
45 Assert screamed here before, should go by without consequence
40
46
41 $ hg commit -m 'is there a bug?'
47 $ hg commit -m 'is there a bug?'
42 $ cd ..
48 $ cd ..
43
49
44
50
45 == fifo & ignore ==
51 == fifo & ignore ==
46
52
47 $ hg init test; cd test;
53 $ hg init test; cd test;
48
54
49 $ mkdir dir
55 $ mkdir dir
50 $ touch a.c dir/a.o dir/b.o
56 $ touch a.c dir/a.o dir/b.o
51
57
52 test what happens if we want to trick hg
58 test what happens if we want to trick hg
53
59
54 $ hg commit -A -m 0
60 $ hg commit -A -m 0
55 adding a.c
61 adding a.c
56 adding dir/a.o
62 adding dir/a.o
57 adding dir/b.o
63 adding dir/b.o
58 $ echo "relglob:*.o" > .hgignore
64 $ echo "relglob:*.o" > .hgignore
59 $ rm a.c
65 $ rm a.c
60 $ rm dir/a.o
66 $ rm dir/a.o
61 $ rm dir/b.o
67 $ rm dir/b.o
62 $ mkdir dir/a.o
68 $ mkdir dir/a.o
63 $ ln -s nonexistent dir/b.o
69 $ ln -s nonexistent dir/b.o
64 $ mkfifo a.c
70 $ mkfifo a.c
65
71
66 it should show a.c, dir/a.o and dir/b.o deleted
72 it should show a.c, dir/a.o and dir/b.o deleted
67
73
68 $ hg status
74 $ hg status
69 M dir/b.o
75 M dir/b.o
70 ! a.c
76 ! a.c
71 ! dir/a.o
77 ! dir/a.o
72 ? .hgignore
78 ? .hgignore
73 $ hg status a.c
79 $ hg status a.c
74 a.c: unsupported file type (type is fifo)
80 a.c: unsupported file type (type is fifo)
75 ! a.c
81 ! a.c
76 $ cd ..
82 $ cd ..
77
83
78
84
79 == symlinks from outside the tree ==
85 == symlinks from outside the tree ==
80
86
81 test absolute path through symlink outside repo
87 test absolute path through symlink outside repo
82
88
83 $ p=`pwd`
89 $ p=`pwd`
84 $ hg init x
90 $ hg init x
85 $ ln -s x y
91 $ ln -s x y
86 $ cd x
92 $ cd x
87 $ touch f
93 $ touch f
88 $ hg add f
94 $ hg add f
89 $ hg status "$p"/y/f
95 $ hg status "$p"/y/f
90 A f
96 A f
91
97
92 try symlink outside repo to file inside
98 try symlink outside repo to file inside
93
99
94 $ ln -s x/f ../z
100 $ ln -s x/f ../z
95
101
96 this should fail
102 this should fail
97
103
98 $ hg status ../z && { echo hg mistakenly exited with status 0; exit 1; } || :
104 $ hg status ../z && { echo hg mistakenly exited with status 0; exit 1; } || :
99 abort: ../z not under root '$TESTTMP/x'
105 abort: ../z not under root '$TESTTMP/x'
100 $ cd ..
106 $ cd ..
101
107
102
108
103 == cloning symlinks ==
109 == cloning symlinks ==
104 $ hg init clone; cd clone;
110 $ hg init clone; cd clone;
105
111
106 try cloning symlink in a subdir
112 try cloning symlink in a subdir
107 1. commit a symlink
113 1. commit a symlink
108
114
109 $ mkdir -p a/b/c
115 $ mkdir -p a/b/c
110 $ cd a/b/c
116 $ cd a/b/c
111 $ ln -s /path/to/symlink/source demo
117 $ ln -s /path/to/symlink/source demo
112 $ cd ../../..
118 $ cd ../../..
113 $ hg stat
119 $ hg stat
114 ? a/b/c/demo
120 ? a/b/c/demo
115 $ hg commit -A -m 'add symlink in a/b/c subdir'
121 $ hg commit -A -m 'add symlink in a/b/c subdir'
116 adding a/b/c/demo
122 adding a/b/c/demo
117
123
118 2. clone it
124 2. clone it
119
125
120 $ cd ..
126 $ cd ..
121 $ hg clone clone clonedest
127 $ hg clone clone clonedest
122 updating to branch default
128 updating to branch default
123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
124
130
125
131
126 == symlink and git diffs ==
132 == symlink and git diffs ==
127
133
128 git symlink diff
134 git symlink diff
129
135
130 $ cd clonedest
136 $ cd clonedest
131 $ hg diff --git -r null:tip
137 $ hg diff --git -r null:tip
132 diff --git a/a/b/c/demo b/a/b/c/demo
138 diff --git a/a/b/c/demo b/a/b/c/demo
133 new file mode 120000
139 new file mode 120000
134 --- /dev/null
140 --- /dev/null
135 +++ b/a/b/c/demo
141 +++ b/a/b/c/demo
136 @@ -0,0 +1,1 @@
142 @@ -0,0 +1,1 @@
137 +/path/to/symlink/source
143 +/path/to/symlink/source
138 \ No newline at end of file
144 \ No newline at end of file
139 $ hg export --git tip > ../sl.diff
145 $ hg export --git tip > ../sl.diff
140
146
141 import git symlink diff
147 import git symlink diff
142
148
143 $ hg rm a/b/c/demo
149 $ hg rm a/b/c/demo
144 $ hg commit -m'remove link'
150 $ hg commit -m'remove link'
145 $ hg import ../sl.diff
151 $ hg import ../sl.diff
146 applying ../sl.diff
152 applying ../sl.diff
147 $ hg diff --git -r 1:tip
153 $ hg diff --git -r 1:tip
148 diff --git a/a/b/c/demo b/a/b/c/demo
154 diff --git a/a/b/c/demo b/a/b/c/demo
149 new file mode 120000
155 new file mode 120000
150 --- /dev/null
156 --- /dev/null
151 +++ b/a/b/c/demo
157 +++ b/a/b/c/demo
152 @@ -0,0 +1,1 @@
158 @@ -0,0 +1,1 @@
153 +/path/to/symlink/source
159 +/path/to/symlink/source
154 \ No newline at end of file
160 \ No newline at end of file
155
161
156 == symlinks and addremove ==
162 == symlinks and addremove ==
157
163
158 directory moved and symlinked
164 directory moved and symlinked
159
165
160 $ mkdir foo
166 $ mkdir foo
161 $ touch foo/a
167 $ touch foo/a
162 $ hg ci -Ama
168 $ hg ci -Ama
163 adding foo/a
169 adding foo/a
164 $ mv foo bar
170 $ mv foo bar
165 $ ln -s bar foo
171 $ ln -s bar foo
166 $ hg status
172 $ hg status
167 ! foo/a
173 ! foo/a
168 ? bar/a
174 ? bar/a
169 ? foo
175 ? foo
170
176
171 now addremove should remove old files
177 now addremove should remove old files
172
178
173 $ hg addremove
179 $ hg addremove
174 adding bar/a
180 adding bar/a
175 adding foo
181 adding foo
176 removing foo/a
182 removing foo/a
177
183
178 commit and update back
184 commit and update back
179
185
180 $ hg ci -mb
186 $ hg ci -mb
181 $ hg up '.^'
187 $ hg up '.^'
182 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
188 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
183 $ hg up tip
189 $ hg up tip
184 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
190 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
185
191
186 $ cd ..
192 $ cd ..
187
193
188 == root of repository is symlinked ==
194 == root of repository is symlinked ==
189
195
190 $ hg init root
196 $ hg init root
191 $ ln -s root link
197 $ ln -s root link
192 $ cd root
198 $ cd root
193 $ echo foo > foo
199 $ echo foo > foo
194 $ hg status
200 $ hg status
195 ? foo
201 ? foo
196 $ hg status ../link
202 $ hg status ../link
197 ? foo
203 ? foo
198 $ hg add foo
204 $ hg add foo
199 $ hg cp foo "$TESTTMP/link/bar"
205 $ hg cp foo "$TESTTMP/link/bar"
200 foo has not been committed yet, so no copy data will be stored for bar.
206 foo has not been committed yet, so no copy data will be stored for bar.
201 $ cd ..
207 $ cd ..
202
208
203
209
204 $ hg init b
210 $ hg init b
205 $ cd b
211 $ cd b
206 $ ln -s nothing dangling
212 $ ln -s nothing dangling
207 $ hg commit -m 'commit symlink without adding' dangling
213 $ hg commit -m 'commit symlink without adding' dangling
208 abort: dangling: file not tracked!
214 abort: dangling: file not tracked!
209 [10]
215 [10]
210 $ hg add dangling
216 $ hg add dangling
211 $ hg commit -m 'add symlink'
217 $ hg commit -m 'add symlink'
212
218
213 $ hg tip -v
219 $ hg tip -v
214 changeset: 0:cabd88b706fc
220 changeset: 0:cabd88b706fc
215 tag: tip
221 tag: tip
216 user: test
222 user: test
217 date: Thu Jan 01 00:00:00 1970 +0000
223 date: Thu Jan 01 00:00:00 1970 +0000
218 files: dangling
224 files: dangling
219 description:
225 description:
220 add symlink
226 add symlink
221
227
222
228
223 $ hg manifest --debug
229 $ hg manifest --debug
224 2564acbe54bbbedfbf608479340b359f04597f80 644 @ dangling
230 2564acbe54bbbedfbf608479340b359f04597f80 644 @ dangling
225 $ readlink.py dangling
231 $ readlink.py dangling
226 dangling -> nothing
232 dangling -> nothing
227
233
228 $ rm dangling
234 $ rm dangling
229 $ ln -s void dangling
235 $ ln -s void dangling
230 $ hg commit -m 'change symlink'
236 $ hg commit -m 'change symlink'
231 $ readlink.py dangling
237 $ readlink.py dangling
232 dangling -> void
238 dangling -> void
233
239
234
240
235 modifying link
241 modifying link
236
242
237 $ rm dangling
243 $ rm dangling
238 $ ln -s empty dangling
244 $ ln -s empty dangling
239 $ readlink.py dangling
245 $ readlink.py dangling
240 dangling -> empty
246 dangling -> empty
241
247
242
248
243 reverting to rev 0:
249 reverting to rev 0:
244
250
245 $ hg revert -r 0 -a
251 $ hg revert -r 0 -a
246 reverting dangling
252 reverting dangling
247 $ readlink.py dangling
253 $ readlink.py dangling
248 dangling -> nothing
254 dangling -> nothing
249
255
250
256
251 backups:
257 backups:
252
258
253 $ readlink.py *.orig
259 $ readlink.py *.orig
254 dangling.orig -> empty
260 dangling.orig -> empty
255 $ rm *.orig
261 $ rm *.orig
256 $ hg up -C
262 $ hg up -C
257 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
258
264
259 copies
265 copies
260
266
261 $ hg cp -v dangling dangling2
267 $ hg cp -v dangling dangling2
262 copying dangling to dangling2
268 copying dangling to dangling2
263 $ hg st -Cmard
269 $ hg st -Cmard
264 A dangling2
270 A dangling2
265 dangling
271 dangling
266 $ readlink.py dangling dangling2
272 $ readlink.py dangling dangling2
267 dangling -> void
273 dangling -> void
268 dangling2 -> void
274 dangling2 -> void
269
275
270
276
271 Issue995: hg copy -A incorrectly handles symbolic links
277 Issue995: hg copy -A incorrectly handles symbolic links
272
278
273 $ hg up -C
279 $ hg up -C
274 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 $ mkdir dir
281 $ mkdir dir
276 $ ln -s dir dirlink
282 $ ln -s dir dirlink
277 $ hg ci -qAm 'add dirlink'
283 $ hg ci -qAm 'add dirlink'
278 $ mkdir newdir
284 $ mkdir newdir
279 $ mv dir newdir/dir
285 $ mv dir newdir/dir
280 $ mv dirlink newdir/dirlink
286 $ mv dirlink newdir/dirlink
281 $ hg mv -A dirlink newdir/dirlink
287 $ hg mv -A dirlink newdir/dirlink
282
288
283 $ cd ..
289 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now