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