##// END OF EJS Templates
narrow: update the narrowspecs to new ones after pulling when widening...
Pulkit Goyal -
r39393:2b8adb7c default
parent child Browse files
Show More
@@ -1,429 +1,430 b''
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 error,
17 error,
18 exchange,
18 exchange,
19 extensions,
19 extensions,
20 hg,
20 hg,
21 merge,
21 merge,
22 narrowspec,
22 narrowspec,
23 node,
23 node,
24 pycompat,
24 pycompat,
25 registrar,
25 registrar,
26 repair,
26 repair,
27 repository,
27 repository,
28 repoview,
28 repoview,
29 sparse,
29 sparse,
30 util,
30 util,
31 )
31 )
32
32
33 from . import (
33 from . import (
34 narrowbundle2,
34 narrowbundle2,
35 )
35 )
36
36
37 table = {}
37 table = {}
38 command = registrar.command(table)
38 command = registrar.command(table)
39
39
40 def setup():
40 def setup():
41 """Wraps user-facing mercurial commands with narrow-aware versions."""
41 """Wraps user-facing mercurial commands with narrow-aware versions."""
42
42
43 entry = extensions.wrapcommand(commands.table, 'clone', clonenarrowcmd)
43 entry = extensions.wrapcommand(commands.table, 'clone', clonenarrowcmd)
44 entry[1].append(('', 'narrow', None,
44 entry[1].append(('', 'narrow', None,
45 _("create a narrow clone of select files")))
45 _("create a narrow clone of select files")))
46 entry[1].append(('', 'depth', '',
46 entry[1].append(('', 'depth', '',
47 _("limit the history fetched by distance from heads")))
47 _("limit the history fetched by distance from heads")))
48 entry[1].append(('', 'narrowspec', '',
48 entry[1].append(('', 'narrowspec', '',
49 _("read narrowspecs from file")))
49 _("read narrowspecs from file")))
50 # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit
50 # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit
51 if 'sparse' not in extensions.enabled():
51 if 'sparse' not in extensions.enabled():
52 entry[1].append(('', 'include', [],
52 entry[1].append(('', 'include', [],
53 _("specifically fetch this file/directory")))
53 _("specifically fetch this file/directory")))
54 entry[1].append(
54 entry[1].append(
55 ('', 'exclude', [],
55 ('', 'exclude', [],
56 _("do not fetch this file/directory, even if included")))
56 _("do not fetch this file/directory, even if included")))
57
57
58 entry = extensions.wrapcommand(commands.table, 'pull', pullnarrowcmd)
58 entry = extensions.wrapcommand(commands.table, 'pull', pullnarrowcmd)
59 entry[1].append(('', 'depth', '',
59 entry[1].append(('', 'depth', '',
60 _("limit the history fetched by distance from heads")))
60 _("limit the history fetched by distance from heads")))
61
61
62 extensions.wrapcommand(commands.table, 'archive', archivenarrowcmd)
62 extensions.wrapcommand(commands.table, 'archive', archivenarrowcmd)
63
63
64 def expandpull(pullop, includepats, excludepats):
64 def expandpull(pullop, includepats, excludepats):
65 if not narrowspec.needsexpansion(includepats):
65 if not narrowspec.needsexpansion(includepats):
66 return includepats, excludepats
66 return includepats, excludepats
67
67
68 heads = pullop.heads or pullop.rheads
68 heads = pullop.heads or pullop.rheads
69 includepats, excludepats = pullop.remote.expandnarrow(
69 includepats, excludepats = pullop.remote.expandnarrow(
70 includepats, excludepats, heads)
70 includepats, excludepats, heads)
71 pullop.repo.ui.debug('Expanded narrowspec to inc=%s, exc=%s\n' % (
71 pullop.repo.ui.debug('Expanded narrowspec to inc=%s, exc=%s\n' % (
72 includepats, excludepats))
72 includepats, excludepats))
73 return set(includepats), set(excludepats)
73 return set(includepats), set(excludepats)
74
74
75 def clonenarrowcmd(orig, ui, repo, *args, **opts):
75 def clonenarrowcmd(orig, ui, repo, *args, **opts):
76 """Wraps clone command, so 'hg clone' first wraps localrepo.clone()."""
76 """Wraps clone command, so 'hg clone' first wraps localrepo.clone()."""
77 opts = pycompat.byteskwargs(opts)
77 opts = pycompat.byteskwargs(opts)
78 wrappedextraprepare = util.nullcontextmanager()
78 wrappedextraprepare = util.nullcontextmanager()
79 opts_narrow = opts['narrow']
79 opts_narrow = opts['narrow']
80 narrowspecfile = opts['narrowspec']
80 narrowspecfile = opts['narrowspec']
81
81
82 if narrowspecfile:
82 if narrowspecfile:
83 filepath = os.path.join(pycompat.getcwd(), narrowspecfile)
83 filepath = os.path.join(pycompat.getcwd(), narrowspecfile)
84 ui.status(_("reading narrowspec from '%s'\n") % filepath)
84 ui.status(_("reading narrowspec from '%s'\n") % filepath)
85 try:
85 try:
86 fp = open(filepath, 'rb')
86 fp = open(filepath, 'rb')
87 except IOError:
87 except IOError:
88 raise error.Abort(_("file '%s' not found") % filepath)
88 raise error.Abort(_("file '%s' not found") % filepath)
89
89
90 includes, excludes, profiles = sparse.parseconfig(ui, fp.read(),
90 includes, excludes, profiles = sparse.parseconfig(ui, fp.read(),
91 'narrow')
91 'narrow')
92 if profiles:
92 if profiles:
93 raise error.Abort(_("cannot specify other files using '%include' in"
93 raise error.Abort(_("cannot specify other files using '%include' in"
94 " narrowspec"))
94 " narrowspec"))
95
95
96 # narrowspec is passed so we should assume that user wants narrow clone
96 # narrowspec is passed so we should assume that user wants narrow clone
97 opts_narrow = True
97 opts_narrow = True
98 opts['include'].extend(includes)
98 opts['include'].extend(includes)
99 opts['exclude'].extend(excludes)
99 opts['exclude'].extend(excludes)
100
100
101 if opts_narrow:
101 if opts_narrow:
102 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
102 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
103 # Create narrow spec patterns from clone flags
103 # Create narrow spec patterns from clone flags
104 includepats = narrowspec.parsepatterns(opts['include'])
104 includepats = narrowspec.parsepatterns(opts['include'])
105 excludepats = narrowspec.parsepatterns(opts['exclude'])
105 excludepats = narrowspec.parsepatterns(opts['exclude'])
106
106
107 # If necessary, ask the server to expand the narrowspec.
107 # If necessary, ask the server to expand the narrowspec.
108 includepats, excludepats = expandpull(
108 includepats, excludepats = expandpull(
109 pullop, includepats, excludepats)
109 pullop, includepats, excludepats)
110
110
111 if not includepats and excludepats:
111 if not includepats and excludepats:
112 # If nothing was included, we assume the user meant to include
112 # If nothing was included, we assume the user meant to include
113 # everything, except what they asked to exclude.
113 # everything, except what they asked to exclude.
114 includepats = {'path:.'}
114 includepats = {'path:.'}
115
115
116 pullop.repo.setnarrowpats(includepats, excludepats)
116 pullop.repo.setnarrowpats(includepats, excludepats)
117
117
118 # This will populate 'includepats' etc with the values from the
118 # This will populate 'includepats' etc with the values from the
119 # narrowspec we just saved.
119 # narrowspec we just saved.
120 orig(pullop, kwargs)
120 orig(pullop, kwargs)
121
121
122 if opts.get('depth'):
122 if opts.get('depth'):
123 kwargs['depth'] = opts['depth']
123 kwargs['depth'] = opts['depth']
124 wrappedextraprepare = extensions.wrappedfunction(exchange,
124 wrappedextraprepare = extensions.wrappedfunction(exchange,
125 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
125 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
126
126
127 def pullnarrow(orig, repo, *args, **kwargs):
127 def pullnarrow(orig, repo, *args, **kwargs):
128 if opts_narrow:
128 if opts_narrow:
129 repo.requirements.add(repository.NARROW_REQUIREMENT)
129 repo.requirements.add(repository.NARROW_REQUIREMENT)
130 repo._writerequirements()
130 repo._writerequirements()
131
131
132 return orig(repo, *args, **kwargs)
132 return orig(repo, *args, **kwargs)
133
133
134 wrappedpull = extensions.wrappedfunction(exchange, 'pull', pullnarrow)
134 wrappedpull = extensions.wrappedfunction(exchange, 'pull', pullnarrow)
135
135
136 with wrappedextraprepare, wrappedpull:
136 with wrappedextraprepare, wrappedpull:
137 return orig(ui, repo, *args, **pycompat.strkwargs(opts))
137 return orig(ui, repo, *args, **pycompat.strkwargs(opts))
138
138
139 def pullnarrowcmd(orig, ui, repo, *args, **opts):
139 def pullnarrowcmd(orig, ui, repo, *args, **opts):
140 """Wraps pull command to allow modifying narrow spec."""
140 """Wraps pull command to allow modifying narrow spec."""
141 wrappedextraprepare = util.nullcontextmanager()
141 wrappedextraprepare = util.nullcontextmanager()
142 if repository.NARROW_REQUIREMENT in repo.requirements:
142 if repository.NARROW_REQUIREMENT in repo.requirements:
143
143
144 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
144 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
145 orig(pullop, kwargs)
145 orig(pullop, kwargs)
146 if opts.get(r'depth'):
146 if opts.get(r'depth'):
147 kwargs['depth'] = opts[r'depth']
147 kwargs['depth'] = opts[r'depth']
148 wrappedextraprepare = extensions.wrappedfunction(exchange,
148 wrappedextraprepare = extensions.wrappedfunction(exchange,
149 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
149 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
150
150
151 with wrappedextraprepare:
151 with wrappedextraprepare:
152 return orig(ui, repo, *args, **opts)
152 return orig(ui, repo, *args, **opts)
153
153
154 def archivenarrowcmd(orig, ui, repo, *args, **opts):
154 def archivenarrowcmd(orig, ui, repo, *args, **opts):
155 """Wraps archive command to narrow the default includes."""
155 """Wraps archive command to narrow the default includes."""
156 if repository.NARROW_REQUIREMENT in repo.requirements:
156 if repository.NARROW_REQUIREMENT in repo.requirements:
157 repo_includes, repo_excludes = repo.narrowpats
157 repo_includes, repo_excludes = repo.narrowpats
158 includes = set(opts.get(r'include', []))
158 includes = set(opts.get(r'include', []))
159 excludes = set(opts.get(r'exclude', []))
159 excludes = set(opts.get(r'exclude', []))
160 includes, excludes, unused_invalid = narrowspec.restrictpatterns(
160 includes, excludes, unused_invalid = narrowspec.restrictpatterns(
161 includes, excludes, repo_includes, repo_excludes)
161 includes, excludes, repo_includes, repo_excludes)
162 if includes:
162 if includes:
163 opts[r'include'] = includes
163 opts[r'include'] = includes
164 if excludes:
164 if excludes:
165 opts[r'exclude'] = excludes
165 opts[r'exclude'] = excludes
166 return orig(ui, repo, *args, **opts)
166 return orig(ui, repo, *args, **opts)
167
167
168 def pullbundle2extraprepare(orig, pullop, kwargs):
168 def pullbundle2extraprepare(orig, pullop, kwargs):
169 repo = pullop.repo
169 repo = pullop.repo
170 if repository.NARROW_REQUIREMENT not in repo.requirements:
170 if repository.NARROW_REQUIREMENT not in repo.requirements:
171 return orig(pullop, kwargs)
171 return orig(pullop, kwargs)
172
172
173 if narrowbundle2.NARROWCAP not in pullop.remotebundle2caps:
173 if narrowbundle2.NARROWCAP not in pullop.remotebundle2caps:
174 raise error.Abort(_("server doesn't support narrow clones"))
174 raise error.Abort(_("server doesn't support narrow clones"))
175 orig(pullop, kwargs)
175 orig(pullop, kwargs)
176 kwargs['narrow'] = True
176 kwargs['narrow'] = True
177 include, exclude = repo.narrowpats
177 include, exclude = repo.narrowpats
178 kwargs['oldincludepats'] = include
178 kwargs['oldincludepats'] = include
179 kwargs['oldexcludepats'] = exclude
179 kwargs['oldexcludepats'] = exclude
180 kwargs['includepats'] = include
180 kwargs['includepats'] = include
181 kwargs['excludepats'] = exclude
181 kwargs['excludepats'] = exclude
182 kwargs['known'] = [node.hex(ctx.node()) for ctx in
182 kwargs['known'] = [node.hex(ctx.node()) for ctx in
183 repo.set('::%ln', pullop.common)
183 repo.set('::%ln', pullop.common)
184 if ctx.node() != node.nullid]
184 if ctx.node() != node.nullid]
185 if not kwargs['known']:
185 if not kwargs['known']:
186 # Mercurial serialized an empty list as '' and deserializes it as
186 # Mercurial serialized an empty list as '' and deserializes it as
187 # [''], so delete it instead to avoid handling the empty string on the
187 # [''], so delete it instead to avoid handling the empty string on the
188 # server.
188 # server.
189 del kwargs['known']
189 del kwargs['known']
190
190
191 extensions.wrapfunction(exchange,'_pullbundle2extraprepare',
191 extensions.wrapfunction(exchange,'_pullbundle2extraprepare',
192 pullbundle2extraprepare)
192 pullbundle2extraprepare)
193
193
194 def _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
194 def _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
195 newincludes, newexcludes, force):
195 newincludes, newexcludes, force):
196 oldmatch = narrowspec.match(repo.root, oldincludes, oldexcludes)
196 oldmatch = narrowspec.match(repo.root, oldincludes, oldexcludes)
197 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
197 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
198
198
199 # This is essentially doing "hg outgoing" to find all local-only
199 # This is essentially doing "hg outgoing" to find all local-only
200 # commits. We will then check that the local-only commits don't
200 # commits. We will then check that the local-only commits don't
201 # have any changes to files that will be untracked.
201 # have any changes to files that will be untracked.
202 unfi = repo.unfiltered()
202 unfi = repo.unfiltered()
203 outgoing = discovery.findcommonoutgoing(unfi, remote,
203 outgoing = discovery.findcommonoutgoing(unfi, remote,
204 commoninc=commoninc)
204 commoninc=commoninc)
205 ui.status(_('looking for local changes to affected paths\n'))
205 ui.status(_('looking for local changes to affected paths\n'))
206 localnodes = []
206 localnodes = []
207 for n in itertools.chain(outgoing.missing, outgoing.excluded):
207 for n in itertools.chain(outgoing.missing, outgoing.excluded):
208 if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()):
208 if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()):
209 localnodes.append(n)
209 localnodes.append(n)
210 revstostrip = unfi.revs('descendants(%ln)', localnodes)
210 revstostrip = unfi.revs('descendants(%ln)', localnodes)
211 hiddenrevs = repoview.filterrevs(repo, 'visible')
211 hiddenrevs = repoview.filterrevs(repo, 'visible')
212 visibletostrip = list(repo.changelog.node(r)
212 visibletostrip = list(repo.changelog.node(r)
213 for r in (revstostrip - hiddenrevs))
213 for r in (revstostrip - hiddenrevs))
214 if visibletostrip:
214 if visibletostrip:
215 ui.status(_('The following changeset(s) or their ancestors have '
215 ui.status(_('The following changeset(s) or their ancestors have '
216 'local changes not on the remote:\n'))
216 'local changes not on the remote:\n'))
217 maxnodes = 10
217 maxnodes = 10
218 if ui.verbose or len(visibletostrip) <= maxnodes:
218 if ui.verbose or len(visibletostrip) <= maxnodes:
219 for n in visibletostrip:
219 for n in visibletostrip:
220 ui.status('%s\n' % node.short(n))
220 ui.status('%s\n' % node.short(n))
221 else:
221 else:
222 for n in visibletostrip[:maxnodes]:
222 for n in visibletostrip[:maxnodes]:
223 ui.status('%s\n' % node.short(n))
223 ui.status('%s\n' % node.short(n))
224 ui.status(_('...and %d more, use --verbose to list all\n') %
224 ui.status(_('...and %d more, use --verbose to list all\n') %
225 (len(visibletostrip) - maxnodes))
225 (len(visibletostrip) - maxnodes))
226 if not force:
226 if not force:
227 raise error.Abort(_('local changes found'),
227 raise error.Abort(_('local changes found'),
228 hint=_('use --force-delete-local-changes to '
228 hint=_('use --force-delete-local-changes to '
229 'ignore'))
229 'ignore'))
230
230
231 with ui.uninterruptable():
231 with ui.uninterruptable():
232 if revstostrip:
232 if revstostrip:
233 tostrip = [unfi.changelog.node(r) for r in revstostrip]
233 tostrip = [unfi.changelog.node(r) for r in revstostrip]
234 if repo['.'].node() in tostrip:
234 if repo['.'].node() in tostrip:
235 # stripping working copy, so move to a different commit first
235 # stripping working copy, so move to a different commit first
236 urev = max(repo.revs('(::%n) - %ln + null',
236 urev = max(repo.revs('(::%n) - %ln + null',
237 repo['.'].node(), visibletostrip))
237 repo['.'].node(), visibletostrip))
238 hg.clean(repo, urev)
238 hg.clean(repo, urev)
239 repair.strip(ui, unfi, tostrip, topic='narrow')
239 repair.strip(ui, unfi, tostrip, topic='narrow')
240
240
241 todelete = []
241 todelete = []
242 for f, f2, size in repo.store.datafiles():
242 for f, f2, size in repo.store.datafiles():
243 if f.startswith('data/'):
243 if f.startswith('data/'):
244 file = f[5:-2]
244 file = f[5:-2]
245 if not newmatch(file):
245 if not newmatch(file):
246 todelete.append(f)
246 todelete.append(f)
247 elif f.startswith('meta/'):
247 elif f.startswith('meta/'):
248 dir = f[5:-13]
248 dir = f[5:-13]
249 dirs = ['.'] + sorted(util.dirs({dir})) + [dir]
249 dirs = ['.'] + sorted(util.dirs({dir})) + [dir]
250 include = True
250 include = True
251 for d in dirs:
251 for d in dirs:
252 visit = newmatch.visitdir(d)
252 visit = newmatch.visitdir(d)
253 if not visit:
253 if not visit:
254 include = False
254 include = False
255 break
255 break
256 if visit == 'all':
256 if visit == 'all':
257 break
257 break
258 if not include:
258 if not include:
259 todelete.append(f)
259 todelete.append(f)
260
260
261 repo.destroying()
261 repo.destroying()
262
262
263 with repo.transaction("narrowing"):
263 with repo.transaction("narrowing"):
264 for f in todelete:
264 for f in todelete:
265 ui.status(_('deleting %s\n') % f)
265 ui.status(_('deleting %s\n') % f)
266 util.unlinkpath(repo.svfs.join(f))
266 util.unlinkpath(repo.svfs.join(f))
267 repo.store.markremoved(f)
267 repo.store.markremoved(f)
268
268
269 for f in repo.dirstate:
269 for f in repo.dirstate:
270 if not newmatch(f):
270 if not newmatch(f):
271 repo.dirstate.drop(f)
271 repo.dirstate.drop(f)
272 repo.wvfs.unlinkpath(f)
272 repo.wvfs.unlinkpath(f)
273 repo.setnarrowpats(newincludes, newexcludes)
273 repo.setnarrowpats(newincludes, newexcludes)
274
274
275 repo.destroyed()
275 repo.destroyed()
276
276
277 def _widen(ui, repo, remote, commoninc, newincludes, newexcludes):
277 def _widen(ui, repo, remote, commoninc, newincludes, newexcludes):
278 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
278 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
279
279
280 # TODO(martinvonz): Get expansion working with widening/narrowing.
280 # TODO(martinvonz): Get expansion working with widening/narrowing.
281 if narrowspec.needsexpansion(newincludes):
281 if narrowspec.needsexpansion(newincludes):
282 raise error.Abort('Expansion not yet supported on pull')
282 raise error.Abort('Expansion not yet supported on pull')
283
283
284 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
284 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
285 orig(pullop, kwargs)
285 orig(pullop, kwargs)
286 # The old{in,ex}cludepats have already been set by orig()
286 # The old{in,ex}cludepats have already been set by orig()
287 kwargs['includepats'] = newincludes
287 kwargs['includepats'] = newincludes
288 kwargs['excludepats'] = newexcludes
288 kwargs['excludepats'] = newexcludes
289 kwargs['widen'] = True
289 kwargs['widen'] = True
290 wrappedextraprepare = extensions.wrappedfunction(exchange,
290 wrappedextraprepare = extensions.wrappedfunction(exchange,
291 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
291 '_pullbundle2extraprepare', pullbundle2extraprepare_widen)
292
292
293 # define a function that narrowbundle2 can call after creating the
293 # define a function that narrowbundle2 can call after creating the
294 # backup bundle, but before applying the bundle from the server
294 # backup bundle, but before applying the bundle from the server
295 def setnewnarrowpats():
295 def setnewnarrowpats():
296 repo.setnarrowpats(newincludes, newexcludes)
296 repo.setnarrowpats(newincludes, newexcludes)
297 repo.setnewnarrowpats = setnewnarrowpats
297 repo.setnewnarrowpats = setnewnarrowpats
298
298
299 with ui.uninterruptable():
299 with ui.uninterruptable():
300 ds = repo.dirstate
300 ds = repo.dirstate
301 p1, p2 = ds.p1(), ds.p2()
301 p1, p2 = ds.p1(), ds.p2()
302 with ds.parentchange():
302 with ds.parentchange():
303 ds.setparents(node.nullid, node.nullid)
303 ds.setparents(node.nullid, node.nullid)
304 common = commoninc[0]
304 common = commoninc[0]
305 with wrappedextraprepare:
305 with wrappedextraprepare:
306 exchange.pull(repo, remote, heads=common)
306 exchange.pull(repo, remote, heads=common)
307 with ds.parentchange():
307 with ds.parentchange():
308 ds.setparents(p1, p2)
308 ds.setparents(p1, p2)
309
309
310 repo.setnewnarrowpats()
310 actions = {k: [] for k in 'a am f g cd dc r dm dg m e k p pr'.split()}
311 actions = {k: [] for k in 'a am f g cd dc r dm dg m e k p pr'.split()}
311 addgaction = actions['g'].append
312 addgaction = actions['g'].append
312
313
313 mf = repo['.'].manifest().matches(newmatch)
314 mf = repo['.'].manifest().matches(newmatch)
314 for f, fn in mf.iteritems():
315 for f, fn in mf.iteritems():
315 if f not in repo.dirstate:
316 if f not in repo.dirstate:
316 addgaction((f, (mf.flags(f), False),
317 addgaction((f, (mf.flags(f), False),
317 "add from widened narrow clone"))
318 "add from widened narrow clone"))
318
319
319 merge.applyupdates(repo, actions, wctx=repo[None],
320 merge.applyupdates(repo, actions, wctx=repo[None],
320 mctx=repo['.'], overwrite=False)
321 mctx=repo['.'], overwrite=False)
321 merge.recordupdates(repo, actions, branchmerge=False)
322 merge.recordupdates(repo, actions, branchmerge=False)
322
323
323 # TODO(rdamazio): Make new matcher format and update description
324 # TODO(rdamazio): Make new matcher format and update description
324 @command('tracked',
325 @command('tracked',
325 [('', 'addinclude', [], _('new paths to include')),
326 [('', 'addinclude', [], _('new paths to include')),
326 ('', 'removeinclude', [], _('old paths to no longer include')),
327 ('', 'removeinclude', [], _('old paths to no longer include')),
327 ('', 'addexclude', [], _('new paths to exclude')),
328 ('', 'addexclude', [], _('new paths to exclude')),
328 ('', 'removeexclude', [], _('old paths to no longer exclude')),
329 ('', 'removeexclude', [], _('old paths to no longer exclude')),
329 ('', 'clear', False, _('whether to replace the existing narrowspec')),
330 ('', 'clear', False, _('whether to replace the existing narrowspec')),
330 ('', 'force-delete-local-changes', False,
331 ('', 'force-delete-local-changes', False,
331 _('forces deletion of local changes when narrowing')),
332 _('forces deletion of local changes when narrowing')),
332 ] + commands.remoteopts,
333 ] + commands.remoteopts,
333 _('[OPTIONS]... [REMOTE]'),
334 _('[OPTIONS]... [REMOTE]'),
334 inferrepo=True)
335 inferrepo=True)
335 def trackedcmd(ui, repo, remotepath=None, *pats, **opts):
336 def trackedcmd(ui, repo, remotepath=None, *pats, **opts):
336 """show or change the current narrowspec
337 """show or change the current narrowspec
337
338
338 With no argument, shows the current narrowspec entries, one per line. Each
339 With no argument, shows the current narrowspec entries, one per line. Each
339 line will be prefixed with 'I' or 'X' for included or excluded patterns,
340 line will be prefixed with 'I' or 'X' for included or excluded patterns,
340 respectively.
341 respectively.
341
342
342 The narrowspec is comprised of expressions to match remote files and/or
343 The narrowspec is comprised of expressions to match remote files and/or
343 directories that should be pulled into your client.
344 directories that should be pulled into your client.
344 The narrowspec has *include* and *exclude* expressions, with excludes always
345 The narrowspec has *include* and *exclude* expressions, with excludes always
345 trumping includes: that is, if a file matches an exclude expression, it will
346 trumping includes: that is, if a file matches an exclude expression, it will
346 be excluded even if it also matches an include expression.
347 be excluded even if it also matches an include expression.
347 Excluding files that were never included has no effect.
348 Excluding files that were never included has no effect.
348
349
349 Each included or excluded entry is in the format described by
350 Each included or excluded entry is in the format described by
350 'hg help patterns'.
351 'hg help patterns'.
351
352
352 The options allow you to add or remove included and excluded expressions.
353 The options allow you to add or remove included and excluded expressions.
353
354
354 If --clear is specified, then all previous includes and excludes are DROPPED
355 If --clear is specified, then all previous includes and excludes are DROPPED
355 and replaced by the new ones specified to --addinclude and --addexclude.
356 and replaced by the new ones specified to --addinclude and --addexclude.
356 If --clear is specified without any further options, the narrowspec will be
357 If --clear is specified without any further options, the narrowspec will be
357 empty and will not match any files.
358 empty and will not match any files.
358 """
359 """
359 opts = pycompat.byteskwargs(opts)
360 opts = pycompat.byteskwargs(opts)
360 if repository.NARROW_REQUIREMENT not in repo.requirements:
361 if repository.NARROW_REQUIREMENT not in repo.requirements:
361 ui.warn(_('The narrow command is only supported on respositories cloned'
362 ui.warn(_('The narrow command is only supported on respositories cloned'
362 ' with --narrow.\n'))
363 ' with --narrow.\n'))
363 return 1
364 return 1
364
365
365 # Before supporting, decide whether it "hg tracked --clear" should mean
366 # Before supporting, decide whether it "hg tracked --clear" should mean
366 # tracking no paths or all paths.
367 # tracking no paths or all paths.
367 if opts['clear']:
368 if opts['clear']:
368 ui.warn(_('The --clear option is not yet supported.\n'))
369 ui.warn(_('The --clear option is not yet supported.\n'))
369 return 1
370 return 1
370
371
371 if narrowspec.needsexpansion(opts['addinclude'] + opts['addexclude']):
372 if narrowspec.needsexpansion(opts['addinclude'] + opts['addexclude']):
372 raise error.Abort('Expansion not yet supported on widen/narrow')
373 raise error.Abort('Expansion not yet supported on widen/narrow')
373
374
374 addedincludes = narrowspec.parsepatterns(opts['addinclude'])
375 addedincludes = narrowspec.parsepatterns(opts['addinclude'])
375 removedincludes = narrowspec.parsepatterns(opts['removeinclude'])
376 removedincludes = narrowspec.parsepatterns(opts['removeinclude'])
376 addedexcludes = narrowspec.parsepatterns(opts['addexclude'])
377 addedexcludes = narrowspec.parsepatterns(opts['addexclude'])
377 removedexcludes = narrowspec.parsepatterns(opts['removeexclude'])
378 removedexcludes = narrowspec.parsepatterns(opts['removeexclude'])
378 widening = addedincludes or removedexcludes
379 widening = addedincludes or removedexcludes
379 narrowing = removedincludes or addedexcludes
380 narrowing = removedincludes or addedexcludes
380 only_show = not widening and not narrowing
381 only_show = not widening and not narrowing
381
382
382 # Only print the current narrowspec.
383 # Only print the current narrowspec.
383 if only_show:
384 if only_show:
384 include, exclude = repo.narrowpats
385 include, exclude = repo.narrowpats
385
386
386 ui.pager('tracked')
387 ui.pager('tracked')
387 fm = ui.formatter('narrow', opts)
388 fm = ui.formatter('narrow', opts)
388 for i in sorted(include):
389 for i in sorted(include):
389 fm.startitem()
390 fm.startitem()
390 fm.write('status', '%s ', 'I', label='narrow.included')
391 fm.write('status', '%s ', 'I', label='narrow.included')
391 fm.write('pat', '%s\n', i, label='narrow.included')
392 fm.write('pat', '%s\n', i, label='narrow.included')
392 for i in sorted(exclude):
393 for i in sorted(exclude):
393 fm.startitem()
394 fm.startitem()
394 fm.write('status', '%s ', 'X', label='narrow.excluded')
395 fm.write('status', '%s ', 'X', label='narrow.excluded')
395 fm.write('pat', '%s\n', i, label='narrow.excluded')
396 fm.write('pat', '%s\n', i, label='narrow.excluded')
396 fm.end()
397 fm.end()
397 return 0
398 return 0
398
399
399 with repo.wlock(), repo.lock():
400 with repo.wlock(), repo.lock():
400 cmdutil.bailifchanged(repo)
401 cmdutil.bailifchanged(repo)
401
402
402 # Find the revisions we have in common with the remote. These will
403 # Find the revisions we have in common with the remote. These will
403 # be used for finding local-only changes for narrowing. They will
404 # be used for finding local-only changes for narrowing. They will
404 # also define the set of revisions to update for widening.
405 # also define the set of revisions to update for widening.
405 remotepath = ui.expandpath(remotepath or 'default')
406 remotepath = ui.expandpath(remotepath or 'default')
406 url, branches = hg.parseurl(remotepath)
407 url, branches = hg.parseurl(remotepath)
407 ui.status(_('comparing with %s\n') % util.hidepassword(url))
408 ui.status(_('comparing with %s\n') % util.hidepassword(url))
408 remote = hg.peer(repo, opts, url)
409 remote = hg.peer(repo, opts, url)
409 commoninc = discovery.findcommonincoming(repo, remote)
410 commoninc = discovery.findcommonincoming(repo, remote)
410
411
411 oldincludes, oldexcludes = repo.narrowpats
412 oldincludes, oldexcludes = repo.narrowpats
412 if narrowing:
413 if narrowing:
413 newincludes = oldincludes - removedincludes
414 newincludes = oldincludes - removedincludes
414 newexcludes = oldexcludes | addedexcludes
415 newexcludes = oldexcludes | addedexcludes
415 _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
416 _narrow(ui, repo, remote, commoninc, oldincludes, oldexcludes,
416 newincludes, newexcludes,
417 newincludes, newexcludes,
417 opts['force_delete_local_changes'])
418 opts['force_delete_local_changes'])
418 # _narrow() updated the narrowspec and _widen() below needs to
419 # _narrow() updated the narrowspec and _widen() below needs to
419 # use the updated values as its base (otherwise removed includes
420 # use the updated values as its base (otherwise removed includes
420 # and addedexcludes will be lost in the resulting narrowspec)
421 # and addedexcludes will be lost in the resulting narrowspec)
421 oldincludes = newincludes
422 oldincludes = newincludes
422 oldexcludes = newexcludes
423 oldexcludes = newexcludes
423
424
424 if widening:
425 if widening:
425 newincludes = oldincludes | addedincludes
426 newincludes = oldincludes | addedincludes
426 newexcludes = oldexcludes - removedexcludes
427 newexcludes = oldexcludes - removedexcludes
427 _widen(ui, repo, remote, commoninc, newincludes, newexcludes)
428 _widen(ui, repo, remote, commoninc, newincludes, newexcludes)
428
429
429 return 0
430 return 0
@@ -1,397 +1,381 b''
1 $ . "$TESTDIR/narrow-library.sh"
1 $ . "$TESTDIR/narrow-library.sh"
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [experimental]
4 > [experimental]
5 > treemanifest = 1
5 > treemanifest = 1
6 > EOF
6 > EOF
7
7
8 $ hg init master
8 $ hg init master
9 $ cd master
9 $ cd master
10
10
11 $ mkdir inside
11 $ mkdir inside
12 $ echo 'inside' > inside/f
12 $ echo 'inside' > inside/f
13 $ hg add inside/f
13 $ hg add inside/f
14 $ hg commit -m 'add inside'
14 $ hg commit -m 'add inside'
15
15
16 $ mkdir widest
16 $ mkdir widest
17 $ echo 'widest' > widest/f
17 $ echo 'widest' > widest/f
18 $ hg add widest/f
18 $ hg add widest/f
19 $ hg commit -m 'add widest'
19 $ hg commit -m 'add widest'
20
20
21 $ mkdir outside
21 $ mkdir outside
22 $ echo 'outside' > outside/f
22 $ echo 'outside' > outside/f
23 $ hg add outside/f
23 $ hg add outside/f
24 $ hg commit -m 'add outside'
24 $ hg commit -m 'add outside'
25
25
26 $ cd ..
26 $ cd ..
27
27
28 narrow clone the inside file
28 narrow clone the inside file
29
29
30 $ hg clone --narrow ssh://user@dummy/master narrow --include inside
30 $ hg clone --narrow ssh://user@dummy/master narrow --include inside
31 requesting all changes
31 requesting all changes
32 adding changesets
32 adding changesets
33 adding manifests
33 adding manifests
34 adding file changes
34 adding file changes
35 added 3 changesets with 1 changes to 1 files
35 added 3 changesets with 1 changes to 1 files
36 new changesets *:* (glob)
36 new changesets *:* (glob)
37 updating to branch default
37 updating to branch default
38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
39 $ cd narrow
39 $ cd narrow
40 $ hg tracked
40 $ hg tracked
41 I path:inside
41 I path:inside
42 $ ls
42 $ ls
43 inside
43 inside
44 $ cat inside/f
44 $ cat inside/f
45 inside
45 inside
46 $ cd ..
46 $ cd ..
47
47
48 add more upstream files which we will include in a wider narrow spec
48 add more upstream files which we will include in a wider narrow spec
49
49
50 $ cd master
50 $ cd master
51
51
52 $ mkdir wider
52 $ mkdir wider
53 $ echo 'wider' > wider/f
53 $ echo 'wider' > wider/f
54 $ hg add wider/f
54 $ hg add wider/f
55 $ echo 'widest v2' > widest/f
55 $ echo 'widest v2' > widest/f
56 $ hg commit -m 'add wider, update widest'
56 $ hg commit -m 'add wider, update widest'
57
57
58 $ echo 'widest v3' > widest/f
58 $ echo 'widest v3' > widest/f
59 $ hg commit -m 'update widest v3'
59 $ hg commit -m 'update widest v3'
60
60
61 $ echo 'inside v2' > inside/f
61 $ echo 'inside v2' > inside/f
62 $ hg commit -m 'update inside'
62 $ hg commit -m 'update inside'
63
63
64 $ mkdir outside2
64 $ mkdir outside2
65 $ echo 'outside2' > outside2/f
65 $ echo 'outside2' > outside2/f
66 $ hg add outside2/f
66 $ hg add outside2/f
67 $ hg commit -m 'add outside2'
67 $ hg commit -m 'add outside2'
68
68
69 $ echo 'widest v4' > widest/f
69 $ echo 'widest v4' > widest/f
70 $ hg commit -m 'update widest v4'
70 $ hg commit -m 'update widest v4'
71
71
72 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
72 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
73 *: update widest v4 (glob)
73 *: update widest v4 (glob)
74 *: add outside2 (glob)
74 *: add outside2 (glob)
75 *: update inside (glob)
75 *: update inside (glob)
76 *: update widest v3 (glob)
76 *: update widest v3 (glob)
77 *: add wider, update widest (glob)
77 *: add wider, update widest (glob)
78 *: add outside (glob)
78 *: add outside (glob)
79 *: add widest (glob)
79 *: add widest (glob)
80 *: add inside (glob)
80 *: add inside (glob)
81
81
82 $ cd ..
82 $ cd ..
83
83
84 Widen the narrow spec to see the wider file. This should not get the newly
84 Widen the narrow spec to see the wider file. This should not get the newly
85 added upstream revisions.
85 added upstream revisions.
86
86
87 $ cd narrow
87 $ cd narrow
88 $ hg tracked --addinclude wider/f
88 $ hg tracked --addinclude wider/f
89 comparing with ssh://user@dummy/master
89 comparing with ssh://user@dummy/master
90 searching for changes
90 searching for changes
91 no changes found
91 no changes found
92 adding changesets
92 adding changesets
93 adding manifests
93 adding manifests
94 adding file changes
94 adding file changes
95 added 0 changesets with 0 changes to 1 files
95 added 0 changesets with 0 changes to 1 files
96 3 local changesets published
96 3 local changesets published
97 $ hg tracked
97 $ hg tracked
98 I path:inside
98 I path:inside
99 I path:wider/f
99
100
100 Pull down the newly added upstream revision.
101 Pull down the newly added upstream revision.
101
102
102 $ hg pull
103 $ hg pull
103 pulling from ssh://user@dummy/master
104 pulling from ssh://user@dummy/master
104 searching for changes
105 searching for changes
105 adding changesets
106 adding changesets
106 adding manifests
107 adding manifests
107 adding file changes
108 adding file changes
108 added 5 changesets with 1 changes to 1 files
109 added 5 changesets with 2 changes to 2 files
109 new changesets *:* (glob)
110 new changesets *:* (glob)
110 (run 'hg update' to get a working copy)
111 (run 'hg update' to get a working copy)
111 $ hg update -r 'desc("add wider")'
112 $ hg update -r 'desc("add wider")'
112 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 $ cat wider/f
114 $ cat wider/f
114 cat: wider/f: $ENOENT$
115 wider
115 [1]
116
116
117 $ hg update -r 'desc("update inside")'
117 $ hg update -r 'desc("update inside")'
118 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 $ cat wider/f
119 $ cat wider/f
120 cat: wider/f: $ENOENT$
120 wider
121 [1]
122 $ cat inside/f
121 $ cat inside/f
123 inside v2
122 inside v2
124
123
125 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
124 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
126 45662f0793c7: update widest v4
125 45662f0793c7: update widest v4
127 1dd1364b566e: add outside2
126 1dd1364b566e: add outside2
128 *: update inside (glob)
127 *: update inside (glob)
129 be0600e3ccba: update widest v3
128 be0600e3ccba: update widest v3
130 *: add wider, update widest (glob)
129 *: add wider, update widest (glob)
131 4922ea71b958: add outside
130 4922ea71b958: add outside
132 40e0ea6c8cd7: add widest
131 40e0ea6c8cd7: add widest
133 *: add inside (glob)
132 *: add inside (glob)
134
133
135 Check that widening with a newline fails
134 Check that widening with a newline fails
136
135
137 $ hg tracked --addinclude 'widest
136 $ hg tracked --addinclude 'widest
138 > '
137 > '
139 abort: newlines are not allowed in narrowspec paths
138 abort: newlines are not allowed in narrowspec paths
140 [255]
139 [255]
141
140
142 widen the narrow spec to include the widest file
141 widen the narrow spec to include the widest file
143
142
144 $ hg tracked --addinclude widest
143 $ hg tracked --addinclude widest
145 comparing with ssh://user@dummy/master
144 comparing with ssh://user@dummy/master
146 searching for changes
145 searching for changes
147 no changes found
146 no changes found
148 adding changesets
147 adding changesets
149 adding manifests
148 adding manifests
150 adding file changes
149 adding file changes
151 added 0 changesets with 4 changes to 2 files
150 added 0 changesets with 4 changes to 3 files
152 5 local changesets published
151 5 local changesets published
153 abort: path ends in directory separator: widest/
154 [255]
155 $ hg tracked
152 $ hg tracked
156 I path:inside
153 I path:inside
154 I path:wider/f
155 I path:widest
157 $ hg update 'desc("add widest")'
156 $ hg update 'desc("add widest")'
157 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
158 $ cat widest/f
159 widest
160 $ hg update 'desc("add wider, update widest")'
161 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 $ cat wider/f
163 wider
164 $ cat widest/f
165 widest v2
166 $ hg update 'desc("update widest v3")'
158 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
167 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 $ cat widest/f
168 $ cat widest/f
160 cat: widest/f: $ENOENT$
169 widest v3
161 [1]
170 $ hg update 'desc("update widest v4")'
162 $ hg update 'desc("add wider, update widest")'
171 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 $ cat wider/f
165 cat: wider/f: $ENOENT$
166 [1]
167 $ cat widest/f
172 $ cat widest/f
168 cat: widest/f: $ENOENT$
173 widest v4
169 [1]
170 $ hg update 'desc("update widest v3")'
171 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 $ cat widest/f
173 cat: widest/f: $ENOENT$
174 [1]
175 $ hg update 'desc("update widest v4")'
176 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 $ cat widest/f
178 cat: widest/f: $ENOENT$
179 [1]
180
174
181 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
175 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
182 *: update widest v4 (glob)
176 *: update widest v4 (glob)
183 1dd1364b566e: add outside2
177 1dd1364b566e: add outside2
184 *: update inside (glob)
178 *: update inside (glob)
185 *: update widest v3 (glob)
179 *: update widest v3 (glob)
186 *: add wider, update widest (glob)
180 *: add wider, update widest (glob)
187 4922ea71b958: add outside
181 4922ea71b958: add outside
188 *: add widest (glob)
182 *: add widest (glob)
189 *: add inside (glob)
183 *: add inside (glob)
190
184
191 separate suite of tests: files from 0-10 modified in changes 0-10. This allows
185 separate suite of tests: files from 0-10 modified in changes 0-10. This allows
192 more obvious precise tests tickling particular corner cases.
186 more obvious precise tests tickling particular corner cases.
193
187
194 $ cd ..
188 $ cd ..
195 $ hg init upstream
189 $ hg init upstream
196 $ cd upstream
190 $ cd upstream
197 $ for x in `$TESTDIR/seq.py 0 10`
191 $ for x in `$TESTDIR/seq.py 0 10`
198 > do
192 > do
199 > mkdir d$x
193 > mkdir d$x
200 > echo $x > d$x/f
194 > echo $x > d$x/f
201 > hg add d$x/f
195 > hg add d$x/f
202 > hg commit -m "add d$x/f"
196 > hg commit -m "add d$x/f"
203 > done
197 > done
204 $ hg log -T "{node|short}: {desc}\n"
198 $ hg log -T "{node|short}: {desc}\n"
205 *: add d10/f (glob)
199 *: add d10/f (glob)
206 *: add d9/f (glob)
200 *: add d9/f (glob)
207 *: add d8/f (glob)
201 *: add d8/f (glob)
208 *: add d7/f (glob)
202 *: add d7/f (glob)
209 *: add d6/f (glob)
203 *: add d6/f (glob)
210 *: add d5/f (glob)
204 *: add d5/f (glob)
211 *: add d4/f (glob)
205 *: add d4/f (glob)
212 *: add d3/f (glob)
206 *: add d3/f (glob)
213 *: add d2/f (glob)
207 *: add d2/f (glob)
214 *: add d1/f (glob)
208 *: add d1/f (glob)
215 *: add d0/f (glob)
209 *: add d0/f (glob)
216
210
217 make narrow clone with every third node.
211 make narrow clone with every third node.
218
212
219 $ cd ..
213 $ cd ..
220 $ hg clone --narrow ssh://user@dummy/upstream narrow2 --include d0 --include d3 --include d6 --include d9
214 $ hg clone --narrow ssh://user@dummy/upstream narrow2 --include d0 --include d3 --include d6 --include d9
221 requesting all changes
215 requesting all changes
222 adding changesets
216 adding changesets
223 adding manifests
217 adding manifests
224 adding file changes
218 adding file changes
225 added 11 changesets with 4 changes to 4 files
219 added 11 changesets with 4 changes to 4 files
226 new changesets *:* (glob)
220 new changesets *:* (glob)
227 updating to branch default
221 updating to branch default
228 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
229 $ cd narrow2
223 $ cd narrow2
230 $ hg tracked
224 $ hg tracked
231 I path:d0
225 I path:d0
232 I path:d3
226 I path:d3
233 I path:d6
227 I path:d6
234 I path:d9
228 I path:d9
235 $ hg verify
229 $ hg verify
236 checking changesets
230 checking changesets
237 checking manifests
231 checking manifests
238 checking directory manifests
232 checking directory manifests
239 crosschecking files in changesets and manifests
233 crosschecking files in changesets and manifests
240 checking files
234 checking files
241 4 files, 11 changesets, 4 total revisions
235 4 files, 11 changesets, 4 total revisions
242 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
236 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
243 5dcf948d1e26: add d10/f
237 5dcf948d1e26: add d10/f
244 *: add d9/f (glob)
238 *: add d9/f (glob)
245 ed07d334af10: add d8/f
239 ed07d334af10: add d8/f
246 472749d2eed8: add d7/f
240 472749d2eed8: add d7/f
247 *: add d6/f (glob)
241 *: add d6/f (glob)
248 47c482f555ec: add d5/f
242 47c482f555ec: add d5/f
249 3c6772db7d10: add d4/f
243 3c6772db7d10: add d4/f
250 *: add d3/f (glob)
244 *: add d3/f (glob)
251 a68ce05aaaed: add d2/f
245 a68ce05aaaed: add d2/f
252 5934322a52dd: add d1/f
246 5934322a52dd: add d1/f
253 *: add d0/f (glob)
247 *: add d0/f (glob)
254 $ hg tracked --addinclude d1
248 $ hg tracked --addinclude d1
255 comparing with ssh://user@dummy/upstream
249 comparing with ssh://user@dummy/upstream
256 searching for changes
250 searching for changes
257 no changes found
251 no changes found
258 adding changesets
252 adding changesets
259 adding manifests
253 adding manifests
260 adding file changes
254 adding file changes
261 added 0 changesets with 1 changes to 5 files
255 added 0 changesets with 1 changes to 5 files
262 11 local changesets published
256 11 local changesets published
263 abort: path ends in directory separator: d1/
264 [255]
265 $ hg tracked
257 $ hg tracked
266 I path:d0
258 I path:d0
259 I path:d1
267 I path:d3
260 I path:d3
268 I path:d6
261 I path:d6
269 I path:d9
262 I path:d9
270 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
263 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
271 5dcf948d1e26: add d10/f
264 5dcf948d1e26: add d10/f
272 *: add d9/f (glob)
265 *: add d9/f (glob)
273 ed07d334af10: add d8/f
266 ed07d334af10: add d8/f
274 472749d2eed8: add d7/f
267 472749d2eed8: add d7/f
275 *: add d6/f (glob)
268 *: add d6/f (glob)
276 47c482f555ec: add d5/f
269 47c482f555ec: add d5/f
277 3c6772db7d10: add d4/f
270 3c6772db7d10: add d4/f
278 *: add d3/f (glob)
271 *: add d3/f (glob)
279 a68ce05aaaed: add d2/f
272 a68ce05aaaed: add d2/f
280 *: add d1/f (glob)
273 *: add d1/f (glob)
281 *: add d0/f (glob)
274 *: add d0/f (glob)
282
275
283 Verify shouldn't claim the repo is corrupt after a widen.
276 Verify shouldn't claim the repo is corrupt after a widen.
284
277
285 $ hg verify
278 $ hg verify
286 checking changesets
279 checking changesets
287 checking manifests
280 checking manifests
288 checking directory manifests
281 checking directory manifests
289 warning: orphan data file 'meta/d1/00manifest.i'
290 crosschecking files in changesets and manifests
282 crosschecking files in changesets and manifests
291 checking files
283 checking files
292 warning: orphan data file 'data/d1/f.i'
284 5 files, 11 changesets, 5 total revisions
293 4 files, 11 changesets, 4 total revisions
294 2 warnings encountered!
295
285
296 Widening preserves parent of local commit
286 Widening preserves parent of local commit
297
287
298 $ cd ..
288 $ cd ..
299 $ hg clone -q --narrow ssh://user@dummy/upstream narrow3 --include d2 -r 2
289 $ hg clone -q --narrow ssh://user@dummy/upstream narrow3 --include d2 -r 2
300 $ cd narrow3
290 $ cd narrow3
301 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
291 $ hg log -T "{if(ellipsis, '...')}{node|short}: {desc}\n"
302 *: add d2/f (glob)
292 *: add d2/f (glob)
303 5934322a52dd: add d1/f
293 5934322a52dd: add d1/f
304 44d97ac7c511: add d0/f
294 44d97ac7c511: add d0/f
305 $ hg pull -q -r 3
295 $ hg pull -q -r 3
306 $ hg co -q tip
296 $ hg co -q tip
307 $ hg pull -q -r 4
297 $ hg pull -q -r 4
308 $ echo local > d2/f
298 $ echo local > d2/f
309 $ hg ci -m local
299 $ hg ci -m local
310 created new head
300 created new head
311 $ hg tracked -q --addinclude d0 --addinclude d9
301 $ hg tracked -q --addinclude d0 --addinclude d9
312 abort: path ends in directory separator: d0/
313 [255]
314
302
315 Widening preserves bookmarks
303 Widening preserves bookmarks
316
304
317 $ cd ..
305 $ cd ..
318 $ hg clone -q --narrow ssh://user@dummy/upstream narrow-bookmarks --include d4
306 $ hg clone -q --narrow ssh://user@dummy/upstream narrow-bookmarks --include d4
319 $ cd narrow-bookmarks
307 $ cd narrow-bookmarks
320 $ echo local > d4/f
308 $ echo local > d4/f
321 $ hg ci -m local
309 $ hg ci -m local
322 $ hg bookmarks bookmark
310 $ hg bookmarks bookmark
323 $ hg bookmarks
311 $ hg bookmarks
324 * bookmark 11:42aed9c63197
312 * bookmark 11:42aed9c63197
325 $ hg -q tracked --addinclude d2
313 $ hg -q tracked --addinclude d2
326 abort: path ends in directory separator: d2/
327 [255]
328 $ hg bookmarks
314 $ hg bookmarks
329 * bookmark 11:42aed9c63197
315 * bookmark 11:42aed9c63197
330 $ hg log -r bookmark -T '{desc}\n'
316 $ hg log -r bookmark -T '{desc}\n'
331 local
317 local
332
318
333 Widening that fails can be recovered from
319 Widening that fails can be recovered from
334
320
335 $ cd ..
321 $ cd ..
336 $ hg clone -q --narrow ssh://user@dummy/upstream interrupted --include d0
322 $ hg clone -q --narrow ssh://user@dummy/upstream interrupted --include d0
337 $ cd interrupted
323 $ cd interrupted
338 $ echo local > d0/f
324 $ echo local > d0/f
339 $ hg ci -m local
325 $ hg ci -m local
340 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
326 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
341 11: local
327 11: local
342 10: add d10/f
328 10: add d10/f
343 9: add d9/f
329 9: add d9/f
344 8: add d8/f
330 8: add d8/f
345 7: add d7/f
331 7: add d7/f
346 6: add d6/f
332 6: add d6/f
347 5: add d5/f
333 5: add d5/f
348 4: add d4/f
334 4: add d4/f
349 3: add d3/f
335 3: add d3/f
350 2: add d2/f
336 2: add d2/f
351 1: add d1/f
337 1: add d1/f
352 0: add d0/f
338 0: add d0/f
353 $ hg bookmarks bookmark
339 $ hg bookmarks bookmark
354 $ hg --config hooks.pretxnchangegroup.bad=false tracked --addinclude d1
340 $ hg --config hooks.pretxnchangegroup.bad=false tracked --addinclude d1
355 comparing with ssh://user@dummy/upstream
341 comparing with ssh://user@dummy/upstream
356 searching for changes
342 searching for changes
357 no changes found
343 no changes found
358 adding changesets
344 adding changesets
359 adding manifests
345 adding manifests
360 adding file changes
346 adding file changes
361 added 0 changesets with 1 changes to 2 files
347 added 0 changesets with 1 changes to 2 files
362 11 local changesets published
348 11 local changesets published
363 abort: path ends in directory separator: d1/
364 [255]
365 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
349 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
366 11: local
350 11: local
367 10: add d10/f
351 10: add d10/f
368 9: add d9/f
352 9: add d9/f
369 8: add d8/f
353 8: add d8/f
370 7: add d7/f
354 7: add d7/f
371 6: add d6/f
355 6: add d6/f
372 5: add d5/f
356 5: add d5/f
373 4: add d4/f
357 4: add d4/f
374 3: add d3/f
358 3: add d3/f
375 2: add d2/f
359 2: add d2/f
376 1: add d1/f
360 1: add d1/f
377 0: add d0/f
361 0: add d0/f
378 $ hg bookmarks
362 $ hg bookmarks
379 * bookmark 11:b7ce3df41eca
363 * bookmark 11:b7ce3df41eca
380 $ hg unbundle .hg/strip-backup/*-widen.hg
364 $ hg unbundle .hg/strip-backup/*-widen.hg
381 abort: $ENOENT$: .hg/strip-backup/*-widen.hg
365 abort: $ENOENT$: .hg/strip-backup/*-widen.hg
382 [255]
366 [255]
383 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
367 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
384 11: local
368 11: local
385 10: add d10/f
369 10: add d10/f
386 9: add d9/f
370 9: add d9/f
387 8: add d8/f
371 8: add d8/f
388 7: add d7/f
372 7: add d7/f
389 6: add d6/f
373 6: add d6/f
390 5: add d5/f
374 5: add d5/f
391 4: add d4/f
375 4: add d4/f
392 3: add d3/f
376 3: add d3/f
393 2: add d2/f
377 2: add d2/f
394 1: add d1/f
378 1: add d1/f
395 0: add d0/f
379 0: add d0/f
396 $ hg bookmarks
380 $ hg bookmarks
397 * bookmark 11:b7ce3df41eca
381 * bookmark 11:b7ce3df41eca
General Comments 0
You need to be logged in to leave comments. Login now