##// END OF EJS Templates
narrow: add --no-backup option for narrowing...
Martin von Zweigbergk -
r47206:3c360ab2 default
parent child Browse files
Show More
@@ -1,663 +1,671 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.node import (
14 14 hex,
15 15 nullid,
16 16 short,
17 17 )
18 18 from mercurial import (
19 19 bundle2,
20 20 cmdutil,
21 21 commands,
22 22 discovery,
23 23 encoding,
24 24 error,
25 25 exchange,
26 26 extensions,
27 27 hg,
28 28 narrowspec,
29 29 pathutil,
30 30 pycompat,
31 31 registrar,
32 32 repair,
33 33 repoview,
34 34 requirements,
35 35 sparse,
36 36 util,
37 37 wireprototypes,
38 38 )
39 39
40 40 table = {}
41 41 command = registrar.command(table)
42 42
43 43
44 44 def setup():
45 45 """Wraps user-facing mercurial commands with narrow-aware versions."""
46 46
47 47 entry = extensions.wrapcommand(commands.table, b'clone', clonenarrowcmd)
48 48 entry[1].append(
49 49 (b'', b'narrow', None, _(b"create a narrow clone of select files"))
50 50 )
51 51 entry[1].append(
52 52 (
53 53 b'',
54 54 b'depth',
55 55 b'',
56 56 _(b"limit the history fetched by distance from heads"),
57 57 )
58 58 )
59 59 entry[1].append((b'', b'narrowspec', b'', _(b"read narrowspecs from file")))
60 60 # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit
61 61 if b'sparse' not in extensions.enabled():
62 62 entry[1].append(
63 63 (b'', b'include', [], _(b"specifically fetch this file/directory"))
64 64 )
65 65 entry[1].append(
66 66 (
67 67 b'',
68 68 b'exclude',
69 69 [],
70 70 _(b"do not fetch this file/directory, even if included"),
71 71 )
72 72 )
73 73
74 74 entry = extensions.wrapcommand(commands.table, b'pull', pullnarrowcmd)
75 75 entry[1].append(
76 76 (
77 77 b'',
78 78 b'depth',
79 79 b'',
80 80 _(b"limit the history fetched by distance from heads"),
81 81 )
82 82 )
83 83
84 84 extensions.wrapcommand(commands.table, b'archive', archivenarrowcmd)
85 85
86 86
87 87 def clonenarrowcmd(orig, ui, repo, *args, **opts):
88 88 """Wraps clone command, so 'hg clone' first wraps localrepo.clone()."""
89 89 opts = pycompat.byteskwargs(opts)
90 90 wrappedextraprepare = util.nullcontextmanager()
91 91 narrowspecfile = opts[b'narrowspec']
92 92
93 93 if narrowspecfile:
94 94 filepath = os.path.join(encoding.getcwd(), narrowspecfile)
95 95 ui.status(_(b"reading narrowspec from '%s'\n") % filepath)
96 96 try:
97 97 fdata = util.readfile(filepath)
98 98 except IOError as inst:
99 99 raise error.Abort(
100 100 _(b"cannot read narrowspecs from '%s': %s")
101 101 % (filepath, encoding.strtolocal(inst.strerror))
102 102 )
103 103
104 104 includes, excludes, profiles = sparse.parseconfig(ui, fdata, b'narrow')
105 105 if profiles:
106 106 raise error.ConfigError(
107 107 _(
108 108 b"cannot specify other files using '%include' in"
109 109 b" narrowspec"
110 110 )
111 111 )
112 112
113 113 narrowspec.validatepatterns(includes)
114 114 narrowspec.validatepatterns(excludes)
115 115
116 116 # narrowspec is passed so we should assume that user wants narrow clone
117 117 opts[b'narrow'] = True
118 118 opts[b'include'].extend(includes)
119 119 opts[b'exclude'].extend(excludes)
120 120
121 121 if opts[b'narrow']:
122 122
123 123 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
124 124 orig(pullop, kwargs)
125 125
126 126 if opts.get(b'depth'):
127 127 kwargs[b'depth'] = opts[b'depth']
128 128
129 129 wrappedextraprepare = extensions.wrappedfunction(
130 130 exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare_widen
131 131 )
132 132
133 133 with wrappedextraprepare:
134 134 return orig(ui, repo, *args, **pycompat.strkwargs(opts))
135 135
136 136
137 137 def pullnarrowcmd(orig, ui, repo, *args, **opts):
138 138 """Wraps pull command to allow modifying narrow spec."""
139 139 wrappedextraprepare = util.nullcontextmanager()
140 140 if requirements.NARROW_REQUIREMENT in repo.requirements:
141 141
142 142 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
143 143 orig(pullop, kwargs)
144 144 if opts.get('depth'):
145 145 kwargs[b'depth'] = opts['depth']
146 146
147 147 wrappedextraprepare = extensions.wrappedfunction(
148 148 exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare_widen
149 149 )
150 150
151 151 with wrappedextraprepare:
152 152 return orig(ui, repo, *args, **opts)
153 153
154 154
155 155 def archivenarrowcmd(orig, ui, repo, *args, **opts):
156 156 """Wraps archive command to narrow the default includes."""
157 157 if requirements.NARROW_REQUIREMENT in repo.requirements:
158 158 repo_includes, repo_excludes = repo.narrowpats
159 159 includes = set(opts.get('include', []))
160 160 excludes = set(opts.get('exclude', []))
161 161 includes, excludes, unused_invalid = narrowspec.restrictpatterns(
162 162 includes, excludes, repo_includes, repo_excludes
163 163 )
164 164 if includes:
165 165 opts['include'] = includes
166 166 if excludes:
167 167 opts['exclude'] = excludes
168 168 return orig(ui, repo, *args, **opts)
169 169
170 170
171 171 def pullbundle2extraprepare(orig, pullop, kwargs):
172 172 repo = pullop.repo
173 173 if requirements.NARROW_REQUIREMENT not in repo.requirements:
174 174 return orig(pullop, kwargs)
175 175
176 176 if wireprototypes.NARROWCAP not in pullop.remote.capabilities():
177 177 raise error.Abort(_(b"server does not support narrow clones"))
178 178 orig(pullop, kwargs)
179 179 kwargs[b'narrow'] = True
180 180 include, exclude = repo.narrowpats
181 181 kwargs[b'oldincludepats'] = include
182 182 kwargs[b'oldexcludepats'] = exclude
183 183 if include:
184 184 kwargs[b'includepats'] = include
185 185 if exclude:
186 186 kwargs[b'excludepats'] = exclude
187 187 # calculate known nodes only in ellipses cases because in non-ellipses cases
188 188 # we have all the nodes
189 189 if wireprototypes.ELLIPSESCAP1 in pullop.remote.capabilities():
190 190 kwargs[b'known'] = [
191 191 hex(ctx.node())
192 192 for ctx in repo.set(b'::%ln', pullop.common)
193 193 if ctx.node() != nullid
194 194 ]
195 195 if not kwargs[b'known']:
196 196 # Mercurial serializes an empty list as '' and deserializes it as
197 197 # [''], so delete it instead to avoid handling the empty string on
198 198 # the server.
199 199 del kwargs[b'known']
200 200
201 201
202 202 extensions.wrapfunction(
203 203 exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare
204 204 )
205 205
206 206
207 207 def _narrow(
208 208 ui,
209 209 repo,
210 210 remote,
211 211 commoninc,
212 212 oldincludes,
213 213 oldexcludes,
214 214 newincludes,
215 215 newexcludes,
216 216 force,
217 backup,
217 218 ):
218 219 oldmatch = narrowspec.match(repo.root, oldincludes, oldexcludes)
219 220 newmatch = narrowspec.match(repo.root, newincludes, newexcludes)
220 221
221 222 # This is essentially doing "hg outgoing" to find all local-only
222 223 # commits. We will then check that the local-only commits don't
223 224 # have any changes to files that will be untracked.
224 225 unfi = repo.unfiltered()
225 226 outgoing = discovery.findcommonoutgoing(unfi, remote, commoninc=commoninc)
226 227 ui.status(_(b'looking for local changes to affected paths\n'))
227 228 localnodes = []
228 229 for n in itertools.chain(outgoing.missing, outgoing.excluded):
229 230 if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()):
230 231 localnodes.append(n)
231 232 revstostrip = unfi.revs(b'descendants(%ln)', localnodes)
232 233 hiddenrevs = repoview.filterrevs(repo, b'visible')
233 234 visibletostrip = list(
234 235 repo.changelog.node(r) for r in (revstostrip - hiddenrevs)
235 236 )
236 237 if visibletostrip:
237 238 ui.status(
238 239 _(
239 240 b'The following changeset(s) or their ancestors have '
240 241 b'local changes not on the remote:\n'
241 242 )
242 243 )
243 244 maxnodes = 10
244 245 if ui.verbose or len(visibletostrip) <= maxnodes:
245 246 for n in visibletostrip:
246 247 ui.status(b'%s\n' % short(n))
247 248 else:
248 249 for n in visibletostrip[:maxnodes]:
249 250 ui.status(b'%s\n' % short(n))
250 251 ui.status(
251 252 _(b'...and %d more, use --verbose to list all\n')
252 253 % (len(visibletostrip) - maxnodes)
253 254 )
254 255 if not force:
255 256 raise error.StateError(
256 257 _(b'local changes found'),
257 258 hint=_(b'use --force-delete-local-changes to ignore'),
258 259 )
259 260
260 261 with ui.uninterruptible():
261 262 if revstostrip:
262 263 tostrip = [unfi.changelog.node(r) for r in revstostrip]
263 264 if repo[b'.'].node() in tostrip:
264 265 # stripping working copy, so move to a different commit first
265 266 urev = max(
266 267 repo.revs(
267 268 b'(::%n) - %ln + null',
268 269 repo[b'.'].node(),
269 270 visibletostrip,
270 271 )
271 272 )
272 273 hg.clean(repo, urev)
273 274 overrides = {(b'devel', b'strip-obsmarkers'): False}
274 275 with ui.configoverride(overrides, b'narrow'):
275 repair.strip(ui, unfi, tostrip, topic=b'narrow')
276 repair.strip(ui, unfi, tostrip, topic=b'narrow', backup=backup)
276 277
277 278 todelete = []
278 279 for f, f2, size in repo.store.datafiles():
279 280 if f.startswith(b'data/'):
280 281 file = f[5:-2]
281 282 if not newmatch(file):
282 283 todelete.append(f)
283 284 elif f.startswith(b'meta/'):
284 285 dir = f[5:-13]
285 286 dirs = sorted(pathutil.dirs({dir})) + [dir]
286 287 include = True
287 288 for d in dirs:
288 289 visit = newmatch.visitdir(d)
289 290 if not visit:
290 291 include = False
291 292 break
292 293 if visit == b'all':
293 294 break
294 295 if not include:
295 296 todelete.append(f)
296 297
297 298 repo.destroying()
298 299
299 300 with repo.transaction(b'narrowing'):
300 301 # Update narrowspec before removing revlogs, so repo won't be
301 302 # corrupt in case of crash
302 303 repo.setnarrowpats(newincludes, newexcludes)
303 304
304 305 for f in todelete:
305 306 ui.status(_(b'deleting %s\n') % f)
306 307 util.unlinkpath(repo.svfs.join(f))
307 308 repo.store.markremoved(f)
308 309
309 310 narrowspec.updateworkingcopy(repo, assumeclean=True)
310 311 narrowspec.copytoworkingcopy(repo)
311 312
312 313 repo.destroyed()
313 314
314 315
315 316 def _widen(
316 317 ui,
317 318 repo,
318 319 remote,
319 320 commoninc,
320 321 oldincludes,
321 322 oldexcludes,
322 323 newincludes,
323 324 newexcludes,
324 325 ):
325 326 # for now we assume that if a server has ellipses enabled, we will be
326 327 # exchanging ellipses nodes. In future we should add ellipses as a client
327 328 # side requirement (maybe) to distinguish a client is shallow or not and
328 329 # then send that information to server whether we want ellipses or not.
329 330 # Theoretically a non-ellipses repo should be able to use narrow
330 331 # functionality from an ellipses enabled server
331 332 remotecap = remote.capabilities()
332 333 ellipsesremote = any(
333 334 cap in remotecap for cap in wireprototypes.SUPPORTED_ELLIPSESCAP
334 335 )
335 336
336 337 # check whether we are talking to a server which supports old version of
337 338 # ellipses capabilities
338 339 isoldellipses = (
339 340 ellipsesremote
340 341 and wireprototypes.ELLIPSESCAP1 in remotecap
341 342 and wireprototypes.ELLIPSESCAP not in remotecap
342 343 )
343 344
344 345 def pullbundle2extraprepare_widen(orig, pullop, kwargs):
345 346 orig(pullop, kwargs)
346 347 # The old{in,ex}cludepats have already been set by orig()
347 348 kwargs[b'includepats'] = newincludes
348 349 kwargs[b'excludepats'] = newexcludes
349 350
350 351 wrappedextraprepare = extensions.wrappedfunction(
351 352 exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare_widen
352 353 )
353 354
354 355 # define a function that narrowbundle2 can call after creating the
355 356 # backup bundle, but before applying the bundle from the server
356 357 def setnewnarrowpats():
357 358 repo.setnarrowpats(newincludes, newexcludes)
358 359
359 360 repo.setnewnarrowpats = setnewnarrowpats
360 361 # silence the devel-warning of applying an empty changegroup
361 362 overrides = {(b'devel', b'all-warnings'): False}
362 363
363 364 common = commoninc[0]
364 365 with ui.uninterruptible():
365 366 if ellipsesremote:
366 367 ds = repo.dirstate
367 368 p1, p2 = ds.p1(), ds.p2()
368 369 with ds.parentchange():
369 370 ds.setparents(nullid, nullid)
370 371 if isoldellipses:
371 372 with wrappedextraprepare:
372 373 exchange.pull(repo, remote, heads=common)
373 374 else:
374 375 known = []
375 376 if ellipsesremote:
376 377 known = [
377 378 ctx.node()
378 379 for ctx in repo.set(b'::%ln', common)
379 380 if ctx.node() != nullid
380 381 ]
381 382 with remote.commandexecutor() as e:
382 383 bundle = e.callcommand(
383 384 b'narrow_widen',
384 385 {
385 386 b'oldincludes': oldincludes,
386 387 b'oldexcludes': oldexcludes,
387 388 b'newincludes': newincludes,
388 389 b'newexcludes': newexcludes,
389 390 b'cgversion': b'03',
390 391 b'commonheads': common,
391 392 b'known': known,
392 393 b'ellipses': ellipsesremote,
393 394 },
394 395 ).result()
395 396
396 397 trmanager = exchange.transactionmanager(
397 398 repo, b'widen', remote.url()
398 399 )
399 400 with trmanager, repo.ui.configoverride(overrides, b'widen'):
400 401 op = bundle2.bundleoperation(
401 402 repo, trmanager.transaction, source=b'widen'
402 403 )
403 404 # TODO: we should catch error.Abort here
404 405 bundle2.processbundle(repo, bundle, op=op)
405 406
406 407 if ellipsesremote:
407 408 with ds.parentchange():
408 409 ds.setparents(p1, p2)
409 410
410 411 with repo.transaction(b'widening'):
411 412 repo.setnewnarrowpats()
412 413 narrowspec.updateworkingcopy(repo)
413 414 narrowspec.copytoworkingcopy(repo)
414 415
415 416
416 417 # TODO(rdamazio): Make new matcher format and update description
417 418 @command(
418 419 b'tracked',
419 420 [
420 421 (b'', b'addinclude', [], _(b'new paths to include')),
421 422 (b'', b'removeinclude', [], _(b'old paths to no longer include')),
422 423 (
423 424 b'',
424 425 b'auto-remove-includes',
425 426 False,
426 427 _(b'automatically choose unused includes to remove'),
427 428 ),
428 429 (b'', b'addexclude', [], _(b'new paths to exclude')),
429 430 (b'', b'import-rules', b'', _(b'import narrowspecs from a file')),
430 431 (b'', b'removeexclude', [], _(b'old paths to no longer exclude')),
431 432 (
432 433 b'',
433 434 b'clear',
434 435 False,
435 436 _(b'whether to replace the existing narrowspec'),
436 437 ),
437 438 (
438 439 b'',
439 440 b'force-delete-local-changes',
440 441 False,
441 442 _(b'forces deletion of local changes when narrowing'),
442 443 ),
443 444 (
444 445 b'',
446 b'backup',
447 True,
448 _(b'back up local changes when narrowing'),
449 ),
450 (
451 b'',
445 452 b'update-working-copy',
446 453 False,
447 454 _(b'update working copy when the store has changed'),
448 455 ),
449 456 ]
450 457 + commands.remoteopts,
451 458 _(b'[OPTIONS]... [REMOTE]'),
452 459 inferrepo=True,
453 460 helpcategory=command.CATEGORY_MAINTENANCE,
454 461 )
455 462 def trackedcmd(ui, repo, remotepath=None, *pats, **opts):
456 463 """show or change the current narrowspec
457 464
458 465 With no argument, shows the current narrowspec entries, one per line. Each
459 466 line will be prefixed with 'I' or 'X' for included or excluded patterns,
460 467 respectively.
461 468
462 469 The narrowspec is comprised of expressions to match remote files and/or
463 470 directories that should be pulled into your client.
464 471 The narrowspec has *include* and *exclude* expressions, with excludes always
465 472 trumping includes: that is, if a file matches an exclude expression, it will
466 473 be excluded even if it also matches an include expression.
467 474 Excluding files that were never included has no effect.
468 475
469 476 Each included or excluded entry is in the format described by
470 477 'hg help patterns'.
471 478
472 479 The options allow you to add or remove included and excluded expressions.
473 480
474 481 If --clear is specified, then all previous includes and excludes are DROPPED
475 482 and replaced by the new ones specified to --addinclude and --addexclude.
476 483 If --clear is specified without any further options, the narrowspec will be
477 484 empty and will not match any files.
478 485
479 486 If --auto-remove-includes is specified, then those includes that don't match
480 487 any files modified by currently visible local commits (those not shared by
481 488 the remote) will be added to the set of explicitly specified includes to
482 489 remove.
483 490
484 491 --import-rules accepts a path to a file containing rules, allowing you to
485 492 add --addinclude, --addexclude rules in bulk. Like the other include and
486 493 exclude switches, the changes are applied immediately.
487 494 """
488 495 opts = pycompat.byteskwargs(opts)
489 496 if requirements.NARROW_REQUIREMENT not in repo.requirements:
490 497 raise error.InputError(
491 498 _(
492 499 b'the tracked command is only supported on '
493 500 b'repositories cloned with --narrow'
494 501 )
495 502 )
496 503
497 504 # Before supporting, decide whether it "hg tracked --clear" should mean
498 505 # tracking no paths or all paths.
499 506 if opts[b'clear']:
500 507 raise error.InputError(_(b'the --clear option is not yet supported'))
501 508
502 509 # import rules from a file
503 510 newrules = opts.get(b'import_rules')
504 511 if newrules:
505 512 try:
506 513 filepath = os.path.join(encoding.getcwd(), newrules)
507 514 fdata = util.readfile(filepath)
508 515 except IOError as inst:
509 516 raise error.StorageError(
510 517 _(b"cannot read narrowspecs from '%s': %s")
511 518 % (filepath, encoding.strtolocal(inst.strerror))
512 519 )
513 520 includepats, excludepats, profiles = sparse.parseconfig(
514 521 ui, fdata, b'narrow'
515 522 )
516 523 if profiles:
517 524 raise error.InputError(
518 525 _(
519 526 b"including other spec files using '%include' "
520 527 b"is not supported in narrowspec"
521 528 )
522 529 )
523 530 opts[b'addinclude'].extend(includepats)
524 531 opts[b'addexclude'].extend(excludepats)
525 532
526 533 addedincludes = narrowspec.parsepatterns(opts[b'addinclude'])
527 534 removedincludes = narrowspec.parsepatterns(opts[b'removeinclude'])
528 535 addedexcludes = narrowspec.parsepatterns(opts[b'addexclude'])
529 536 removedexcludes = narrowspec.parsepatterns(opts[b'removeexclude'])
530 537 autoremoveincludes = opts[b'auto_remove_includes']
531 538
532 539 update_working_copy = opts[b'update_working_copy']
533 540 only_show = not (
534 541 addedincludes
535 542 or removedincludes
536 543 or addedexcludes
537 544 or removedexcludes
538 545 or newrules
539 546 or autoremoveincludes
540 547 or update_working_copy
541 548 )
542 549
543 550 oldincludes, oldexcludes = repo.narrowpats
544 551
545 552 # filter the user passed additions and deletions into actual additions and
546 553 # deletions of excludes and includes
547 554 addedincludes -= oldincludes
548 555 removedincludes &= oldincludes
549 556 addedexcludes -= oldexcludes
550 557 removedexcludes &= oldexcludes
551 558
552 559 widening = addedincludes or removedexcludes
553 560 narrowing = removedincludes or addedexcludes
554 561
555 562 # Only print the current narrowspec.
556 563 if only_show:
557 564 ui.pager(b'tracked')
558 565 fm = ui.formatter(b'narrow', opts)
559 566 for i in sorted(oldincludes):
560 567 fm.startitem()
561 568 fm.write(b'status', b'%s ', b'I', label=b'narrow.included')
562 569 fm.write(b'pat', b'%s\n', i, label=b'narrow.included')
563 570 for i in sorted(oldexcludes):
564 571 fm.startitem()
565 572 fm.write(b'status', b'%s ', b'X', label=b'narrow.excluded')
566 573 fm.write(b'pat', b'%s\n', i, label=b'narrow.excluded')
567 574 fm.end()
568 575 return 0
569 576
570 577 if update_working_copy:
571 578 with repo.wlock(), repo.lock(), repo.transaction(b'narrow-wc'):
572 579 narrowspec.updateworkingcopy(repo)
573 580 narrowspec.copytoworkingcopy(repo)
574 581 return 0
575 582
576 583 if not (widening or narrowing or autoremoveincludes):
577 584 ui.status(_(b"nothing to widen or narrow\n"))
578 585 return 0
579 586
580 587 with repo.wlock(), repo.lock():
581 588 cmdutil.bailifchanged(repo)
582 589
583 590 # Find the revisions we have in common with the remote. These will
584 591 # be used for finding local-only changes for narrowing. They will
585 592 # also define the set of revisions to update for widening.
586 593 remotepath = ui.expandpath(remotepath or b'default')
587 594 url, branches = hg.parseurl(remotepath)
588 595 ui.status(_(b'comparing with %s\n') % util.hidepassword(url))
589 596 remote = hg.peer(repo, opts, url)
590 597
591 598 # check narrow support before doing anything if widening needs to be
592 599 # performed. In future we should also abort if client is ellipses and
593 600 # server does not support ellipses
594 601 if widening and wireprototypes.NARROWCAP not in remote.capabilities():
595 602 raise error.Abort(_(b"server does not support narrow clones"))
596 603
597 604 commoninc = discovery.findcommonincoming(repo, remote)
598 605
599 606 if autoremoveincludes:
600 607 outgoing = discovery.findcommonoutgoing(
601 608 repo, remote, commoninc=commoninc
602 609 )
603 610 ui.status(_(b'looking for unused includes to remove\n'))
604 611 localfiles = set()
605 612 for n in itertools.chain(outgoing.missing, outgoing.excluded):
606 613 localfiles.update(repo[n].files())
607 614 suggestedremovals = []
608 615 for include in sorted(oldincludes):
609 616 match = narrowspec.match(repo.root, [include], oldexcludes)
610 617 if not any(match(f) for f in localfiles):
611 618 suggestedremovals.append(include)
612 619 if suggestedremovals:
613 620 for s in suggestedremovals:
614 621 ui.status(b'%s\n' % s)
615 622 if (
616 623 ui.promptchoice(
617 624 _(
618 625 b'remove these unused includes (yn)?'
619 626 b'$$ &Yes $$ &No'
620 627 )
621 628 )
622 629 == 0
623 630 ):
624 631 removedincludes.update(suggestedremovals)
625 632 narrowing = True
626 633 else:
627 634 ui.status(_(b'found no unused includes\n'))
628 635
629 636 if narrowing:
630 637 newincludes = oldincludes - removedincludes
631 638 newexcludes = oldexcludes | addedexcludes
632 639 _narrow(
633 640 ui,
634 641 repo,
635 642 remote,
636 643 commoninc,
637 644 oldincludes,
638 645 oldexcludes,
639 646 newincludes,
640 647 newexcludes,
641 648 opts[b'force_delete_local_changes'],
649 opts[b'backup'],
642 650 )
643 651 # _narrow() updated the narrowspec and _widen() below needs to
644 652 # use the updated values as its base (otherwise removed includes
645 653 # and addedexcludes will be lost in the resulting narrowspec)
646 654 oldincludes = newincludes
647 655 oldexcludes = newexcludes
648 656
649 657 if widening:
650 658 newincludes = oldincludes | addedincludes
651 659 newexcludes = oldexcludes - removedexcludes
652 660 _widen(
653 661 ui,
654 662 repo,
655 663 remote,
656 664 commoninc,
657 665 oldincludes,
658 666 oldexcludes,
659 667 newincludes,
660 668 newexcludes,
661 669 )
662 670
663 671 return 0
@@ -1,227 +1,229 b''
1 1 #testcases flat tree
2 2 $ . "$TESTDIR/narrow-library.sh"
3 3
4 4 #if tree
5 5 $ cat << EOF >> $HGRCPATH
6 6 > [experimental]
7 7 > treemanifest = 1
8 8 > EOF
9 9 #endif
10 10
11 11 $ hg init master
12 12 $ cd master
13 13 $ cat >> .hg/hgrc <<EOF
14 14 > [narrow]
15 15 > serveellipses=True
16 16 > EOF
17 17
18 18 $ mkdir inside
19 19 $ echo 'inside' > inside/f
20 20 $ hg add inside/f
21 21 $ hg commit -m 'add inside'
22 22
23 23 $ mkdir widest
24 24 $ echo 'widest' > widest/f
25 25 $ hg add widest/f
26 26 $ hg commit -m 'add widest'
27 27
28 28 $ mkdir outside
29 29 $ echo 'outside' > outside/f
30 30 $ hg add outside/f
31 31 $ hg commit -m 'add outside'
32 32
33 33 $ cd ..
34 34
35 35 narrow clone the inside file
36 36
37 37 $ hg clone --narrow ssh://user@dummy/master narrow --include inside
38 38 requesting all changes
39 39 adding changesets
40 40 adding manifests
41 41 adding file changes
42 42 added 2 changesets with 1 changes to 1 files
43 43 new changesets *:* (glob)
44 44 updating to branch default
45 45 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
46 46 $ cd narrow
47 47 $ hg tracked
48 48 I path:inside
49 49 $ ls -A
50 50 .hg
51 51 inside
52 52 $ cat inside/f
53 53 inside
54 54 $ cd ..
55 55
56 56 add more upstream files which we will include in a wider narrow spec
57 57
58 58 $ cd master
59 59
60 60 $ mkdir wider
61 61 $ echo 'wider' > wider/f
62 62 $ hg add wider/f
63 63 $ echo 'widest v2' > widest/f
64 64 $ hg commit -m 'add wider, update widest'
65 65
66 66 $ echo 'widest v3' > widest/f
67 67 $ hg commit -m 'update widest v3'
68 68
69 69 $ echo 'inside v2' > inside/f
70 70 $ hg commit -m 'update inside'
71 71
72 72 $ mkdir outside2
73 73 $ echo 'outside2' > outside2/f
74 74 $ hg add outside2/f
75 75 $ hg commit -m 'add outside2'
76 76
77 77 $ echo 'widest v4' > widest/f
78 78 $ hg commit -m 'update widest v4'
79 79
80 80 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
81 81 7: update widest v4
82 82 6: add outside2
83 83 5: update inside
84 84 4: update widest v3
85 85 3: add wider, update widest
86 86 2: add outside
87 87 1: add widest
88 88 0: add inside
89 89
90 90 $ cd ..
91 91
92 92 Testing the --import-rules flag of `hg tracked` command
93 93
94 94 $ cd narrow
95 95 $ hg tracked --import-rules
96 96 hg tracked: option --import-rules requires argument
97 97 hg tracked [OPTIONS]... [REMOTE]
98 98
99 99 show or change the current narrowspec
100 100
101 101 options ([+] can be repeated):
102 102
103 103 --addinclude VALUE [+] new paths to include
104 104 --removeinclude VALUE [+] old paths to no longer include
105 105 --auto-remove-includes automatically choose unused includes to
106 106 remove
107 107 --addexclude VALUE [+] new paths to exclude
108 108 --import-rules VALUE import narrowspecs from a file
109 109 --removeexclude VALUE [+] old paths to no longer exclude
110 110 --clear whether to replace the existing narrowspec
111 111 --force-delete-local-changes forces deletion of local changes when
112 112 narrowing
113 --[no-]backup back up local changes when narrowing
114 (default: on)
113 115 --update-working-copy update working copy when the store has
114 116 changed
115 117 -e --ssh CMD specify ssh command to use
116 118 --remotecmd CMD specify hg command to run on the remote side
117 119 --insecure do not verify server certificate (ignoring
118 120 web.cacerts config)
119 121
120 122 (use 'hg tracked -h' to show more help)
121 123 [10]
122 124 $ hg tracked --import-rules doesnotexist
123 125 abort: cannot read narrowspecs from '$TESTTMP/narrow/doesnotexist': $ENOENT$
124 126 [50]
125 127
126 128 $ cat > specs <<EOF
127 129 > %include foo
128 130 > [include]
129 131 > path:widest/
130 132 > [exclude]
131 133 > path:inside/
132 134 > EOF
133 135
134 136 $ hg tracked --import-rules specs
135 137 abort: including other spec files using '%include' is not supported in narrowspec
136 138 [10]
137 139
138 140 $ cat > specs <<EOF
139 141 > [include]
140 142 > outisde
141 143 > [exclude]
142 144 > inside
143 145 > EOF
144 146
145 147 $ hg tracked --import-rules specs
146 148 comparing with ssh://user@dummy/master
147 149 searching for changes
148 150 looking for local changes to affected paths
149 151 deleting data/inside/f.i
150 152 deleting meta/inside/00manifest.i (tree !)
151 153 saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-widen.hg (glob)
152 154 adding changesets
153 155 adding manifests
154 156 adding file changes
155 157 added 2 changesets with 0 changes to 0 files
156 158 $ hg tracked
157 159 I path:outisde
158 160 X path:inside
159 161
160 162 Testing the --import-rules flag with --addinclude and --addexclude
161 163
162 164 $ cat > specs <<EOF
163 165 > [include]
164 166 > widest
165 167 > EOF
166 168
167 169 $ hg tracked --import-rules specs --addinclude 'wider/'
168 170 comparing with ssh://user@dummy/master
169 171 searching for changes
170 172 saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-widen.hg (glob)
171 173 adding changesets
172 174 adding manifests
173 175 adding file changes
174 176 added 3 changesets with 1 changes to 1 files
175 177 $ hg tracked
176 178 I path:outisde
177 179 I path:wider
178 180 I path:widest
179 181 X path:inside
180 182
181 183 $ cat > specs <<EOF
182 184 > [exclude]
183 185 > outside2
184 186 > EOF
185 187
186 188 $ hg tracked --import-rules specs --addexclude 'widest'
187 189 comparing with ssh://user@dummy/master
188 190 searching for changes
189 191 looking for local changes to affected paths
190 192 deleting data/widest/f.i
191 193 deleting meta/widest/00manifest.i (tree !)
192 194 $ hg tracked
193 195 I path:outisde
194 196 I path:wider
195 197 X path:inside
196 198 X path:outside2
197 199 X path:widest
198 200
199 201 $ hg tracked --import-rules specs --clear
200 202 abort: the --clear option is not yet supported
201 203 [10]
202 204
203 205 Testing with passing a out of wdir file
204 206
205 207 $ cat > ../nspecs <<EOF
206 208 > [include]
207 209 > widest
208 210 > EOF
209 211
210 212 $ hg tracked --import-rules ../nspecs
211 213 comparing with ssh://user@dummy/master
212 214 searching for changes
213 215 saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-widen.hg (glob)
214 216 adding changesets
215 217 adding manifests
216 218 adding file changes
217 219 added 3 changesets with 0 changes to 0 files
218 220
219 221 $ cd ..
220 222
221 223 Testing tracked command on a non-narrow repo
222 224
223 225 $ hg init non-narrow
224 226 $ cd non-narrow
225 227 $ hg tracked --addinclude foobar
226 228 abort: the tracked command is only supported on repositories cloned with --narrow
227 229 [10]
@@ -1,494 +1,511 b''
1 1 #testcases flat tree
2 2 #testcases lfs-on lfs-off
3 3
4 4 $ cat >> $HGRCPATH << EOF
5 5 > [experimental]
6 6 > evolution=createmarkers
7 7 > EOF
8 8
9 9 #if lfs-on
10 10 $ cat >> $HGRCPATH <<EOF
11 11 > [extensions]
12 12 > lfs =
13 13 > EOF
14 14 #endif
15 15
16 16 $ . "$TESTDIR/narrow-library.sh"
17 17
18 18 #if tree
19 19 $ cat << EOF >> $HGRCPATH
20 20 > [experimental]
21 21 > treemanifest = 1
22 22 > EOF
23 23 #endif
24 24
25 25 $ hg init master
26 26 $ cd master
27 27 $ cat >> .hg/hgrc <<EOF
28 28 > [narrow]
29 29 > serveellipses=True
30 30 > EOF
31 31 $ for x in `$TESTDIR/seq.py 0 10`
32 32 > do
33 33 > mkdir d$x
34 34 > echo $x > d$x/f
35 35 > hg add d$x/f
36 36 > hg commit -m "add d$x/f"
37 37 > done
38 38 $ hg log -T "{rev}: {desc}\n"
39 39 10: add d10/f
40 40 9: add d9/f
41 41 8: add d8/f
42 42 7: add d7/f
43 43 6: add d6/f
44 44 5: add d5/f
45 45 4: add d4/f
46 46 3: add d3/f
47 47 2: add d2/f
48 48 1: add d1/f
49 49 0: add d0/f
50 50 $ cd ..
51 51
52 52 Error if '.' or '..' are in the directory to track.
53 53 $ hg clone --narrow ssh://user@dummy/master foo --include ./asdf
54 54 abort: "." and ".." are not allowed in narrowspec paths
55 55 [255]
56 56 $ hg clone --narrow ssh://user@dummy/master foo --include asdf/..
57 57 abort: "." and ".." are not allowed in narrowspec paths
58 58 [255]
59 59 $ hg clone --narrow ssh://user@dummy/master foo --include a/./c
60 60 abort: "." and ".." are not allowed in narrowspec paths
61 61 [255]
62 62
63 63 Names with '.' in them are OK.
64 64 $ hg clone --narrow ssh://user@dummy/master should-work --include a/.b/c
65 65 requesting all changes
66 66 adding changesets
67 67 adding manifests
68 68 adding file changes
69 69 added 1 changesets with 0 changes to 0 files
70 70 new changesets * (glob)
71 71 updating to branch default
72 72 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
73 73
74 74 Test repo with local changes
75 75 $ hg clone --narrow ssh://user@dummy/master narrow-local-changes --include d0 --include d3 --include d6
76 76 requesting all changes
77 77 adding changesets
78 78 adding manifests
79 79 adding file changes
80 80 added 6 changesets with 3 changes to 3 files
81 81 new changesets *:* (glob)
82 82 updating to branch default
83 83 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 84 $ cd narrow-local-changes
85 85 $ echo local change >> d0/f
86 86 $ hg ci -m 'local change to d0'
87 87 $ hg co '.^'
88 88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 89 $ echo local change >> d3/f
90 90 $ hg ci -m 'local hidden change to d3'
91 91 created new head
92 92 $ hg ci --amend -m 'local change to d3'
93 93 $ hg tracked --removeinclude d0
94 94 comparing with ssh://user@dummy/master
95 95 searching for changes
96 96 looking for local changes to affected paths
97 97 The following changeset(s) or their ancestors have local changes not on the remote:
98 98 * (glob)
99 99 abort: local changes found
100 100 (use --force-delete-local-changes to ignore)
101 101 [20]
102 102 Check that nothing was removed by the failed attempts
103 103 $ hg tracked
104 104 I path:d0
105 105 I path:d3
106 106 I path:d6
107 107 $ hg files
108 108 d0/f
109 109 d3/f
110 110 d6/f
111 111 $ find *
112 112 d0
113 113 d0/f
114 114 d3
115 115 d3/f
116 116 d6
117 117 d6/f
118 118 $ hg verify -q
119 119 Force deletion of local changes
120 120 $ hg log -T "{rev}: {desc} {outsidenarrow}\n"
121 121 8: local change to d3
122 122 6: local change to d0
123 123 5: add d10/f outsidenarrow
124 124 4: add d6/f
125 125 3: add d5/f outsidenarrow
126 126 2: add d3/f
127 127 1: add d2/f outsidenarrow
128 128 0: add d0/f
129 129 $ hg tracked --removeinclude d0 --force-delete-local-changes
130 130 comparing with ssh://user@dummy/master
131 131 searching for changes
132 132 looking for local changes to affected paths
133 133 The following changeset(s) or their ancestors have local changes not on the remote:
134 134 * (glob)
135 135 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
136 136 deleting data/d0/f.i (reporevlogstore !)
137 137 deleting meta/d0/00manifest.i (tree !)
138 138 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
139 139 deleting data/d0/f/4374b5650fc5ae54ac857c0f0381971fdde376f7 (reposimplestore !)
140 140 deleting data/d0/f/index (reposimplestore !)
141 141
142 142 $ hg log -T "{rev}: {desc} {outsidenarrow}\n"
143 143 7: local change to d3
144 144 5: add d10/f outsidenarrow
145 145 4: add d6/f
146 146 3: add d5/f outsidenarrow
147 147 2: add d3/f
148 148 1: add d2/f outsidenarrow
149 149 0: add d0/f outsidenarrow
150 150 Can restore stripped local changes after widening
151 151 $ hg tracked --addinclude d0 -q
152 152 $ hg unbundle .hg/strip-backup/*-narrow.hg -q
153 153 $ hg --hidden co -r 'desc("local change to d0")' -q
154 154 $ cat d0/f
155 155 0
156 156 local change
157 157 Pruned commits affecting removed paths should not prevent narrowing
158 158 $ hg co '.^'
159 159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 160 $ hg debugobsolete `hg log -T '{node}' -r 'desc("local change to d0")'`
161 161 1 new obsolescence markers
162 162 obsoleted 1 changesets
163 163 $ hg tracked --removeinclude d0
164 164 comparing with ssh://user@dummy/master
165 165 searching for changes
166 166 looking for local changes to affected paths
167 167 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
168 168 deleting data/d0/f.i (reporevlogstore !)
169 169 deleting meta/d0/00manifest.i (tree !)
170 170 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
171 171 deleting data/d0/f/4374b5650fc5ae54ac857c0f0381971fdde376f7 (reposimplestore !)
172 172 deleting data/d0/f/index (reposimplestore !)
173 173
174 174 Updates off of stripped commit if necessary
175 175 $ hg co -r 'desc("local change to d3")' -q
176 176 $ echo local change >> d6/f
177 177 $ hg ci -m 'local change to d6'
178 178 $ hg tracked --removeinclude d3 --force-delete-local-changes
179 179 comparing with ssh://user@dummy/master
180 180 searching for changes
181 181 looking for local changes to affected paths
182 182 The following changeset(s) or their ancestors have local changes not on the remote:
183 183 * (glob)
184 184 * (glob)
185 185 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
186 186 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
187 187 deleting data/d3/f.i (reporevlogstore !)
188 188 deleting meta/d3/00manifest.i (tree !)
189 189 deleting data/d3/f/2661d26c649684b482d10f91960cc3db683c38b4 (reposimplestore !)
190 190 deleting data/d3/f/99fa7136105a15e2045ce3d9152e4837c5349e4d (reposimplestore !)
191 191 deleting data/d3/f/index (reposimplestore !)
192 192 $ hg log -T '{desc}\n' -r .
193 193 add d10/f
194 194 Updates to nullid if necessary
195 195 $ hg tracked --addinclude d3 -q
196 196 $ hg co null -q
197 197 $ mkdir d3
198 198 $ echo local change > d3/f
199 199 $ hg add d3/f
200 200 $ hg ci -m 'local change to d3'
201 201 created new head
202 202 $ hg tracked --removeinclude d3 --force-delete-local-changes
203 203 comparing with ssh://user@dummy/master
204 204 searching for changes
205 205 looking for local changes to affected paths
206 206 The following changeset(s) or their ancestors have local changes not on the remote:
207 207 * (glob)
208 208 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
209 209 saved backup bundle to $TESTTMP/narrow-local-changes/.hg/strip-backup/*-narrow.hg (glob)
210 210 deleting data/d3/f.i (reporevlogstore !)
211 211 deleting meta/d3/00manifest.i (tree !)
212 212 deleting data/d3/f/2661d26c649684b482d10f91960cc3db683c38b4 (reposimplestore !)
213 213 deleting data/d3/f/5ce0767945cbdbca3b924bb9fbf5143f72ab40ac (reposimplestore !)
214 214 deleting data/d3/f/index (reposimplestore !)
215 215 $ hg id
216 216 000000000000
217 217 $ cd ..
218 218
219 219 Narrowing doesn't resurrect old commits (unlike what regular `hg strip` does)
220 220 $ hg clone --narrow ssh://user@dummy/master narrow-obsmarkers --include d0 --include d3 -q
221 221 $ cd narrow-obsmarkers
222 222 $ echo a >> d0/f2
223 223 $ hg add d0/f2
224 224 $ hg ci -m 'modify d0/'
225 225 $ echo a >> d3/f2
226 226 $ hg add d3/f2
227 227 $ hg commit --amend -m 'modify d0/ and d3/'
228 228 $ hg log -T "{rev}: {desc}\n"
229 229 5: modify d0/ and d3/
230 230 3: add d10/f
231 231 2: add d3/f
232 232 1: add d2/f
233 233 0: add d0/f
234 234 $ hg tracked --removeinclude d3 --force-delete-local-changes -q
235 235 $ hg log -T "{rev}: {desc}\n"
236 236 3: add d10/f
237 237 2: add d3/f
238 238 1: add d2/f
239 239 0: add d0/f
240 240 $ cd ..
241 241
242 242 Widening doesn't lose bookmarks
243 243 $ hg clone --narrow ssh://user@dummy/master widen-bookmarks --include d0 -q
244 244 $ cd widen-bookmarks
245 245 $ hg bookmark my-bookmark
246 246 $ hg log -T "{rev}: {desc} {bookmarks}\n"
247 247 1: add d10/f my-bookmark
248 248 0: add d0/f
249 249 $ hg tracked --addinclude d3 -q
250 250 $ hg log -T "{rev}: {desc} {bookmarks}\n"
251 251 3: add d10/f my-bookmark
252 252 2: add d3/f
253 253 1: add d2/f
254 254 0: add d0/f
255 255 $ cd ..
256 256
257 257 Can remove last include, making repo empty
258 258 $ hg clone --narrow ssh://user@dummy/master narrow-empty --include d0 -r 5
259 259 adding changesets
260 260 adding manifests
261 261 adding file changes
262 262 added 2 changesets with 1 changes to 1 files
263 263 new changesets *:* (glob)
264 264 updating to branch default
265 265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 266 $ cd narrow-empty
267 267 $ hg tracked --removeinclude d0
268 268 comparing with ssh://user@dummy/master
269 269 searching for changes
270 270 looking for local changes to affected paths
271 271 deleting data/d0/f.i (reporevlogstore !)
272 272 deleting meta/d0/00manifest.i (tree !)
273 273 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
274 274 deleting data/d0/f/index (reposimplestore !)
275 275 $ hg tracked
276 276 $ hg files
277 277 [1]
278 278 $ test -d d0
279 279 [1]
280 280 Do some work in the empty clone
281 281 $ hg diff --change .
282 282 $ hg branch foo
283 283 marked working directory as branch foo
284 284 (branches are permanent and global, did you want a bookmark?)
285 285 $ hg ci -m empty
286 286 $ hg log -T "{rev}: {desc} {outsidenarrow}\n"
287 287 2: empty
288 288 1: add d5/f outsidenarrow
289 289 0: add d0/f outsidenarrow
290 290 $ hg pull -q
291 291 Can widen the empty clone
292 292 $ hg tracked --addinclude d0
293 293 comparing with ssh://user@dummy/master
294 294 searching for changes
295 295 saved backup bundle to $TESTTMP/narrow-empty/.hg/strip-backup/*-widen.hg (glob)
296 296 adding changesets
297 297 adding manifests
298 298 adding file changes
299 299 added 3 changesets with 1 changes to 1 files
300 300 $ hg tracked
301 301 I path:d0
302 302 $ hg files
303 303 d0/f
304 304 $ find *
305 305 d0
306 306 d0/f
307 307 $ cd ..
308 308
309 309 TODO(martinvonz): test including e.g. d3/g and then removing it once
310 310 https://bitbucket.org/Google/narrowhg/issues/6 is fixed
311 311
312 312 $ hg clone --narrow ssh://user@dummy/master narrow --include d0 --include d3 --include d6 --include d9
313 313 requesting all changes
314 314 adding changesets
315 315 adding manifests
316 316 adding file changes
317 317 added 8 changesets with 4 changes to 4 files
318 318 new changesets *:* (glob)
319 319 updating to branch default
320 320 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
321 321 $ cd narrow
322 322 $ hg tracked
323 323 I path:d0
324 324 I path:d3
325 325 I path:d6
326 326 I path:d9
327 327 $ hg tracked --removeinclude d6
328 328 comparing with ssh://user@dummy/master
329 329 searching for changes
330 330 looking for local changes to affected paths
331 331 deleting data/d6/f.i (reporevlogstore !)
332 332 deleting meta/d6/00manifest.i (tree !)
333 333 deleting data/d6/f/7339d30678f451ac8c3f38753beeb4cf2e1655c7 (reposimplestore !)
334 334 deleting data/d6/f/index (reposimplestore !)
335 335 $ hg tracked
336 336 I path:d0
337 337 I path:d3
338 338 I path:d9
339 339 #if repofncache
340 340 $ hg debugrebuildfncache
341 341 fncache already up to date
342 342 #endif
343 343 $ find *
344 344 d0
345 345 d0/f
346 346 d3
347 347 d3/f
348 348 d9
349 349 d9/f
350 350 $ hg verify -q
351 351 $ hg tracked --addexclude d3/f
352 352 comparing with ssh://user@dummy/master
353 353 searching for changes
354 354 looking for local changes to affected paths
355 355 deleting data/d3/f.i (reporevlogstore !)
356 356 deleting data/d3/f/2661d26c649684b482d10f91960cc3db683c38b4 (reposimplestore !)
357 357 deleting data/d3/f/index (reposimplestore !)
358 358 $ hg tracked
359 359 I path:d0
360 360 I path:d3
361 361 I path:d9
362 362 X path:d3/f
363 363 #if repofncache
364 364 $ hg debugrebuildfncache
365 365 fncache already up to date
366 366 #endif
367 367 $ find *
368 368 d0
369 369 d0/f
370 370 d9
371 371 d9/f
372 372 $ hg verify -q
373 373 $ hg tracked --addexclude d0
374 374 comparing with ssh://user@dummy/master
375 375 searching for changes
376 376 looking for local changes to affected paths
377 377 deleting data/d0/f.i (reporevlogstore !)
378 378 deleting meta/d0/00manifest.i (tree !)
379 379 deleting data/d0/f/362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (reposimplestore !)
380 380 deleting data/d0/f/index (reposimplestore !)
381 381 $ hg tracked
382 382 I path:d3
383 383 I path:d9
384 384 X path:d0
385 385 X path:d3/f
386 386 #if repofncache
387 387 $ hg debugrebuildfncache
388 388 fncache already up to date
389 389 #endif
390 390 $ find *
391 391 d9
392 392 d9/f
393 393
394 394 Make a 15 of changes to d9 to test the path without --verbose
395 395 (Note: using regexes instead of "* (glob)" because if the test fails, it
396 396 produces more sensible diffs)
397 397 $ hg tracked
398 398 I path:d3
399 399 I path:d9
400 400 X path:d0
401 401 X path:d3/f
402 402 $ for x in `$TESTDIR/seq.py 1 15`
403 403 > do
404 404 > echo local change >> d9/f
405 405 > hg commit -m "change $x to d9/f"
406 406 > done
407 407 $ hg tracked --removeinclude d9
408 408 comparing with ssh://user@dummy/master
409 409 searching for changes
410 410 looking for local changes to affected paths
411 411 The following changeset(s) or their ancestors have local changes not on the remote:
412 412 ^[0-9a-f]{12}$ (re)
413 413 ^[0-9a-f]{12}$ (re)
414 414 ^[0-9a-f]{12}$ (re)
415 415 ^[0-9a-f]{12}$ (re)
416 416 ^[0-9a-f]{12}$ (re)
417 417 ^[0-9a-f]{12}$ (re)
418 418 ^[0-9a-f]{12}$ (re)
419 419 ^[0-9a-f]{12}$ (re)
420 420 ^[0-9a-f]{12}$ (re)
421 421 ^[0-9a-f]{12}$ (re)
422 422 ...and 5 more, use --verbose to list all
423 423 abort: local changes found
424 424 (use --force-delete-local-changes to ignore)
425 425 [20]
426 426 Now test it *with* verbose.
427 427 $ hg tracked --removeinclude d9 --verbose
428 428 comparing with ssh://user@dummy/master
429 429 searching for changes
430 430 looking for local changes to affected paths
431 431 The following changeset(s) or their ancestors have local changes not on the remote:
432 432 ^[0-9a-f]{12}$ (re)
433 433 ^[0-9a-f]{12}$ (re)
434 434 ^[0-9a-f]{12}$ (re)
435 435 ^[0-9a-f]{12}$ (re)
436 436 ^[0-9a-f]{12}$ (re)
437 437 ^[0-9a-f]{12}$ (re)
438 438 ^[0-9a-f]{12}$ (re)
439 439 ^[0-9a-f]{12}$ (re)
440 440 ^[0-9a-f]{12}$ (re)
441 441 ^[0-9a-f]{12}$ (re)
442 442 ^[0-9a-f]{12}$ (re)
443 443 ^[0-9a-f]{12}$ (re)
444 444 ^[0-9a-f]{12}$ (re)
445 445 ^[0-9a-f]{12}$ (re)
446 446 ^[0-9a-f]{12}$ (re)
447 447 abort: local changes found
448 448 (use --force-delete-local-changes to ignore)
449 449 [20]
450 450 $ cd ..
451 451
452 452 Test --auto-remove-includes
453 453 $ hg clone --narrow ssh://user@dummy/master narrow-auto-remove -q \
454 454 > --include d0 --include d1 --include d2
455 455 $ cd narrow-auto-remove
456 456 $ echo a >> d0/f
457 457 $ hg ci -m 'local change to d0'
458 458 $ hg co '.^'
459 459 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
460 460 $ echo a >> d1/f
461 461 $ hg ci -m 'local change to d1'
462 462 created new head
463 463 $ hg debugobsolete $(hg log -T '{node}' -r 'desc("local change to d0")')
464 464 1 new obsolescence markers
465 465 obsoleted 1 changesets
466 466 $ echo n | hg tracked --auto-remove-includes --config ui.interactive=yes
467 467 comparing with ssh://user@dummy/master
468 468 searching for changes
469 469 looking for unused includes to remove
470 470 path:d0
471 471 path:d2
472 472 remove these unused includes (yn)? n
473 473 $ hg tracked --auto-remove-includes
474 474 comparing with ssh://user@dummy/master
475 475 searching for changes
476 476 looking for unused includes to remove
477 477 path:d0
478 478 path:d2
479 479 remove these unused includes (yn)? y
480 480 looking for local changes to affected paths
481 481 saved backup bundle to $TESTTMP/narrow-auto-remove/.hg/strip-backup/*-narrow.hg (glob)
482 482 deleting data/d0/f.i
483 483 deleting data/d2/f.i
484 484 deleting meta/d0/00manifest.i (tree !)
485 485 deleting meta/d2/00manifest.i (tree !)
486 486 $ hg tracked
487 487 I path:d1
488 488 $ hg files
489 489 d1/f
490 490 $ hg tracked --auto-remove-includes
491 491 comparing with ssh://user@dummy/master
492 492 searching for changes
493 493 looking for unused includes to remove
494 494 found no unused includes
495 Test --no-backup
496 $ hg tracked --addinclude d0 --addinclude d2 -q
497 $ hg unbundle .hg/strip-backup/*-narrow.hg -q
498 $ rm .hg/strip-backup/*
499 $ hg tracked --auto-remove-includes --no-backup
500 comparing with ssh://user@dummy/master
501 searching for changes
502 looking for unused includes to remove
503 path:d0
504 path:d2
505 remove these unused includes (yn)? y
506 looking for local changes to affected paths
507 deleting data/d0/f.i
508 deleting data/d2/f.i
509 deleting meta/d0/00manifest.i (tree !)
510 deleting meta/d2/00manifest.i (tree !)
511 $ ls .hg/strip-backup/
General Comments 0
You need to be logged in to leave comments. Login now