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