##// END OF EJS Templates
narrowspec: limit patterns to path: and rootfilesin: (BC)...
Gregory Szorc -
r39567:0d572769 default
parent child Browse files
Show More
@@ -1,198 +1,241
1 1 # narrowspec.py - methods for working with a narrow view of a repository
2 2 #
3 3 # Copyright 2017 Google, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import errno
11 11
12 12 from .i18n import _
13 13 from . import (
14 14 error,
15 15 match as matchmod,
16 16 repository,
17 17 sparse,
18 18 util,
19 19 )
20 20
21 21 FILENAME = 'narrowspec'
22 22
23 # Pattern prefixes that are allowed in narrow patterns. This list MUST
24 # only contain patterns that are fast and safe to evaluate. Keep in mind
25 # that patterns are supplied by clients and executed on remote servers
26 # as part of wire protocol commands.
27 VALID_PREFIXES = (
28 b'path:',
29 b'rootfilesin:',
30 )
31
23 32 def parseserverpatterns(text):
24 33 """Parses the narrowspec format that's returned by the server."""
25 34 includepats = set()
26 35 excludepats = set()
27 36
28 37 # We get one entry per line, in the format "<key> <value>".
29 38 # It's OK for value to contain other spaces.
30 39 for kp in (l.split(' ', 1) for l in text.splitlines()):
31 40 if len(kp) != 2:
32 41 raise error.Abort(_('Invalid narrowspec pattern line: "%s"') % kp)
33 42 key = kp[0]
34 43 pat = kp[1]
35 44 if key == 'include':
36 45 includepats.add(pat)
37 46 elif key == 'exclude':
38 47 excludepats.add(pat)
39 48 else:
40 49 raise error.Abort(_('Invalid key "%s" in server response') % key)
41 50
42 51 return includepats, excludepats
43 52
44 53 def normalizesplitpattern(kind, pat):
45 54 """Returns the normalized version of a pattern and kind.
46 55
47 56 Returns a tuple with the normalized kind and normalized pattern.
48 57 """
49 58 pat = pat.rstrip('/')
50 59 _validatepattern(pat)
51 60 return kind, pat
52 61
53 62 def _numlines(s):
54 63 """Returns the number of lines in s, including ending empty lines."""
55 64 # We use splitlines because it is Unicode-friendly and thus Python 3
56 65 # compatible. However, it does not count empty lines at the end, so trick
57 66 # it by adding a character at the end.
58 67 return len((s + 'x').splitlines())
59 68
60 69 def _validatepattern(pat):
61 70 """Validates the pattern and aborts if it is invalid.
62 71
63 72 Patterns are stored in the narrowspec as newline-separated
64 73 POSIX-style bytestring paths. There's no escaping.
65 74 """
66 75
67 76 # We use newlines as separators in the narrowspec file, so don't allow them
68 77 # in patterns.
69 78 if _numlines(pat) > 1:
70 79 raise error.Abort(_('newlines are not allowed in narrowspec paths'))
71 80
72 81 components = pat.split('/')
73 82 if '.' in components or '..' in components:
74 83 raise error.Abort(_('"." and ".." are not allowed in narrowspec paths'))
75 84
76 85 def normalizepattern(pattern, defaultkind='path'):
77 86 """Returns the normalized version of a text-format pattern.
78 87
79 88 If the pattern has no kind, the default will be added.
80 89 """
81 90 kind, pat = matchmod._patsplit(pattern, defaultkind)
82 91 return '%s:%s' % normalizesplitpattern(kind, pat)
83 92
84 93 def parsepatterns(pats):
85 """Parses a list of patterns into a typed pattern set."""
86 return set(normalizepattern(p) for p in pats)
94 """Parses an iterable of patterns into a typed pattern set.
95
96 Patterns are assumed to be ``path:`` if no prefix is present.
97 For safety and performance reasons, only some prefixes are allowed.
98 See ``validatepatterns()``.
99
100 This function should be used on patterns that come from the user to
101 normalize and validate them to the internal data structure used for
102 representing patterns.
103 """
104 res = {normalizepattern(orig) for orig in pats}
105 validatepatterns(res)
106 return res
107
108 def validatepatterns(pats):
109 """Validate that patterns are in the expected data structure and format.
110
111 And that is a set of normalized patterns beginning with ``path:`` or
112 ``rootfilesin:``.
113
114 This function should be used to validate internal data structures
115 and patterns that are loaded from sources that use the internal,
116 prefixed pattern representation (but can't necessarily be fully trusted).
117 """
118 if not isinstance(pats, set):
119 raise error.ProgrammingError('narrow patterns should be a set; '
120 'got %r' % pats)
121
122 for pat in pats:
123 if not pat.startswith(VALID_PREFIXES):
124 # Use a Mercurial exception because this can happen due to user
125 # bugs (e.g. manually updating spec file).
126 raise error.Abort(_('invalid prefix on narrow pattern: %s') % pat,
127 hint=_('narrow patterns must begin with one of '
128 'the following: %s') %
129 ', '.join(VALID_PREFIXES))
87 130
88 131 def format(includes, excludes):
89 132 output = '[include]\n'
90 133 for i in sorted(includes - excludes):
91 134 output += i + '\n'
92 135 output += '[exclude]\n'
93 136 for e in sorted(excludes):
94 137 output += e + '\n'
95 138 return output
96 139
97 140 def match(root, include=None, exclude=None):
98 141 if not include:
99 142 # Passing empty include and empty exclude to matchmod.match()
100 143 # gives a matcher that matches everything, so explicitly use
101 144 # the nevermatcher.
102 145 return matchmod.never(root, '')
103 146 return matchmod.match(root, '', [], include=include or [],
104 147 exclude=exclude or [])
105 148
106 149 def needsexpansion(includes):
107 150 return [i for i in includes if i.startswith('include:')]
108 151
109 152 def load(repo):
110 153 try:
111 154 spec = repo.svfs.read(FILENAME)
112 155 except IOError as e:
113 156 # Treat "narrowspec does not exist" the same as "narrowspec file exists
114 157 # and is empty".
115 158 if e.errno == errno.ENOENT:
116 159 return set(), set()
117 160 raise
118 161 # maybe we should care about the profiles returned too
119 162 includepats, excludepats, profiles = sparse.parseconfig(repo.ui, spec,
120 163 'narrow')
121 164 if profiles:
122 165 raise error.Abort(_("including other spec files using '%include' is not"
123 166 " supported in narrowspec"))
124 167 return includepats, excludepats
125 168
126 169 def save(repo, includepats, excludepats):
127 170 spec = format(includepats, excludepats)
128 171 repo.svfs.write(FILENAME, spec)
129 172
130 173 def savebackup(repo, backupname):
131 174 if repository.NARROW_REQUIREMENT not in repo.requirements:
132 175 return
133 176 vfs = repo.vfs
134 177 vfs.tryunlink(backupname)
135 178 util.copyfile(repo.svfs.join(FILENAME), vfs.join(backupname), hardlink=True)
136 179
137 180 def restorebackup(repo, backupname):
138 181 if repository.NARROW_REQUIREMENT not in repo.requirements:
139 182 return
140 183 util.rename(repo.vfs.join(backupname), repo.svfs.join(FILENAME))
141 184
142 185 def clearbackup(repo, backupname):
143 186 if repository.NARROW_REQUIREMENT not in repo.requirements:
144 187 return
145 188 repo.vfs.unlink(backupname)
146 189
147 190 def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes):
148 191 r""" Restricts the patterns according to repo settings,
149 192 results in a logical AND operation
150 193
151 194 :param req_includes: requested includes
152 195 :param req_excludes: requested excludes
153 196 :param repo_includes: repo includes
154 197 :param repo_excludes: repo excludes
155 198 :return: include patterns, exclude patterns, and invalid include patterns.
156 199
157 200 >>> restrictpatterns({'f1','f2'}, {}, ['f1'], [])
158 201 (set(['f1']), {}, [])
159 202 >>> restrictpatterns({'f1'}, {}, ['f1','f2'], [])
160 203 (set(['f1']), {}, [])
161 204 >>> restrictpatterns({'f1/fc1', 'f3/fc3'}, {}, ['f1','f2'], [])
162 205 (set(['f1/fc1']), {}, [])
163 206 >>> restrictpatterns({'f1_fc1'}, {}, ['f1','f2'], [])
164 207 ([], set(['path:.']), [])
165 208 >>> restrictpatterns({'f1/../f2/fc2'}, {}, ['f1','f2'], [])
166 209 (set(['f2/fc2']), {}, [])
167 210 >>> restrictpatterns({'f1/../f3/fc3'}, {}, ['f1','f2'], [])
168 211 ([], set(['path:.']), [])
169 212 >>> restrictpatterns({'f1/$non_exitent_var'}, {}, ['f1','f2'], [])
170 213 (set(['f1/$non_exitent_var']), {}, [])
171 214 """
172 215 res_excludes = set(req_excludes)
173 216 res_excludes.update(repo_excludes)
174 217 invalid_includes = []
175 218 if not req_includes:
176 219 res_includes = set(repo_includes)
177 220 elif 'path:.' not in repo_includes:
178 221 res_includes = []
179 222 for req_include in req_includes:
180 223 req_include = util.expandpath(util.normpath(req_include))
181 224 if req_include in repo_includes:
182 225 res_includes.append(req_include)
183 226 continue
184 227 valid = False
185 228 for repo_include in repo_includes:
186 229 if req_include.startswith(repo_include + '/'):
187 230 valid = True
188 231 res_includes.append(req_include)
189 232 break
190 233 if not valid:
191 234 invalid_includes.append(req_include)
192 235 if len(res_includes) == 0:
193 236 res_excludes = {'path:.'}
194 237 else:
195 238 res_includes = set(res_includes)
196 239 else:
197 240 res_includes = set(req_includes)
198 241 return res_includes, res_excludes, invalid_includes
@@ -1,256 +1,284
1 1 $ . "$TESTDIR/narrow-library.sh"
2 2
3 3 $ hg init master
4 4 $ cd master
5 5 $ cat >> .hg/hgrc <<EOF
6 6 > [narrow]
7 7 > serveellipses=True
8 8 > EOF
9 9 $ mkdir dir
10 10 $ mkdir dir/src
11 11 $ cd dir/src
12 12 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "f$x"; hg add "f$x"; hg commit -m "Commit src $x"; done
13 13 $ cd ..
14 14 $ mkdir tests
15 15 $ cd tests
16 16 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "t$x"; hg add "t$x"; hg commit -m "Commit test $x"; done
17 17 $ cd ../../..
18 18
19 Only path: and rootfilesin: pattern prefixes are allowed
20
21 $ hg clone --narrow ssh://user@dummy/master badnarrow --noupdate --include 'glob:**'
22 requesting all changes
23 abort: invalid prefix on narrow pattern: glob:**
24 (narrow patterns must begin with one of the following: path:, rootfilesin:)
25 [255]
26
27 $ hg clone --narrow ssh://user@dummy/master badnarrow --noupdate --exclude 'set:ignored'
28 requesting all changes
29 abort: invalid prefix on narrow pattern: set:ignored
30 (narrow patterns must begin with one of the following: path:, rootfilesin:)
31 [255]
32
19 33 narrow clone a file, f10
20 34
21 35 $ hg clone --narrow ssh://user@dummy/master narrow --noupdate --include "dir/src/f10"
22 36 requesting all changes
23 37 adding changesets
24 38 adding manifests
25 39 adding file changes
26 40 added 3 changesets with 1 changes to 1 files
27 41 new changesets *:* (glob)
28 42 $ cd narrow
29 43 $ cat .hg/requires | grep -v generaldelta
30 44 dotencode
31 45 fncache
32 46 narrowhg-experimental
33 47 revlogv1
34 48 store
35 49 testonly-simplestore (reposimplestore !)
36 50
37 51 $ hg tracked
38 52 I path:dir/src/f10
39 53 $ hg tracked
40 54 I path:dir/src/f10
41 55 $ hg update
42 56 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 57 $ find * | sort
44 58 dir
45 59 dir/src
46 60 dir/src/f10
47 61 $ cat dir/src/f10
48 62 10
49 63
50 64 $ cd ..
51 65
52 66 narrow clone with a newline should fail
53 67
54 68 $ hg clone --narrow ssh://user@dummy/master narrow_fail --noupdate --include 'dir/src/f10
55 69 > '
56 70 requesting all changes
57 71 abort: newlines are not allowed in narrowspec paths
58 72 [255]
59 73
60 74 narrow clone a directory, tests/, except tests/t19
61 75
62 76 $ hg clone --narrow ssh://user@dummy/master narrowdir --noupdate --include "dir/tests/" --exclude "dir/tests/t19"
63 77 requesting all changes
64 78 adding changesets
65 79 adding manifests
66 80 adding file changes
67 81 added 21 changesets with 19 changes to 19 files
68 82 new changesets *:* (glob)
69 83 $ cd narrowdir
70 84 $ hg tracked
71 85 I path:dir/tests
72 86 X path:dir/tests/t19
73 87 $ hg tracked
74 88 I path:dir/tests
75 89 X path:dir/tests/t19
76 90 $ hg update
77 91 19 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 92 $ find * | sort
79 93 dir
80 94 dir/tests
81 95 dir/tests/t1
82 96 dir/tests/t10
83 97 dir/tests/t11
84 98 dir/tests/t12
85 99 dir/tests/t13
86 100 dir/tests/t14
87 101 dir/tests/t15
88 102 dir/tests/t16
89 103 dir/tests/t17
90 104 dir/tests/t18
91 105 dir/tests/t2
92 106 dir/tests/t20
93 107 dir/tests/t3
94 108 dir/tests/t4
95 109 dir/tests/t5
96 110 dir/tests/t6
97 111 dir/tests/t7
98 112 dir/tests/t8
99 113 dir/tests/t9
100 114
101 115 $ cd ..
102 116
103 117 narrow clone everything but a directory (tests/)
104 118
105 119 $ hg clone --narrow ssh://user@dummy/master narrowroot --noupdate --exclude "dir/tests"
106 120 requesting all changes
107 121 adding changesets
108 122 adding manifests
109 123 adding file changes
110 124 added 21 changesets with 20 changes to 20 files
111 125 new changesets *:* (glob)
112 126 $ cd narrowroot
113 127 $ hg tracked
114 128 I path:.
115 129 X path:dir/tests
116 130 $ hg tracked
117 131 I path:.
118 132 X path:dir/tests
119 133 $ hg update
120 134 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 135 $ find * | sort
122 136 dir
123 137 dir/src
124 138 dir/src/f1
125 139 dir/src/f10
126 140 dir/src/f11
127 141 dir/src/f12
128 142 dir/src/f13
129 143 dir/src/f14
130 144 dir/src/f15
131 145 dir/src/f16
132 146 dir/src/f17
133 147 dir/src/f18
134 148 dir/src/f19
135 149 dir/src/f2
136 150 dir/src/f20
137 151 dir/src/f3
138 152 dir/src/f4
139 153 dir/src/f5
140 154 dir/src/f6
141 155 dir/src/f7
142 156 dir/src/f8
143 157 dir/src/f9
144 158
145 159 $ cd ..
146 160
147 161 narrow clone no paths at all
148 162
149 163 $ hg clone --narrow ssh://user@dummy/master narrowempty --noupdate
150 164 requesting all changes
151 165 adding changesets
152 166 adding manifests
153 167 adding file changes
154 168 added 1 changesets with 0 changes to 0 files
155 169 new changesets * (glob)
156 170 $ cd narrowempty
157 171 $ hg tracked
158 172 $ hg update
159 173 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 174 $ ls
161 175
162 176 $ cd ..
163 177
164 178 simple clone
165 179 $ hg clone ssh://user@dummy/master simpleclone
166 180 requesting all changes
167 181 adding changesets
168 182 adding manifests
169 183 adding file changes
170 184 added 40 changesets with 40 changes to 40 files
171 185 new changesets * (glob)
172 186 updating to branch default
173 187 40 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 188 $ cd simpleclone
175 189 $ find * | sort
176 190 dir
177 191 dir/src
178 192 dir/src/f1
179 193 dir/src/f10
180 194 dir/src/f11
181 195 dir/src/f12
182 196 dir/src/f13
183 197 dir/src/f14
184 198 dir/src/f15
185 199 dir/src/f16
186 200 dir/src/f17
187 201 dir/src/f18
188 202 dir/src/f19
189 203 dir/src/f2
190 204 dir/src/f20
191 205 dir/src/f3
192 206 dir/src/f4
193 207 dir/src/f5
194 208 dir/src/f6
195 209 dir/src/f7
196 210 dir/src/f8
197 211 dir/src/f9
198 212 dir/tests
199 213 dir/tests/t1
200 214 dir/tests/t10
201 215 dir/tests/t11
202 216 dir/tests/t12
203 217 dir/tests/t13
204 218 dir/tests/t14
205 219 dir/tests/t15
206 220 dir/tests/t16
207 221 dir/tests/t17
208 222 dir/tests/t18
209 223 dir/tests/t19
210 224 dir/tests/t2
211 225 dir/tests/t20
212 226 dir/tests/t3
213 227 dir/tests/t4
214 228 dir/tests/t5
215 229 dir/tests/t6
216 230 dir/tests/t7
217 231 dir/tests/t8
218 232 dir/tests/t9
219 233
220 234 $ cd ..
221 235
222 236 Testing the --narrowspec flag to clone
223 237
224 238 $ cat >> narrowspecs <<EOF
225 239 > %include foo
226 240 > [include]
227 241 > path:dir/tests/
228 242 > dir/src/f12
229 243 > EOF
230 244
231 245 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
232 246 reading narrowspec from '$TESTTMP/narrowspecs'
233 247 abort: cannot specify other files using '%include' in narrowspec
234 248 [255]
235 249
236 250 $ cat > narrowspecs <<EOF
237 251 > [include]
238 252 > path:dir/tests/
239 253 > file:dir/src/f12
240 254 > EOF
241 255
242 256 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
243 257 reading narrowspec from '$TESTTMP/narrowspecs'
244 258 requesting all changes
245 259 adding changesets
246 260 adding manifests
247 261 adding file changes
248 262 added 21 changesets with 20 changes to 20 files
249 263 new changesets f93383bb3e99:26ce255d5b5d
250 264 updating to branch default
251 265 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 266 $ cd specfile
253 267 $ hg tracked
254 268 I path:dir/tests
255 269 I path:file:dir/src/f12
256 270 $ cd ..
271
272 Narrow spec with invalid patterns is rejected
273
274 $ cat > narrowspecs <<EOF
275 > [include]
276 > glob:**
277 > EOF
278
279 $ hg clone ssh://user@dummy/master badspecfile --narrowspec narrowspecs
280 reading narrowspec from '$TESTTMP/narrowspecs'
281 requesting all changes
282 abort: invalid prefix on narrow pattern: glob:**
283 (narrow patterns must begin with one of the following: path:, rootfilesin:)
284 [255]
@@ -1,429 +1,441
1 1 $ . "$TESTDIR/narrow-library.sh"
2 2
3 3 initialize nested directories to validate complex include/exclude patterns
4 4
5 5 $ hg init master
6 6 $ cd master
7 7 $ cat >> .hg/hgrc <<EOF
8 8 > [narrow]
9 9 > serveellipses=True
10 10 > EOF
11 11
12 12 $ echo root > root
13 13 $ hg add root
14 14 $ hg commit -m 'add root'
15 15
16 16 $ for d in dir1 dir2 dir1/dirA dir1/dirB dir2/dirA dir2/dirB
17 17 > do
18 18 > mkdir -p $d
19 19 > echo $d/foo > $d/foo
20 20 > hg add $d/foo
21 21 > hg commit -m "add $d/foo"
22 22 > echo $d/bar > $d/bar
23 23 > hg add $d/bar
24 24 > hg commit -m "add $d/bar"
25 25 > done
26 26 #if execbit
27 27 $ chmod +x dir1/dirA/foo
28 28 $ hg commit -m "make dir1/dirA/foo executable"
29 29 #else
30 30 $ hg import --bypass - <<EOF
31 31 > # HG changeset patch
32 32 > make dir1/dirA/foo executable
33 33 >
34 34 > diff --git a/dir1/dirA/foo b/dir1/dirA/foo
35 35 > old mode 100644
36 36 > new mode 100755
37 37 > EOF
38 38 applying patch from stdin
39 39 $ hg update -qr tip
40 40 #endif
41 41 $ hg log -G -T '{rev} {node|short} {files}\n'
42 42 @ 13 c87ca422d521 dir1/dirA/foo
43 43 |
44 44 o 12 951b8a83924e dir2/dirB/bar
45 45 |
46 46 o 11 01ae5a51b563 dir2/dirB/foo
47 47 |
48 48 o 10 5eababdf0ac5 dir2/dirA/bar
49 49 |
50 50 o 9 99d690663739 dir2/dirA/foo
51 51 |
52 52 o 8 8e80155d5445 dir1/dirB/bar
53 53 |
54 54 o 7 406760310428 dir1/dirB/foo
55 55 |
56 56 o 6 623466a5f475 dir1/dirA/bar
57 57 |
58 58 o 5 06ff3a5be997 dir1/dirA/foo
59 59 |
60 60 o 4 33227af02764 dir2/bar
61 61 |
62 62 o 3 5e1f9d8d7c69 dir2/foo
63 63 |
64 64 o 2 594bc4b13d4a dir1/bar
65 65 |
66 66 o 1 47f480a08324 dir1/foo
67 67 |
68 68 o 0 2a4f0c3b67da root
69 69
70 70 $ cd ..
71 71
72 72 clone a narrow portion of the master, such that we can widen it later
73 73
74 74 $ hg clone --narrow ssh://user@dummy/master narrow \
75 75 > --include dir1 \
76 76 > --include dir2 \
77 77 > --exclude dir1/dirA \
78 78 > --exclude dir1/dirB \
79 79 > --exclude dir2/dirA \
80 80 > --exclude dir2/dirB
81 81 requesting all changes
82 82 adding changesets
83 83 adding manifests
84 84 adding file changes
85 85 added 6 changesets with 4 changes to 4 files
86 86 new changesets *:* (glob)
87 87 updating to branch default
88 88 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 89
90 90 $ cd narrow
91 91 $ hg tracked
92 92 I path:dir1
93 93 I path:dir2
94 94 X path:dir1/dirA
95 95 X path:dir1/dirB
96 96 X path:dir2/dirA
97 97 X path:dir2/dirB
98 98 $ hg manifest -r tip
99 99 dir1/bar
100 100 dir1/dirA/bar
101 101 dir1/dirA/foo
102 102 dir1/dirB/bar
103 103 dir1/dirB/foo
104 104 dir1/foo
105 105 dir2/bar
106 106 dir2/dirA/bar
107 107 dir2/dirA/foo
108 108 dir2/dirB/bar
109 109 dir2/dirB/foo
110 110 dir2/foo
111 111 root
112 112 $ find * | sort
113 113 dir1
114 114 dir1/bar
115 115 dir1/foo
116 116 dir2
117 117 dir2/bar
118 118 dir2/foo
119 119 $ hg log -G -T '{rev} {node|short}{if(ellipsis, "...")} {files}\n'
120 120 @ 5 c87ca422d521... dir1/dirA/foo
121 121 |
122 122 o 4 33227af02764 dir2/bar
123 123 |
124 124 o 3 5e1f9d8d7c69 dir2/foo
125 125 |
126 126 o 2 594bc4b13d4a dir1/bar
127 127 |
128 128 o 1 47f480a08324 dir1/foo
129 129 |
130 130 o 0 2a4f0c3b67da... root
131 131
132 132
133 133 widen the narrow checkout
134 134
135 135 $ hg tracked --removeexclude dir1/dirA
136 136 comparing with ssh://user@dummy/master
137 137 searching for changes
138 138 no changes found
139 139 saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-widen.hg (glob)
140 140 adding changesets
141 141 adding manifests
142 142 adding file changes
143 143 added 9 changesets with 6 changes to 6 files
144 144 new changesets *:* (glob)
145 145 $ hg tracked
146 146 I path:dir1
147 147 I path:dir2
148 148 X path:dir1/dirB
149 149 X path:dir2/dirA
150 150 X path:dir2/dirB
151 151 $ find * | sort
152 152 dir1
153 153 dir1/bar
154 154 dir1/dirA
155 155 dir1/dirA/bar
156 156 dir1/dirA/foo
157 157 dir1/foo
158 158 dir2
159 159 dir2/bar
160 160 dir2/foo
161 161
162 162 #if execbit
163 163 $ test -x dir1/dirA/foo && echo executable
164 164 executable
165 165 $ test -x dir1/dirA/bar || echo not executable
166 166 not executable
167 167 #endif
168 168
169 169 $ hg log -G -T '{rev} {node|short}{if(ellipsis, "...")} {files}\n'
170 170 @ 8 c87ca422d521 dir1/dirA/foo
171 171 |
172 172 o 7 951b8a83924e... dir2/dirB/bar
173 173 |
174 174 o 6 623466a5f475 dir1/dirA/bar
175 175 |
176 176 o 5 06ff3a5be997 dir1/dirA/foo
177 177 |
178 178 o 4 33227af02764 dir2/bar
179 179 |
180 180 o 3 5e1f9d8d7c69 dir2/foo
181 181 |
182 182 o 2 594bc4b13d4a dir1/bar
183 183 |
184 184 o 1 47f480a08324 dir1/foo
185 185 |
186 186 o 0 2a4f0c3b67da... root
187 187
188 188
189 189 widen narrow spec again, but exclude a file in previously included spec
190 190
191 191 $ hg tracked --removeexclude dir2/dirB --addexclude dir1/dirA/bar
192 192 comparing with ssh://user@dummy/master
193 193 searching for changes
194 194 looking for local changes to affected paths
195 195 deleting data/dir1/dirA/bar.i (reporevlogstore !)
196 196 deleting data/dir1/dirA/bar/0eca1d0cbdaea4651d1d04d71976a6d2d9bfaae5 (reposimplestore !)
197 197 deleting data/dir1/dirA/bar/index (reposimplestore !)
198 198 no changes found
199 199 saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-widen.hg (glob)
200 200 adding changesets
201 201 adding manifests
202 202 adding file changes
203 203 added 11 changesets with 7 changes to 7 files
204 204 new changesets *:* (glob)
205 205 $ hg tracked
206 206 I path:dir1
207 207 I path:dir2
208 208 X path:dir1/dirA/bar
209 209 X path:dir1/dirB
210 210 X path:dir2/dirA
211 211 $ find * | sort
212 212 dir1
213 213 dir1/bar
214 214 dir1/dirA
215 215 dir1/dirA/foo
216 216 dir1/foo
217 217 dir2
218 218 dir2/bar
219 219 dir2/dirB
220 220 dir2/dirB/bar
221 221 dir2/dirB/foo
222 222 dir2/foo
223 223 $ hg log -G -T '{rev} {node|short}{if(ellipsis, "...")} {files}\n'
224 224 @ 10 c87ca422d521 dir1/dirA/foo
225 225 |
226 226 o 9 951b8a83924e dir2/dirB/bar
227 227 |
228 228 o 8 01ae5a51b563 dir2/dirB/foo
229 229 |
230 230 o 7 5eababdf0ac5... dir2/dirA/bar
231 231 |
232 232 o 6 623466a5f475... dir1/dirA/bar
233 233 |
234 234 o 5 06ff3a5be997 dir1/dirA/foo
235 235 |
236 236 o 4 33227af02764 dir2/bar
237 237 |
238 238 o 3 5e1f9d8d7c69 dir2/foo
239 239 |
240 240 o 2 594bc4b13d4a dir1/bar
241 241 |
242 242 o 1 47f480a08324 dir1/foo
243 243 |
244 244 o 0 2a4f0c3b67da... root
245 245
246 246
247 247 widen narrow spec yet again, excluding a directory in previous spec
248 248
249 249 $ hg tracked --removeexclude dir2/dirA --addexclude dir1/dirA
250 250 comparing with ssh://user@dummy/master
251 251 searching for changes
252 252 looking for local changes to affected paths
253 253 deleting data/dir1/dirA/foo.i (reporevlogstore !)
254 254 deleting data/dir1/dirA/foo/162caeb3d55dceb1fee793aa631ac8c73fcb8b5e (reposimplestore !)
255 255 deleting data/dir1/dirA/foo/index (reposimplestore !)
256 256 no changes found
257 257 saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-widen.hg (glob)
258 258 adding changesets
259 259 adding manifests
260 260 adding file changes
261 261 added 13 changesets with 8 changes to 8 files
262 262 new changesets *:* (glob)
263 263 $ hg tracked
264 264 I path:dir1
265 265 I path:dir2
266 266 X path:dir1/dirA
267 267 X path:dir1/dirA/bar
268 268 X path:dir1/dirB
269 269 $ find * | sort
270 270 dir1
271 271 dir1/bar
272 272 dir1/foo
273 273 dir2
274 274 dir2/bar
275 275 dir2/dirA
276 276 dir2/dirA/bar
277 277 dir2/dirA/foo
278 278 dir2/dirB
279 279 dir2/dirB/bar
280 280 dir2/dirB/foo
281 281 dir2/foo
282 282 $ hg log -G -T '{rev} {node|short}{if(ellipsis, "...")} {files}\n'
283 283 @ 12 c87ca422d521... dir1/dirA/foo
284 284 |
285 285 o 11 951b8a83924e dir2/dirB/bar
286 286 |
287 287 o 10 01ae5a51b563 dir2/dirB/foo
288 288 |
289 289 o 9 5eababdf0ac5 dir2/dirA/bar
290 290 |
291 291 o 8 99d690663739 dir2/dirA/foo
292 292 |
293 293 o 7 8e80155d5445... dir1/dirB/bar
294 294 |
295 295 o 6 623466a5f475... dir1/dirA/bar
296 296 |
297 297 o 5 06ff3a5be997... dir1/dirA/foo
298 298 |
299 299 o 4 33227af02764 dir2/bar
300 300 |
301 301 o 3 5e1f9d8d7c69 dir2/foo
302 302 |
303 303 o 2 594bc4b13d4a dir1/bar
304 304 |
305 305 o 1 47f480a08324 dir1/foo
306 306 |
307 307 o 0 2a4f0c3b67da... root
308 308
309 309
310 310 include a directory that was previously explicitly excluded
311 311
312 312 $ hg tracked --removeexclude dir1/dirA
313 313 comparing with ssh://user@dummy/master
314 314 searching for changes
315 315 no changes found
316 316 saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-widen.hg (glob)
317 317 adding changesets
318 318 adding manifests
319 319 adding file changes
320 320 added 13 changesets with 9 changes to 9 files
321 321 new changesets *:* (glob)
322 322 $ hg tracked
323 323 I path:dir1
324 324 I path:dir2
325 325 X path:dir1/dirA/bar
326 326 X path:dir1/dirB
327 327 $ find * | sort
328 328 dir1
329 329 dir1/bar
330 330 dir1/dirA
331 331 dir1/dirA/foo
332 332 dir1/foo
333 333 dir2
334 334 dir2/bar
335 335 dir2/dirA
336 336 dir2/dirA/bar
337 337 dir2/dirA/foo
338 338 dir2/dirB
339 339 dir2/dirB/bar
340 340 dir2/dirB/foo
341 341 dir2/foo
342 342 $ hg log -G -T '{rev} {node|short}{if(ellipsis, "...")} {files}\n'
343 343 @ 12 c87ca422d521 dir1/dirA/foo
344 344 |
345 345 o 11 951b8a83924e dir2/dirB/bar
346 346 |
347 347 o 10 01ae5a51b563 dir2/dirB/foo
348 348 |
349 349 o 9 5eababdf0ac5 dir2/dirA/bar
350 350 |
351 351 o 8 99d690663739 dir2/dirA/foo
352 352 |
353 353 o 7 8e80155d5445... dir1/dirB/bar
354 354 |
355 355 o 6 623466a5f475... dir1/dirA/bar
356 356 |
357 357 o 5 06ff3a5be997 dir1/dirA/foo
358 358 |
359 359 o 4 33227af02764 dir2/bar
360 360 |
361 361 o 3 5e1f9d8d7c69 dir2/foo
362 362 |
363 363 o 2 594bc4b13d4a dir1/bar
364 364 |
365 365 o 1 47f480a08324 dir1/foo
366 366 |
367 367 o 0 2a4f0c3b67da... root
368 368
369 369
370 370 $ cd ..
371 371
372 372 clone a narrow portion of the master, such that we can widen it later
373 373
374 374 $ hg clone --narrow ssh://user@dummy/master narrow2 --include dir1/dirA
375 375 requesting all changes
376 376 adding changesets
377 377 adding manifests
378 378 adding file changes
379 379 added 5 changesets with 2 changes to 2 files
380 380 new changesets *:* (glob)
381 381 updating to branch default
382 382 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 383 $ cd narrow2
384 384 $ find * | sort
385 385 dir1
386 386 dir1/dirA
387 387 dir1/dirA/bar
388 388 dir1/dirA/foo
389 389 $ hg tracked --addinclude dir1
390 390 comparing with ssh://user@dummy/master
391 391 searching for changes
392 392 no changes found
393 393 saved backup bundle to $TESTTMP/narrow2/.hg/strip-backup/*-widen.hg (glob)
394 394 adding changesets
395 395 adding manifests
396 396 adding file changes
397 397 added 10 changesets with 6 changes to 6 files
398 398 new changesets *:* (glob)
399 399 $ find * | sort
400 400 dir1
401 401 dir1/bar
402 402 dir1/dirA
403 403 dir1/dirA/bar
404 404 dir1/dirA/foo
405 405 dir1/dirB
406 406 dir1/dirB/bar
407 407 dir1/dirB/foo
408 408 dir1/foo
409 409 $ hg log -G -T '{rev} {node|short}{if(ellipsis, "...")} {files}\n'
410 410 @ 9 c87ca422d521 dir1/dirA/foo
411 411 |
412 412 o 8 951b8a83924e... dir2/dirB/bar
413 413 |
414 414 o 7 8e80155d5445 dir1/dirB/bar
415 415 |
416 416 o 6 406760310428 dir1/dirB/foo
417 417 |
418 418 o 5 623466a5f475 dir1/dirA/bar
419 419 |
420 420 o 4 06ff3a5be997 dir1/dirA/foo
421 421 |
422 422 o 3 33227af02764... dir2/bar
423 423 |
424 424 o 2 594bc4b13d4a dir1/bar
425 425 |
426 426 o 1 47f480a08324 dir1/foo
427 427 |
428 428 o 0 2a4f0c3b67da... root
429 429
430
431 Illegal patterns are rejected
432
433 $ hg tracked --addinclude glob:**
434 abort: invalid prefix on narrow pattern: glob:**
435 (narrow patterns must begin with one of the following: path:, rootfilesin:)
436 [255]
437
438 $ hg tracked --addexclude set:ignored
439 abort: invalid prefix on narrow pattern: set:ignored
440 (narrow patterns must begin with one of the following: path:, rootfilesin:)
441 [255]
General Comments 0
You need to be logged in to leave comments. Login now