##// END OF EJS Templates
narrow: validate spec files are well-formed during clone (BC)...
Gregory Szorc -
r39577:8301741e default
parent child Browse files
Show More
@@ -1,460 +1,463
1 # narrowcommands.py - command modifications for narrowhg extension
1 # narrowcommands.py - command modifications for narrowhg extension
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 from __future__ import absolute_import
7 from __future__ import absolute_import
8
8
9 import itertools
9 import itertools
10 import os
10 import os
11
11
12 from mercurial.i18n import _
12 from mercurial.i18n import _
13 from mercurial import (
13 from mercurial import (
14 cmdutil,
14 cmdutil,
15 commands,
15 commands,
16 discovery,
16 discovery,
17 encoding,
17 encoding,
18 error,
18 error,
19 exchange,
19 exchange,
20 extensions,
20 extensions,
21 hg,
21 hg,
22 merge,
22 merge,
23 narrowspec,
23 narrowspec,
24 node,
24 node,
25 pycompat,
25 pycompat,
26 registrar,
26 registrar,
27 repair,
27 repair,
28 repository,
28 repository,
29 repoview,
29 repoview,
30 sparse,
30 sparse,
31 util,
31 util,
32 )
32 )
33
33
34 from . import (
34 from . import (
35 narrowwirepeer,
35 narrowwirepeer,
36 )
36 )
37
37
38 table = {}
38 table = {}
39 command = registrar.command(table)
39 command = registrar.command(table)
40
40
41 def setup():
41 def setup():
42 """Wraps user-facing mercurial commands with narrow-aware versions."""
42 """Wraps user-facing mercurial commands with narrow-aware versions."""
43
43
44 entry = extensions.wrapcommand(commands.table, 'clone', clonenarrowcmd)
44 entry = extensions.wrapcommand(commands.table, 'clone', clonenarrowcmd)
45 entry[1].append(('', 'narrow', None,
45 entry[1].append(('', 'narrow', None,
46 _("create a narrow clone of select files")))
46 _("create a narrow clone of select files")))
47 entry[1].append(('', 'depth', '',
47 entry[1].append(('', 'depth', '',
48 _("limit the history fetched by distance from heads")))
48 _("limit the history fetched by distance from heads")))
49 entry[1].append(('', 'narrowspec', '',
49 entry[1].append(('', 'narrowspec', '',
50 _("read narrowspecs from file")))
50 _("read narrowspecs from file")))
51 # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit
51 # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit
52 if 'sparse' not in extensions.enabled():
52 if 'sparse' not in extensions.enabled():
53 entry[1].append(('', 'include', [],
53 entry[1].append(('', 'include', [],
54 _("specifically fetch this file/directory")))
54 _("specifically fetch this file/directory")))
55 entry[1].append(
55 entry[1].append(
56 ('', 'exclude', [],
56 ('', 'exclude', [],
57 _("do not fetch this file/directory, even if included")))
57 _("do not fetch this file/directory, even if included")))
58
58
59 entry = extensions.wrapcommand(commands.table, 'pull', pullnarrowcmd)
59 entry = extensions.wrapcommand(commands.table, 'pull', pullnarrowcmd)
60 entry[1].append(('', 'depth', '',
60 entry[1].append(('', 'depth', '',
61 _("limit the history fetched by distance from heads")))
61 _("limit the history fetched by distance from heads")))
62
62
63 extensions.wrapcommand(commands.table, 'archive', archivenarrowcmd)
63 extensions.wrapcommand(commands.table, 'archive', archivenarrowcmd)
64
64
65 def expandpull(pullop, includepats, excludepats):
65 def expandpull(pullop, includepats, excludepats):
66 if not narrowspec.needsexpansion(includepats):
66 if not narrowspec.needsexpansion(includepats):
67 return includepats, excludepats
67 return includepats, excludepats
68
68
69 heads = pullop.heads or pullop.rheads
69 heads = pullop.heads or pullop.rheads
70 includepats, excludepats = pullop.remote.expandnarrow(
70 includepats, excludepats = pullop.remote.expandnarrow(
71 includepats, excludepats, heads)
71 includepats, excludepats, heads)
72 pullop.repo.ui.debug('Expanded narrowspec to inc=%s, exc=%s\n' % (
72 pullop.repo.ui.debug('Expanded narrowspec to inc=%s, exc=%s\n' % (
73 includepats, excludepats))
73 includepats, excludepats))
74
74
75 includepats = set(includepats)
75 includepats = set(includepats)
76 excludepats = set(excludepats)
76 excludepats = set(excludepats)
77
77
78 # Nefarious remote could supply unsafe patterns. Validate them.
78 # Nefarious remote could supply unsafe patterns. Validate them.
79 narrowspec.validatepatterns(includepats)
79 narrowspec.validatepatterns(includepats)
80 narrowspec.validatepatterns(excludepats)
80 narrowspec.validatepatterns(excludepats)
81
81
82 return includepats, excludepats
82 return includepats, excludepats
83
83
84 def clonenarrowcmd(orig, ui, repo, *args, **opts):
84 def clonenarrowcmd(orig, ui, repo, *args, **opts):
85 """Wraps clone command, so 'hg clone' first wraps localrepo.clone()."""
85 """Wraps clone command, so 'hg clone' first wraps localrepo.clone()."""
86 opts = pycompat.byteskwargs(opts)
86 opts = pycompat.byteskwargs(opts)
87 wrappedextraprepare = util.nullcontextmanager()
87 wrappedextraprepare = util.nullcontextmanager()
88 opts_narrow = opts['narrow']
88 opts_narrow = opts['narrow']
89 narrowspecfile = opts['narrowspec']
89 narrowspecfile = opts['narrowspec']
90
90
91 if narrowspecfile:
91 if narrowspecfile:
92 filepath = os.path.join(pycompat.getcwd(), narrowspecfile)
92 filepath = os.path.join(pycompat.getcwd(), narrowspecfile)
93 ui.status(_("reading narrowspec from '%s'\n") % filepath)
93 ui.status(_("reading narrowspec from '%s'\n") % filepath)
94 try:
94 try:
95 fdata = util.readfile(filepath)
95 fdata = util.readfile(filepath)
96 except IOError as inst:
96 except IOError as inst:
97 raise error.Abort(_("cannot read narrowspecs from '%s': %s") %
97 raise error.Abort(_("cannot read narrowspecs from '%s': %s") %
98 (filepath, encoding.strtolocal(inst.strerror)))
98 (filepath, encoding.strtolocal(inst.strerror)))
99
99
100 includes, excludes, profiles = sparse.parseconfig(ui, fdata, 'narrow')
100 includes, excludes, profiles = sparse.parseconfig(ui, fdata, 'narrow')
101 if profiles:
101 if profiles:
102 raise error.Abort(_("cannot specify other files using '%include' in"
102 raise error.Abort(_("cannot specify other files using '%include' in"
103 " narrowspec"))
103 " narrowspec"))
104
104
105 narrowspec.validatepatterns(includes)
106 narrowspec.validatepatterns(excludes)
107
105 # narrowspec is passed so we should assume that user wants narrow clone
108 # narrowspec is passed so we should assume that user wants narrow clone
106 opts_narrow = True
109 opts_narrow = True
107 opts['include'].extend(includes)
110 opts['include'].extend(includes)
108 opts['exclude'].extend(excludes)
111 opts['exclude'].extend(excludes)
109
112
110 if opts_narrow:
113 if opts_narrow:
111 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
114 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
112 # Create narrow spec patterns from clone flags
115 # Create narrow spec patterns from clone flags
113 includepats = narrowspec.parsepatterns(opts['include'])
116 includepats = narrowspec.parsepatterns(opts['include'])
114 excludepats = narrowspec.parsepatterns(opts['exclude'])
117 excludepats = narrowspec.parsepatterns(opts['exclude'])
115
118
116 # If necessary, ask the server to expand the narrowspec.
119 # If necessary, ask the server to expand the narrowspec.
117 includepats, excludepats = expandpull(
120 includepats, excludepats = expandpull(
118 pullop, includepats, excludepats)
121 pullop, includepats, excludepats)
119
122
120 if not includepats and excludepats:
123 if not includepats and excludepats:
121 # If nothing was included, we assume the user meant to include
124 # If nothing was included, we assume the user meant to include
122 # everything, except what they asked to exclude.
125 # everything, except what they asked to exclude.
123 includepats = {'path:.'}
126 includepats = {'path:.'}
124
127
125 pullop.repo.setnarrowpats(includepats, excludepats)
128 pullop.repo.setnarrowpats(includepats, excludepats)
126
129
127 # This will populate 'includepats' etc with the values from the
130 # This will populate 'includepats' etc with the values from the
128 # narrowspec we just saved.
131 # narrowspec we just saved.
129 orig(pullop, kwargs)
132 orig(pullop, kwargs)
130
133
131 if opts.get('depth'):
134 if opts.get('depth'):
132 kwargs['depth'] = opts['depth']
135 kwargs['depth'] = opts['depth']
133 wrappedextraprepare = extensions.wrappedfunction(exchange,
136 wrappedextraprepare = extensions.wrappedfunction(exchange,
134 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
137 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
135
138
136 def pullnarrow(orig, repo, *args, **kwargs):
139 def pullnarrow(orig, repo, *args, **kwargs):
137 if opts_narrow:
140 if opts_narrow:
138 repo.requirements.add(repository.NARROW_REQUIREMENT)
141 repo.requirements.add(repository.NARROW_REQUIREMENT)
139 repo._writerequirements()
142 repo._writerequirements()
140
143
141 return orig(repo, *args, **kwargs)
144 return orig(repo, *args, **kwargs)
142
145
143 wrappedpull = extensions.wrappedfunction(exchange, 'pull', pullnarrow)
146 wrappedpull = extensions.wrappedfunction(exchange, 'pull', pullnarrow)
144
147
145 with wrappedextraprepare, wrappedpull:
148 with wrappedextraprepare, wrappedpull:
146 return orig(ui, repo, *args, **pycompat.strkwargs(opts))
149 return orig(ui, repo, *args, **pycompat.strkwargs(opts))
147
150
148 def pullnarrowcmd(orig, ui, repo, *args, **opts):
151 def pullnarrowcmd(orig, ui, repo, *args, **opts):
149 """Wraps pull command to allow modifying narrow spec."""
152 """Wraps pull command to allow modifying narrow spec."""
150 wrappedextraprepare = util.nullcontextmanager()
153 wrappedextraprepare = util.nullcontextmanager()
151 if repository.NARROW_REQUIREMENT in repo.requirements:
154 if repository.NARROW_REQUIREMENT in repo.requirements:
152
155
153 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
156 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
154 orig(pullop, kwargs)
157 orig(pullop, kwargs)
155 if opts.get(r'depth'):
158 if opts.get(r'depth'):
156 kwargs['depth'] = opts[r'depth']
159 kwargs['depth'] = opts[r'depth']
157 wrappedextraprepare = extensions.wrappedfunction(exchange,
160 wrappedextraprepare = extensions.wrappedfunction(exchange,
158 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
161 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
159
162
160 with wrappedextraprepare:
163 with wrappedextraprepare:
161 return orig(ui, repo, *args, **opts)
164 return orig(ui, repo, *args, **opts)
162
165
163 def archivenarrowcmd(orig, ui, repo, *args, **opts):
166 def archivenarrowcmd(orig, ui, repo, *args, **opts):
164 """Wraps archive command to narrow the default includes."""
167 """Wraps archive command to narrow the default includes."""
165 if repository.NARROW_REQUIREMENT in repo.requirements:
168 if repository.NARROW_REQUIREMENT in repo.requirements:
166 repo_includes, repo_excludes = repo.narrowpats
169 repo_includes, repo_excludes = repo.narrowpats
167 includes = set(opts.get(r'include', []))
170 includes = set(opts.get(r'include', []))
168 excludes = set(opts.get(r'exclude', []))
171 excludes = set(opts.get(r'exclude', []))
169 includes, excludes, unused_invalid = narrowspec.restrictpatterns(
172 includes, excludes, unused_invalid = narrowspec.restrictpatterns(
170 includes, excludes, repo_includes, repo_excludes)
173 includes, excludes, repo_includes, repo_excludes)
171 if includes:
174 if includes:
172 opts[r'include'] = includes
175 opts[r'include'] = includes
173 if excludes:
176 if excludes:
174 opts[r'exclude'] = excludes
177 opts[r'exclude'] = excludes
175 return orig(ui, repo, *args, **opts)
178 return orig(ui, repo, *args, **opts)
176
179
177 def pullbundle2extraprepare(orig, pullop, kwargs):
180 def pullbundle2extraprepare(orig, pullop, kwargs):
178 repo = pullop.repo
181 repo = pullop.repo
179 if repository.NARROW_REQUIREMENT not in repo.requirements:
182 if repository.NARROW_REQUIREMENT not in repo.requirements:
180 return orig(pullop, kwargs)
183 return orig(pullop, kwargs)
181
184
182 if narrowwirepeer.NARROWCAP not in pullop.remote.capabilities():
185 if narrowwirepeer.NARROWCAP not in pullop.remote.capabilities():
183 raise error.Abort(_("server doesn't support narrow clones"))
186 raise error.Abort(_("server doesn't support narrow clones"))
184 orig(pullop, kwargs)
187 orig(pullop, kwargs)
185 kwargs['narrow'] = True
188 kwargs['narrow'] = True
186 include, exclude = repo.narrowpats
189 include, exclude = repo.narrowpats
187 kwargs['oldincludepats'] = include
190 kwargs['oldincludepats'] = include
188 kwargs['oldexcludepats'] = exclude
191 kwargs['oldexcludepats'] = exclude
189 kwargs['includepats'] = include
192 kwargs['includepats'] = include
190 kwargs['excludepats'] = exclude
193 kwargs['excludepats'] = exclude
191 # calculate known nodes only in ellipses cases because in non-ellipses cases
194 # calculate known nodes only in ellipses cases because in non-ellipses cases
192 # we have all the nodes
195 # we have all the nodes
193 if narrowwirepeer.ELLIPSESCAP in pullop.remote.capabilities():
196 if narrowwirepeer.ELLIPSESCAP in pullop.remote.capabilities():
194 kwargs['known'] = [node.hex(ctx.node()) for ctx in
197 kwargs['known'] = [node.hex(ctx.node()) for ctx in
195 repo.set('::%ln', pullop.common)
198 repo.set('::%ln', pullop.common)
196 if ctx.node() != node.nullid]
199 if ctx.node() != node.nullid]
197 if not kwargs['known']:
200 if not kwargs['known']:
198 # Mercurial serializes an empty list as '' and deserializes it as
201 # Mercurial serializes an empty list as '' and deserializes it as
199 # [''], so delete it instead to avoid handling the empty string on
202 # [''], so delete it instead to avoid handling the empty string on
200 # the server.
203 # the server.
201 del kwargs['known']
204 del kwargs['known']
202
205
203 extensions.wrapfunction(exchange,'_pullbundle2extraprepare',
206 extensions.wrapfunction(exchange,'_pullbundle2extraprepare',
204 pullbundle2extraprepare)
207 pullbundle2extraprepare)
205
208
206 def _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
209 def _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
207 newincludes, newexcludes, force):
210 newincludes, newexcludes, force):
208 oldmatch = narrowspec.match(repo.root, oldincludes, oldexcludes)
211 oldmatch = narrowspec.match(repo.root, oldincludes, oldexcludes)
209 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
212 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
210
213
211 # This is essentially doing "hg outgoing" to find all local-only
214 # This is essentially doing "hg outgoing" to find all local-only
212 # commits. We will then check that the local-only commits don't
215 # commits. We will then check that the local-only commits don't
213 # have any changes to files that will be untracked.
216 # have any changes to files that will be untracked.
214 unfi = repo.unfiltered()
217 unfi = repo.unfiltered()
215 outgoing = discovery.findcommonoutgoing(unfi, remote,
218 outgoing = discovery.findcommonoutgoing(unfi, remote,
216 commoninc=commoninc)
219 commoninc=commoninc)
217 ui.status(_('looking for local changes to affected paths\n'))
220 ui.status(_('looking for local changes to affected paths\n'))
218 localnodes = []
221 localnodes = []
219 for n in itertools.chain(outgoing.missing, outgoing.excluded):
222 for n in itertools.chain(outgoing.missing, outgoing.excluded):
220 if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()):
223 if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()):
221 localnodes.append(n)
224 localnodes.append(n)
222 revstostrip = unfi.revs('descendants(%ln)', localnodes)
225 revstostrip = unfi.revs('descendants(%ln)', localnodes)
223 hiddenrevs = repoview.filterrevs(repo, 'visible')
226 hiddenrevs = repoview.filterrevs(repo, 'visible')
224 visibletostrip = list(repo.changelog.node(r)
227 visibletostrip = list(repo.changelog.node(r)
225 for r in (revstostrip - hiddenrevs))
228 for r in (revstostrip - hiddenrevs))
226 if visibletostrip:
229 if visibletostrip:
227 ui.status(_('The following changeset(s) or their ancestors have '
230 ui.status(_('The following changeset(s) or their ancestors have '
228 'local changes not on the remote:\n'))
231 'local changes not on the remote:\n'))
229 maxnodes = 10
232 maxnodes = 10
230 if ui.verbose or len(visibletostrip) <= maxnodes:
233 if ui.verbose or len(visibletostrip) <= maxnodes:
231 for n in visibletostrip:
234 for n in visibletostrip:
232 ui.status('%s\n' % node.short(n))
235 ui.status('%s\n' % node.short(n))
233 else:
236 else:
234 for n in visibletostrip[:maxnodes]:
237 for n in visibletostrip[:maxnodes]:
235 ui.status('%s\n' % node.short(n))
238 ui.status('%s\n' % node.short(n))
236 ui.status(_('...and %d more, use --verbose to list all\n') %
239 ui.status(_('...and %d more, use --verbose to list all\n') %
237 (len(visibletostrip) - maxnodes))
240 (len(visibletostrip) - maxnodes))
238 if not force:
241 if not force:
239 raise error.Abort(_('local changes found'),
242 raise error.Abort(_('local changes found'),
240 hint=_('use --force-delete-local-changes to '
243 hint=_('use --force-delete-local-changes to '
241 'ignore'))
244 'ignore'))
242
245
243 with ui.uninterruptable():
246 with ui.uninterruptable():
244 if revstostrip:
247 if revstostrip:
245 tostrip = [unfi.changelog.node(r) for r in revstostrip]
248 tostrip = [unfi.changelog.node(r) for r in revstostrip]
246 if repo['.'].node() in tostrip:
249 if repo['.'].node() in tostrip:
247 # stripping working copy, so move to a different commit first
250 # stripping working copy, so move to a different commit first
248 urev = max(repo.revs('(::%n) - %ln + null',
251 urev = max(repo.revs('(::%n) - %ln + null',
249 repo['.'].node(), visibletostrip))
252 repo['.'].node(), visibletostrip))
250 hg.clean(repo, urev)
253 hg.clean(repo, urev)
251 repair.strip(ui, unfi, tostrip, topic='narrow')
254 repair.strip(ui, unfi, tostrip, topic='narrow')
252
255
253 todelete = []
256 todelete = []
254 for f, f2, size in repo.store.datafiles():
257 for f, f2, size in repo.store.datafiles():
255 if f.startswith('data/'):
258 if f.startswith('data/'):
256 file = f[5:-2]
259 file = f[5:-2]
257 if not newmatch(file):
260 if not newmatch(file):
258 todelete.append(f)
261 todelete.append(f)
259 elif f.startswith('meta/'):
262 elif f.startswith('meta/'):
260 dir = f[5:-13]
263 dir = f[5:-13]
261 dirs = ['.'] + sorted(util.dirs({dir})) + [dir]
264 dirs = ['.'] + sorted(util.dirs({dir})) + [dir]
262 include = True
265 include = True
263 for d in dirs:
266 for d in dirs:
264 visit = newmatch.visitdir(d)
267 visit = newmatch.visitdir(d)
265 if not visit:
268 if not visit:
266 include = False
269 include = False
267 break
270 break
268 if visit == 'all':
271 if visit == 'all':
269 break
272 break
270 if not include:
273 if not include:
271 todelete.append(f)
274 todelete.append(f)
272
275
273 repo.destroying()
276 repo.destroying()
274
277
275 with repo.transaction("narrowing"):
278 with repo.transaction("narrowing"):
276 for f in todelete:
279 for f in todelete:
277 ui.status(_('deleting %s\n') % f)
280 ui.status(_('deleting %s\n') % f)
278 util.unlinkpath(repo.svfs.join(f))
281 util.unlinkpath(repo.svfs.join(f))
279 repo.store.markremoved(f)
282 repo.store.markremoved(f)
280
283
281 for f in repo.dirstate:
284 for f in repo.dirstate:
282 if not newmatch(f):
285 if not newmatch(f):
283 repo.dirstate.drop(f)
286 repo.dirstate.drop(f)
284 repo.wvfs.unlinkpath(f)
287 repo.wvfs.unlinkpath(f)
285 repo.setnarrowpats(newincludes, newexcludes)
288 repo.setnarrowpats(newincludes, newexcludes)
286
289
287 repo.destroyed()
290 repo.destroyed()
288
291
289 def _widen(ui, repo, remote, commoninc, newincludes, newexcludes):
292 def _widen(ui, repo, remote, commoninc, newincludes, newexcludes):
290 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
293 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
291
294
292 # TODO(martinvonz): Get expansion working with widening/narrowing.
295 # TODO(martinvonz): Get expansion working with widening/narrowing.
293 if narrowspec.needsexpansion(newincludes):
296 if narrowspec.needsexpansion(newincludes):
294 raise error.Abort('Expansion not yet supported on pull')
297 raise error.Abort('Expansion not yet supported on pull')
295
298
296 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
299 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
297 orig(pullop, kwargs)
300 orig(pullop, kwargs)
298 # The old{in,ex}cludepats have already been set by orig()
301 # The old{in,ex}cludepats have already been set by orig()
299 kwargs['includepats'] = newincludes
302 kwargs['includepats'] = newincludes
300 kwargs['excludepats'] = newexcludes
303 kwargs['excludepats'] = newexcludes
301 kwargs['widen'] = True
304 kwargs['widen'] = True
302 wrappedextraprepare = extensions.wrappedfunction(exchange,
305 wrappedextraprepare = extensions.wrappedfunction(exchange,
303 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
306 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
304
307
305 # define a function that narrowbundle2 can call after creating the
308 # define a function that narrowbundle2 can call after creating the
306 # backup bundle, but before applying the bundle from the server
309 # backup bundle, but before applying the bundle from the server
307 def setnewnarrowpats():
310 def setnewnarrowpats():
308 repo.setnarrowpats(newincludes, newexcludes)
311 repo.setnarrowpats(newincludes, newexcludes)
309 repo.setnewnarrowpats = setnewnarrowpats
312 repo.setnewnarrowpats = setnewnarrowpats
310
313
311 with ui.uninterruptable():
314 with ui.uninterruptable():
312 ds = repo.dirstate
315 ds = repo.dirstate
313 p1, p2 = ds.p1(), ds.p2()
316 p1, p2 = ds.p1(), ds.p2()
314 with ds.parentchange():
317 with ds.parentchange():
315 ds.setparents(node.nullid, node.nullid)
318 ds.setparents(node.nullid, node.nullid)
316 common = commoninc[0]
319 common = commoninc[0]
317 with wrappedextraprepare:
320 with wrappedextraprepare:
318 exchange.pull(repo, remote, heads=common)
321 exchange.pull(repo, remote, heads=common)
319 with ds.parentchange():
322 with ds.parentchange():
320 ds.setparents(p1, p2)
323 ds.setparents(p1, p2)
321
324
322 repo.setnewnarrowpats()
325 repo.setnewnarrowpats()
323 actions = {k: [] for k in 'a am f g cd dc r dm dg m e k p pr'.split()}
326 actions = {k: [] for k in 'a am f g cd dc r dm dg m e k p pr'.split()}
324 addgaction = actions['g'].append
327 addgaction = actions['g'].append
325
328
326 mf = repo['.'].manifest().matches(newmatch)
329 mf = repo['.'].manifest().matches(newmatch)
327 for f, fn in mf.iteritems():
330 for f, fn in mf.iteritems():
328 if f not in repo.dirstate:
331 if f not in repo.dirstate:
329 addgaction((f, (mf.flags(f), False),
332 addgaction((f, (mf.flags(f), False),
330 "add from widened narrow clone"))
333 "add from widened narrow clone"))
331
334
332 merge.applyupdates(repo, actions, wctx=repo[None],
335 merge.applyupdates(repo, actions, wctx=repo[None],
333 mctx=repo['.'], overwrite=False)
336 mctx=repo['.'], overwrite=False)
334 merge.recordupdates(repo, actions, branchmerge=False)
337 merge.recordupdates(repo, actions, branchmerge=False)
335
338
336 # TODO(rdamazio): Make new matcher format and update description
339 # TODO(rdamazio): Make new matcher format and update description
337 @command('tracked',
340 @command('tracked',
338 [('', 'addinclude', [], _('new paths to include')),
341 [('', 'addinclude', [], _('new paths to include')),
339 ('', 'removeinclude', [], _('old paths to no longer include')),
342 ('', 'removeinclude', [], _('old paths to no longer include')),
340 ('', 'addexclude', [], _('new paths to exclude')),
343 ('', 'addexclude', [], _('new paths to exclude')),
341 ('', 'import-rules', '', _('import narrowspecs from a file')),
344 ('', 'import-rules', '', _('import narrowspecs from a file')),
342 ('', 'removeexclude', [], _('old paths to no longer exclude')),
345 ('', 'removeexclude', [], _('old paths to no longer exclude')),
343 ('', 'clear', False, _('whether to replace the existing narrowspec')),
346 ('', 'clear', False, _('whether to replace the existing narrowspec')),
344 ('', 'force-delete-local-changes', False,
347 ('', 'force-delete-local-changes', False,
345 _('forces deletion of local changes when narrowing')),
348 _('forces deletion of local changes when narrowing')),
346 ] + commands.remoteopts,
349 ] + commands.remoteopts,
347 _('[OPTIONS]... [REMOTE]'),
350 _('[OPTIONS]... [REMOTE]'),
348 inferrepo=True)
351 inferrepo=True)
349 def trackedcmd(ui, repo, remotepath=None, *pats, **opts):
352 def trackedcmd(ui, repo, remotepath=None, *pats, **opts):
350 """show or change the current narrowspec
353 """show or change the current narrowspec
351
354
352 With no argument, shows the current narrowspec entries, one per line. Each
355 With no argument, shows the current narrowspec entries, one per line. Each
353 line will be prefixed with 'I' or 'X' for included or excluded patterns,
356 line will be prefixed with 'I' or 'X' for included or excluded patterns,
354 respectively.
357 respectively.
355
358
356 The narrowspec is comprised of expressions to match remote files and/or
359 The narrowspec is comprised of expressions to match remote files and/or
357 directories that should be pulled into your client.
360 directories that should be pulled into your client.
358 The narrowspec has *include* and *exclude* expressions, with excludes always
361 The narrowspec has *include* and *exclude* expressions, with excludes always
359 trumping includes: that is, if a file matches an exclude expression, it will
362 trumping includes: that is, if a file matches an exclude expression, it will
360 be excluded even if it also matches an include expression.
363 be excluded even if it also matches an include expression.
361 Excluding files that were never included has no effect.
364 Excluding files that were never included has no effect.
362
365
363 Each included or excluded entry is in the format described by
366 Each included or excluded entry is in the format described by
364 'hg help patterns'.
367 'hg help patterns'.
365
368
366 The options allow you to add or remove included and excluded expressions.
369 The options allow you to add or remove included and excluded expressions.
367
370
368 If --clear is specified, then all previous includes and excludes are DROPPED
371 If --clear is specified, then all previous includes and excludes are DROPPED
369 and replaced by the new ones specified to --addinclude and --addexclude.
372 and replaced by the new ones specified to --addinclude and --addexclude.
370 If --clear is specified without any further options, the narrowspec will be
373 If --clear is specified without any further options, the narrowspec will be
371 empty and will not match any files.
374 empty and will not match any files.
372 """
375 """
373 opts = pycompat.byteskwargs(opts)
376 opts = pycompat.byteskwargs(opts)
374 if repository.NARROW_REQUIREMENT not in repo.requirements:
377 if repository.NARROW_REQUIREMENT not in repo.requirements:
375 ui.warn(_('The narrow command is only supported on respositories cloned'
378 ui.warn(_('The narrow command is only supported on respositories cloned'
376 ' with --narrow.\n'))
379 ' with --narrow.\n'))
377 return 1
380 return 1
378
381
379 # Before supporting, decide whether it "hg tracked --clear" should mean
382 # Before supporting, decide whether it "hg tracked --clear" should mean
380 # tracking no paths or all paths.
383 # tracking no paths or all paths.
381 if opts['clear']:
384 if opts['clear']:
382 ui.warn(_('The --clear option is not yet supported.\n'))
385 ui.warn(_('The --clear option is not yet supported.\n'))
383 return 1
386 return 1
384
387
385 # import rules from a file
388 # import rules from a file
386 newrules = opts.get('import_rules')
389 newrules = opts.get('import_rules')
387 if newrules:
390 if newrules:
388 try:
391 try:
389 filepath = os.path.join(pycompat.getcwd(), newrules)
392 filepath = os.path.join(pycompat.getcwd(), newrules)
390 fdata = util.readfile(filepath)
393 fdata = util.readfile(filepath)
391 except IOError as inst:
394 except IOError as inst:
392 raise error.Abort(_("cannot read narrowspecs from '%s': %s") %
395 raise error.Abort(_("cannot read narrowspecs from '%s': %s") %
393 (filepath, encoding.strtolocal(inst.strerror)))
396 (filepath, encoding.strtolocal(inst.strerror)))
394 includepats, excludepats, profiles = sparse.parseconfig(ui, fdata,
397 includepats, excludepats, profiles = sparse.parseconfig(ui, fdata,
395 'narrow')
398 'narrow')
396 if profiles:
399 if profiles:
397 raise error.Abort(_("including other spec files using '%include' "
400 raise error.Abort(_("including other spec files using '%include' "
398 "is not supported in narrowspec"))
401 "is not supported in narrowspec"))
399 opts['addinclude'].extend(includepats)
402 opts['addinclude'].extend(includepats)
400 opts['addexclude'].extend(excludepats)
403 opts['addexclude'].extend(excludepats)
401
404
402 if narrowspec.needsexpansion(opts['addinclude'] + opts['addexclude']):
405 if narrowspec.needsexpansion(opts['addinclude'] + opts['addexclude']):
403 raise error.Abort('Expansion not yet supported on widen/narrow')
406 raise error.Abort('Expansion not yet supported on widen/narrow')
404
407
405 addedincludes = narrowspec.parsepatterns(opts['addinclude'])
408 addedincludes = narrowspec.parsepatterns(opts['addinclude'])
406 removedincludes = narrowspec.parsepatterns(opts['removeinclude'])
409 removedincludes = narrowspec.parsepatterns(opts['removeinclude'])
407 addedexcludes = narrowspec.parsepatterns(opts['addexclude'])
410 addedexcludes = narrowspec.parsepatterns(opts['addexclude'])
408 removedexcludes = narrowspec.parsepatterns(opts['removeexclude'])
411 removedexcludes = narrowspec.parsepatterns(opts['removeexclude'])
409 widening = addedincludes or removedexcludes
412 widening = addedincludes or removedexcludes
410 narrowing = removedincludes or addedexcludes
413 narrowing = removedincludes or addedexcludes
411 only_show = not widening and not narrowing
414 only_show = not widening and not narrowing
412
415
413 # Only print the current narrowspec.
416 # Only print the current narrowspec.
414 if only_show:
417 if only_show:
415 include, exclude = repo.narrowpats
418 include, exclude = repo.narrowpats
416
419
417 ui.pager('tracked')
420 ui.pager('tracked')
418 fm = ui.formatter('narrow', opts)
421 fm = ui.formatter('narrow', opts)
419 for i in sorted(include):
422 for i in sorted(include):
420 fm.startitem()
423 fm.startitem()
421 fm.write('status', '%s ', 'I', label='narrow.included')
424 fm.write('status', '%s ', 'I', label='narrow.included')
422 fm.write('pat', '%s\n', i, label='narrow.included')
425 fm.write('pat', '%s\n', i, label='narrow.included')
423 for i in sorted(exclude):
426 for i in sorted(exclude):
424 fm.startitem()
427 fm.startitem()
425 fm.write('status', '%s ', 'X', label='narrow.excluded')
428 fm.write('status', '%s ', 'X', label='narrow.excluded')
426 fm.write('pat', '%s\n', i, label='narrow.excluded')
429 fm.write('pat', '%s\n', i, label='narrow.excluded')
427 fm.end()
430 fm.end()
428 return 0
431 return 0
429
432
430 with repo.wlock(), repo.lock():
433 with repo.wlock(), repo.lock():
431 cmdutil.bailifchanged(repo)
434 cmdutil.bailifchanged(repo)
432
435
433 # Find the revisions we have in common with the remote. These will
436 # Find the revisions we have in common with the remote. These will
434 # be used for finding local-only changes for narrowing. They will
437 # be used for finding local-only changes for narrowing. They will
435 # also define the set of revisions to update for widening.
438 # also define the set of revisions to update for widening.
436 remotepath = ui.expandpath(remotepath or 'default')
439 remotepath = ui.expandpath(remotepath or 'default')
437 url, branches = hg.parseurl(remotepath)
440 url, branches = hg.parseurl(remotepath)
438 ui.status(_('comparing with %s\n') % util.hidepassword(url))
441 ui.status(_('comparing with %s\n') % util.hidepassword(url))
439 remote = hg.peer(repo, opts, url)
442 remote = hg.peer(repo, opts, url)
440 commoninc = discovery.findcommonincoming(repo, remote)
443 commoninc = discovery.findcommonincoming(repo, remote)
441
444
442 oldincludes, oldexcludes = repo.narrowpats
445 oldincludes, oldexcludes = repo.narrowpats
443 if narrowing:
446 if narrowing:
444 newincludes = oldincludes - removedincludes
447 newincludes = oldincludes - removedincludes
445 newexcludes = oldexcludes | addedexcludes
448 newexcludes = oldexcludes | addedexcludes
446 _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
449 _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
447 newincludes, newexcludes,
450 newincludes, newexcludes,
448 opts['force_delete_local_changes'])
451 opts['force_delete_local_changes'])
449 # _narrow() updated the narrowspec and _widen() below needs to
452 # _narrow() updated the narrowspec and _widen() below needs to
450 # use the updated values as its base (otherwise removed includes
453 # use the updated values as its base (otherwise removed includes
451 # and addedexcludes will be lost in the resulting narrowspec)
454 # and addedexcludes will be lost in the resulting narrowspec)
452 oldincludes = newincludes
455 oldincludes = newincludes
453 oldexcludes = newexcludes
456 oldexcludes = newexcludes
454
457
455 if widening:
458 if widening:
456 newincludes = oldincludes | addedincludes
459 newincludes = oldincludes | addedincludes
457 newexcludes = oldexcludes - removedexcludes
460 newexcludes = oldexcludes - removedexcludes
458 _widen(ui, repo, remote, commoninc, newincludes, newexcludes)
461 _widen(ui, repo, remote, commoninc, newincludes, newexcludes)
459
462
460 return 0
463 return 0
@@ -1,161 +1,161
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 $ mkdir dir
5 $ mkdir dir
6 $ mkdir dir/src
6 $ mkdir dir/src
7 $ cd dir/src
7 $ cd dir/src
8 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "f$x"; hg add "f$x"; hg commit -m "Commit src $x"; done
8 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "f$x"; hg add "f$x"; hg commit -m "Commit src $x"; done
9 $ cd ..
9 $ cd ..
10 $ mkdir tests
10 $ mkdir tests
11 $ cd tests
11 $ cd tests
12 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "t$x"; hg add "t$x"; hg commit -m "Commit test $x"; done
12 $ for x in `$TESTDIR/seq.py 20`; do echo $x > "t$x"; hg add "t$x"; hg commit -m "Commit test $x"; done
13 $ cd ../../..
13 $ cd ../../..
14
14
15 narrow clone a file, f10
15 narrow clone a file, f10
16
16
17 $ hg clone --narrow ssh://user@dummy/master narrow --noupdate --include "dir/src/f10"
17 $ hg clone --narrow ssh://user@dummy/master narrow --noupdate --include "dir/src/f10"
18 requesting all changes
18 requesting all changes
19 adding changesets
19 adding changesets
20 adding manifests
20 adding manifests
21 adding file changes
21 adding file changes
22 added 40 changesets with 1 changes to 1 files
22 added 40 changesets with 1 changes to 1 files
23 new changesets *:* (glob)
23 new changesets *:* (glob)
24 $ cd narrow
24 $ cd narrow
25 $ cat .hg/requires | grep -v generaldelta
25 $ cat .hg/requires | grep -v generaldelta
26 dotencode
26 dotencode
27 fncache
27 fncache
28 narrowhg-experimental
28 narrowhg-experimental
29 revlogv1
29 revlogv1
30 store
30 store
31 testonly-simplestore (reposimplestore !)
31 testonly-simplestore (reposimplestore !)
32
32
33 $ hg tracked
33 $ hg tracked
34 I path:dir/src/f10
34 I path:dir/src/f10
35 $ hg update
35 $ hg update
36 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 $ find * | sort
37 $ find * | sort
38 dir
38 dir
39 dir/src
39 dir/src
40 dir/src/f10
40 dir/src/f10
41 $ cat dir/src/f10
41 $ cat dir/src/f10
42 10
42 10
43
43
44 $ cd ..
44 $ cd ..
45
45
46 narrow clone a directory, tests/, except tests/t19
46 narrow clone a directory, tests/, except tests/t19
47
47
48 $ hg clone --narrow ssh://user@dummy/master narrowdir --noupdate --include "dir/tests/" --exclude "dir/tests/t19"
48 $ hg clone --narrow ssh://user@dummy/master narrowdir --noupdate --include "dir/tests/" --exclude "dir/tests/t19"
49 requesting all changes
49 requesting all changes
50 adding changesets
50 adding changesets
51 adding manifests
51 adding manifests
52 adding file changes
52 adding file changes
53 added 40 changesets with 19 changes to 19 files
53 added 40 changesets with 19 changes to 19 files
54 new changesets *:* (glob)
54 new changesets *:* (glob)
55 $ cd narrowdir
55 $ cd narrowdir
56 $ hg tracked
56 $ hg tracked
57 I path:dir/tests
57 I path:dir/tests
58 X path:dir/tests/t19
58 X path:dir/tests/t19
59 $ hg update
59 $ hg update
60 19 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 19 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 $ find * | sort
61 $ find * | sort
62 dir
62 dir
63 dir/tests
63 dir/tests
64 dir/tests/t1
64 dir/tests/t1
65 dir/tests/t10
65 dir/tests/t10
66 dir/tests/t11
66 dir/tests/t11
67 dir/tests/t12
67 dir/tests/t12
68 dir/tests/t13
68 dir/tests/t13
69 dir/tests/t14
69 dir/tests/t14
70 dir/tests/t15
70 dir/tests/t15
71 dir/tests/t16
71 dir/tests/t16
72 dir/tests/t17
72 dir/tests/t17
73 dir/tests/t18
73 dir/tests/t18
74 dir/tests/t2
74 dir/tests/t2
75 dir/tests/t20
75 dir/tests/t20
76 dir/tests/t3
76 dir/tests/t3
77 dir/tests/t4
77 dir/tests/t4
78 dir/tests/t5
78 dir/tests/t5
79 dir/tests/t6
79 dir/tests/t6
80 dir/tests/t7
80 dir/tests/t7
81 dir/tests/t8
81 dir/tests/t8
82 dir/tests/t9
82 dir/tests/t9
83
83
84 $ cd ..
84 $ cd ..
85
85
86 narrow clone everything but a directory (tests/)
86 narrow clone everything but a directory (tests/)
87
87
88 $ hg clone --narrow ssh://user@dummy/master narrowroot --noupdate --exclude "dir/tests"
88 $ hg clone --narrow ssh://user@dummy/master narrowroot --noupdate --exclude "dir/tests"
89 requesting all changes
89 requesting all changes
90 adding changesets
90 adding changesets
91 adding manifests
91 adding manifests
92 adding file changes
92 adding file changes
93 added 40 changesets with 20 changes to 20 files
93 added 40 changesets with 20 changes to 20 files
94 new changesets *:* (glob)
94 new changesets *:* (glob)
95 $ cd narrowroot
95 $ cd narrowroot
96 $ hg tracked
96 $ hg tracked
97 I path:.
97 I path:.
98 X path:dir/tests
98 X path:dir/tests
99 $ hg update
99 $ hg update
100 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 $ find * | sort
101 $ find * | sort
102 dir
102 dir
103 dir/src
103 dir/src
104 dir/src/f1
104 dir/src/f1
105 dir/src/f10
105 dir/src/f10
106 dir/src/f11
106 dir/src/f11
107 dir/src/f12
107 dir/src/f12
108 dir/src/f13
108 dir/src/f13
109 dir/src/f14
109 dir/src/f14
110 dir/src/f15
110 dir/src/f15
111 dir/src/f16
111 dir/src/f16
112 dir/src/f17
112 dir/src/f17
113 dir/src/f18
113 dir/src/f18
114 dir/src/f19
114 dir/src/f19
115 dir/src/f2
115 dir/src/f2
116 dir/src/f20
116 dir/src/f20
117 dir/src/f3
117 dir/src/f3
118 dir/src/f4
118 dir/src/f4
119 dir/src/f5
119 dir/src/f5
120 dir/src/f6
120 dir/src/f6
121 dir/src/f7
121 dir/src/f7
122 dir/src/f8
122 dir/src/f8
123 dir/src/f9
123 dir/src/f9
124
124
125 $ cd ..
125 $ cd ..
126
126
127 Testing the --narrowspec flag to clone
127 Testing the --narrowspec flag to clone
128
128
129 $ cat >> narrowspecs <<EOF
129 $ cat >> narrowspecs <<EOF
130 > %include foo
130 > %include foo
131 > [include]
131 > [include]
132 > path:dir/tests/
132 > path:dir/tests/
133 > file:dir/src/f12
133 > path:file:dir/src/f12
134 > EOF
134 > EOF
135
135
136 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
136 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
137 reading narrowspec from '$TESTTMP/narrowspecs'
137 reading narrowspec from '$TESTTMP/narrowspecs'
138 abort: cannot specify other files using '%include' in narrowspec
138 abort: cannot specify other files using '%include' in narrowspec
139 [255]
139 [255]
140
140
141 $ cat > narrowspecs <<EOF
141 $ cat > narrowspecs <<EOF
142 > [include]
142 > [include]
143 > path:dir/tests/
143 > path:dir/tests/
144 > file:dir/src/f12
144 > path:file:dir/src/f12
145 > EOF
145 > EOF
146
146
147 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
147 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
148 reading narrowspec from '$TESTTMP/narrowspecs'
148 reading narrowspec from '$TESTTMP/narrowspecs'
149 requesting all changes
149 requesting all changes
150 adding changesets
150 adding changesets
151 adding manifests
151 adding manifests
152 adding file changes
152 adding file changes
153 added 40 changesets with 20 changes to 20 files
153 added 40 changesets with 20 changes to 20 files
154 new changesets 681085829a73:26ce255d5b5d
154 new changesets 681085829a73:26ce255d5b5d
155 updating to branch default
155 updating to branch default
156 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
156 20 files updated, 0 files merged, 0 files removed, 0 files unresolved
157 $ cd specfile
157 $ cd specfile
158 $ hg tracked
158 $ hg tracked
159 I path:dir/tests
159 I path:dir/tests
160 I path:file:dir/src/f12
160 I path:file:dir/src/f12
161 $ cd ..
161 $ cd ..
@@ -1,284 +1,283
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
19 Only path: and rootfilesin: pattern prefixes are allowed
20
20
21 $ hg clone --narrow ssh://user@dummy/master badnarrow --noupdate --include 'glob:**'
21 $ hg clone --narrow ssh://user@dummy/master badnarrow --noupdate --include 'glob:**'
22 requesting all changes
22 requesting all changes
23 abort: invalid prefix on narrow pattern: glob:**
23 abort: invalid prefix on narrow pattern: glob:**
24 (narrow patterns must begin with one of the following: path:, rootfilesin:)
24 (narrow patterns must begin with one of the following: path:, rootfilesin:)
25 [255]
25 [255]
26
26
27 $ hg clone --narrow ssh://user@dummy/master badnarrow --noupdate --exclude 'set:ignored'
27 $ hg clone --narrow ssh://user@dummy/master badnarrow --noupdate --exclude 'set:ignored'
28 requesting all changes
28 requesting all changes
29 abort: invalid prefix on narrow pattern: set:ignored
29 abort: invalid prefix on narrow pattern: set:ignored
30 (narrow patterns must begin with one of the following: path:, rootfilesin:)
30 (narrow patterns must begin with one of the following: path:, rootfilesin:)
31 [255]
31 [255]
32
32
33 narrow clone a file, f10
33 narrow clone a file, f10
34
34
35 $ 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"
36 requesting all changes
36 requesting all changes
37 adding changesets
37 adding changesets
38 adding manifests
38 adding manifests
39 adding file changes
39 adding file changes
40 added 3 changesets with 1 changes to 1 files
40 added 3 changesets with 1 changes to 1 files
41 new changesets *:* (glob)
41 new changesets *:* (glob)
42 $ cd narrow
42 $ cd narrow
43 $ cat .hg/requires | grep -v generaldelta
43 $ cat .hg/requires | grep -v generaldelta
44 dotencode
44 dotencode
45 fncache
45 fncache
46 narrowhg-experimental
46 narrowhg-experimental
47 revlogv1
47 revlogv1
48 store
48 store
49 testonly-simplestore (reposimplestore !)
49 testonly-simplestore (reposimplestore !)
50
50
51 $ hg tracked
51 $ hg tracked
52 I path:dir/src/f10
52 I path:dir/src/f10
53 $ hg tracked
53 $ hg tracked
54 I path:dir/src/f10
54 I path:dir/src/f10
55 $ hg update
55 $ hg update
56 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
57 $ find * | sort
57 $ find * | sort
58 dir
58 dir
59 dir/src
59 dir/src
60 dir/src/f10
60 dir/src/f10
61 $ cat dir/src/f10
61 $ cat dir/src/f10
62 10
62 10
63
63
64 $ cd ..
64 $ cd ..
65
65
66 narrow clone with a newline should fail
66 narrow clone with a newline should fail
67
67
68 $ 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
69 > '
69 > '
70 requesting all changes
70 requesting all changes
71 abort: newlines are not allowed in narrowspec paths
71 abort: newlines are not allowed in narrowspec paths
72 [255]
72 [255]
73
73
74 narrow clone a directory, tests/, except tests/t19
74 narrow clone a directory, tests/, except tests/t19
75
75
76 $ 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"
77 requesting all changes
77 requesting all changes
78 adding changesets
78 adding changesets
79 adding manifests
79 adding manifests
80 adding file changes
80 adding file changes
81 added 21 changesets with 19 changes to 19 files
81 added 21 changesets with 19 changes to 19 files
82 new changesets *:* (glob)
82 new changesets *:* (glob)
83 $ cd narrowdir
83 $ cd narrowdir
84 $ hg tracked
84 $ hg tracked
85 I path:dir/tests
85 I path:dir/tests
86 X path:dir/tests/t19
86 X path:dir/tests/t19
87 $ hg tracked
87 $ hg tracked
88 I path:dir/tests
88 I path:dir/tests
89 X path:dir/tests/t19
89 X path:dir/tests/t19
90 $ hg update
90 $ hg update
91 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
92 $ find * | sort
92 $ find * | sort
93 dir
93 dir
94 dir/tests
94 dir/tests
95 dir/tests/t1
95 dir/tests/t1
96 dir/tests/t10
96 dir/tests/t10
97 dir/tests/t11
97 dir/tests/t11
98 dir/tests/t12
98 dir/tests/t12
99 dir/tests/t13
99 dir/tests/t13
100 dir/tests/t14
100 dir/tests/t14
101 dir/tests/t15
101 dir/tests/t15
102 dir/tests/t16
102 dir/tests/t16
103 dir/tests/t17
103 dir/tests/t17
104 dir/tests/t18
104 dir/tests/t18
105 dir/tests/t2
105 dir/tests/t2
106 dir/tests/t20
106 dir/tests/t20
107 dir/tests/t3
107 dir/tests/t3
108 dir/tests/t4
108 dir/tests/t4
109 dir/tests/t5
109 dir/tests/t5
110 dir/tests/t6
110 dir/tests/t6
111 dir/tests/t7
111 dir/tests/t7
112 dir/tests/t8
112 dir/tests/t8
113 dir/tests/t9
113 dir/tests/t9
114
114
115 $ cd ..
115 $ cd ..
116
116
117 narrow clone everything but a directory (tests/)
117 narrow clone everything but a directory (tests/)
118
118
119 $ 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"
120 requesting all changes
120 requesting all changes
121 adding changesets
121 adding changesets
122 adding manifests
122 adding manifests
123 adding file changes
123 adding file changes
124 added 21 changesets with 20 changes to 20 files
124 added 21 changesets with 20 changes to 20 files
125 new changesets *:* (glob)
125 new changesets *:* (glob)
126 $ cd narrowroot
126 $ cd narrowroot
127 $ hg tracked
127 $ hg tracked
128 I path:.
128 I path:.
129 X path:dir/tests
129 X path:dir/tests
130 $ hg tracked
130 $ hg tracked
131 I path:.
131 I path:.
132 X path:dir/tests
132 X path:dir/tests
133 $ hg update
133 $ hg update
134 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
135 $ find * | sort
135 $ find * | sort
136 dir
136 dir
137 dir/src
137 dir/src
138 dir/src/f1
138 dir/src/f1
139 dir/src/f10
139 dir/src/f10
140 dir/src/f11
140 dir/src/f11
141 dir/src/f12
141 dir/src/f12
142 dir/src/f13
142 dir/src/f13
143 dir/src/f14
143 dir/src/f14
144 dir/src/f15
144 dir/src/f15
145 dir/src/f16
145 dir/src/f16
146 dir/src/f17
146 dir/src/f17
147 dir/src/f18
147 dir/src/f18
148 dir/src/f19
148 dir/src/f19
149 dir/src/f2
149 dir/src/f2
150 dir/src/f20
150 dir/src/f20
151 dir/src/f3
151 dir/src/f3
152 dir/src/f4
152 dir/src/f4
153 dir/src/f5
153 dir/src/f5
154 dir/src/f6
154 dir/src/f6
155 dir/src/f7
155 dir/src/f7
156 dir/src/f8
156 dir/src/f8
157 dir/src/f9
157 dir/src/f9
158
158
159 $ cd ..
159 $ cd ..
160
160
161 narrow clone no paths at all
161 narrow clone no paths at all
162
162
163 $ hg clone --narrow ssh://user@dummy/master narrowempty --noupdate
163 $ hg clone --narrow ssh://user@dummy/master narrowempty --noupdate
164 requesting all changes
164 requesting all changes
165 adding changesets
165 adding changesets
166 adding manifests
166 adding manifests
167 adding file changes
167 adding file changes
168 added 1 changesets with 0 changes to 0 files
168 added 1 changesets with 0 changes to 0 files
169 new changesets * (glob)
169 new changesets * (glob)
170 $ cd narrowempty
170 $ cd narrowempty
171 $ hg tracked
171 $ hg tracked
172 $ hg update
172 $ hg update
173 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
174 $ ls
174 $ ls
175
175
176 $ cd ..
176 $ cd ..
177
177
178 simple clone
178 simple clone
179 $ hg clone ssh://user@dummy/master simpleclone
179 $ hg clone ssh://user@dummy/master simpleclone
180 requesting all changes
180 requesting all changes
181 adding changesets
181 adding changesets
182 adding manifests
182 adding manifests
183 adding file changes
183 adding file changes
184 added 40 changesets with 40 changes to 40 files
184 added 40 changesets with 40 changes to 40 files
185 new changesets * (glob)
185 new changesets * (glob)
186 updating to branch default
186 updating to branch default
187 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
188 $ cd simpleclone
188 $ cd simpleclone
189 $ find * | sort
189 $ find * | sort
190 dir
190 dir
191 dir/src
191 dir/src
192 dir/src/f1
192 dir/src/f1
193 dir/src/f10
193 dir/src/f10
194 dir/src/f11
194 dir/src/f11
195 dir/src/f12
195 dir/src/f12
196 dir/src/f13
196 dir/src/f13
197 dir/src/f14
197 dir/src/f14
198 dir/src/f15
198 dir/src/f15
199 dir/src/f16
199 dir/src/f16
200 dir/src/f17
200 dir/src/f17
201 dir/src/f18
201 dir/src/f18
202 dir/src/f19
202 dir/src/f19
203 dir/src/f2
203 dir/src/f2
204 dir/src/f20
204 dir/src/f20
205 dir/src/f3
205 dir/src/f3
206 dir/src/f4
206 dir/src/f4
207 dir/src/f5
207 dir/src/f5
208 dir/src/f6
208 dir/src/f6
209 dir/src/f7
209 dir/src/f7
210 dir/src/f8
210 dir/src/f8
211 dir/src/f9
211 dir/src/f9
212 dir/tests
212 dir/tests
213 dir/tests/t1
213 dir/tests/t1
214 dir/tests/t10
214 dir/tests/t10
215 dir/tests/t11
215 dir/tests/t11
216 dir/tests/t12
216 dir/tests/t12
217 dir/tests/t13
217 dir/tests/t13
218 dir/tests/t14
218 dir/tests/t14
219 dir/tests/t15
219 dir/tests/t15
220 dir/tests/t16
220 dir/tests/t16
221 dir/tests/t17
221 dir/tests/t17
222 dir/tests/t18
222 dir/tests/t18
223 dir/tests/t19
223 dir/tests/t19
224 dir/tests/t2
224 dir/tests/t2
225 dir/tests/t20
225 dir/tests/t20
226 dir/tests/t3
226 dir/tests/t3
227 dir/tests/t4
227 dir/tests/t4
228 dir/tests/t5
228 dir/tests/t5
229 dir/tests/t6
229 dir/tests/t6
230 dir/tests/t7
230 dir/tests/t7
231 dir/tests/t8
231 dir/tests/t8
232 dir/tests/t9
232 dir/tests/t9
233
233
234 $ cd ..
234 $ cd ..
235
235
236 Testing the --narrowspec flag to clone
236 Testing the --narrowspec flag to clone
237
237
238 $ cat >> narrowspecs <<EOF
238 $ cat >> narrowspecs <<EOF
239 > %include foo
239 > %include foo
240 > [include]
240 > [include]
241 > path:dir/tests/
241 > path:dir/tests/
242 > dir/src/f12
242 > path:file:dir/src/f12
243 > EOF
243 > EOF
244
244
245 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
245 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
246 reading narrowspec from '$TESTTMP/narrowspecs'
246 reading narrowspec from '$TESTTMP/narrowspecs'
247 abort: cannot specify other files using '%include' in narrowspec
247 abort: cannot specify other files using '%include' in narrowspec
248 [255]
248 [255]
249
249
250 $ cat > narrowspecs <<EOF
250 $ cat > narrowspecs <<EOF
251 > [include]
251 > [include]
252 > path:dir/tests/
252 > path:dir/tests/
253 > file:dir/src/f12
253 > path:file:dir/src/f12
254 > EOF
254 > EOF
255
255
256 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
256 $ hg clone ssh://user@dummy/master specfile --narrowspec narrowspecs
257 reading narrowspec from '$TESTTMP/narrowspecs'
257 reading narrowspec from '$TESTTMP/narrowspecs'
258 requesting all changes
258 requesting all changes
259 adding changesets
259 adding changesets
260 adding manifests
260 adding manifests
261 adding file changes
261 adding file changes
262 added 21 changesets with 20 changes to 20 files
262 added 21 changesets with 20 changes to 20 files
263 new changesets f93383bb3e99:26ce255d5b5d
263 new changesets f93383bb3e99:26ce255d5b5d
264 updating to branch default
264 updating to branch default
265 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
266 $ cd specfile
266 $ cd specfile
267 $ hg tracked
267 $ hg tracked
268 I path:dir/tests
268 I path:dir/tests
269 I path:file:dir/src/f12
269 I path:file:dir/src/f12
270 $ cd ..
270 $ cd ..
271
271
272 Narrow spec with invalid patterns is rejected
272 Narrow spec with invalid patterns is rejected
273
273
274 $ cat > narrowspecs <<EOF
274 $ cat > narrowspecs <<EOF
275 > [include]
275 > [include]
276 > glob:**
276 > glob:**
277 > EOF
277 > EOF
278
278
279 $ hg clone ssh://user@dummy/master badspecfile --narrowspec narrowspecs
279 $ hg clone ssh://user@dummy/master badspecfile --narrowspec narrowspecs
280 reading narrowspec from '$TESTTMP/narrowspecs'
280 reading narrowspec from '$TESTTMP/narrowspecs'
281 requesting all changes
282 abort: invalid prefix on narrow pattern: glob:**
281 abort: invalid prefix on narrow pattern: glob:**
283 (narrow patterns must begin with one of the following: path:, rootfilesin:)
282 (narrow patterns must begin with one of the following: path:, rootfilesin:)
284 [255]
283 [255]
General Comments 0
You need to be logged in to leave comments. Login now