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