##// END OF EJS Templates
sparse: move working directory refreshing into core...
Gregory Szorc -
r33324:33d0859c default
parent child Browse files
Show More
@@ -86,7 +86,6 b' from mercurial import ('
86 86 hg,
87 87 localrepo,
88 88 match as matchmod,
89 merge as mergemod,
90 89 registrar,
91 90 sparse,
92 91 util,
@@ -149,7 +148,7 b' def _setupcommit(ui):'
149 148 if set(profiles) & set(ctx.files()):
150 149 origstatus = repo.status()
151 150 origsparsematch = sparse.matcher(repo)
152 _refresh(repo.ui, repo, origstatus, origsparsematch, True)
151 sparse.refreshwdir(repo, origstatus, origsparsematch, force=True)
153 152
154 153 sparse.prunetemporaryincludes(repo)
155 154
@@ -398,7 +397,8 b' def debugsparse(ui, repo, *pats, **opts)'
398 397 wlock = repo.wlock()
399 398 fcounts = map(
400 399 len,
401 _refresh(ui, repo, repo.status(), sparse.matcher(repo), force))
400 sparse.refreshwdir(repo, repo.status(), sparse.matcher(repo),
401 force=force))
402 402 _verbose_output(ui, opts, 0, 0, 0, *fcounts)
403 403 finally:
404 404 wlock.release()
@@ -452,7 +452,9 b' def _config(ui, repo, pats, opts, includ'
452 452 sparse.writeconfig(repo, newinclude, newexclude, newprofiles)
453 453
454 454 fcounts = map(
455 len, _refresh(ui, repo, oldstatus, oldsparsematch, force))
455 len,
456 sparse.refreshwdir(repo, oldstatus, oldsparsematch,
457 force=force))
456 458
457 459 profilecount = (len(newprofiles - oldprofiles) -
458 460 len(oldprofiles - newprofiles))
@@ -516,7 +518,9 b' def _import(ui, repo, files, opts, force'
516 518
517 519 try:
518 520 fcounts = map(
519 len, _refresh(ui, repo, oldstatus, oldsparsematch, force))
521 len,
522 sparse.refreshwdir(repo, oldstatus, oldsparsematch,
523 force=force))
520 524 except Exception:
521 525 sparse.writeconfig(repo, oincludes, oexcludes, oprofiles)
522 526 raise
@@ -533,101 +537,7 b' def _clear(ui, repo, files, force=False)'
533 537 oldstatus = repo.status()
534 538 oldsparsematch = sparse.matcher(repo)
535 539 sparse.writeconfig(repo, set(), set(), profiles)
536 _refresh(ui, repo, oldstatus, oldsparsematch, force)
537
538 def _refresh(ui, repo, origstatus, origsparsematch, force):
539 """Refreshes which files are on disk by comparing the old status and
540 sparsematch with the new sparsematch.
541
542 Will raise an exception if a file with pending changes is being excluded
543 or included (unless force=True).
544 """
545 modified, added, removed, deleted, unknown, ignored, clean = origstatus
546
547 # Verify there are no pending changes
548 pending = set()
549 pending.update(modified)
550 pending.update(added)
551 pending.update(removed)
552 sparsematch = sparse.matcher(repo)
553 abort = False
554 for file in pending:
555 if not sparsematch(file):
556 ui.warn(_("pending changes to '%s'\n") % file)
557 abort = not force
558 if abort:
559 raise error.Abort(_("could not update sparseness due to " +
560 "pending changes"))
561
562 # Calculate actions
563 dirstate = repo.dirstate
564 ctx = repo['.']
565 added = []
566 lookup = []
567 dropped = []
568 mf = ctx.manifest()
569 files = set(mf)
570
571 actions = {}
572
573 for file in files:
574 old = origsparsematch(file)
575 new = sparsematch(file)
576 # Add files that are newly included, or that don't exist in
577 # the dirstate yet.
578 if (new and not old) or (old and new and not file in dirstate):
579 fl = mf.flags(file)
580 if repo.wvfs.exists(file):
581 actions[file] = ('e', (fl,), '')
582 lookup.append(file)
583 else:
584 actions[file] = ('g', (fl, False), '')
585 added.append(file)
586 # Drop files that are newly excluded, or that still exist in
587 # the dirstate.
588 elif (old and not new) or (not old and not new and file in dirstate):
589 dropped.append(file)
590 if file not in pending:
591 actions[file] = ('r', [], '')
592
593 # Verify there are no pending changes in newly included files
594 abort = False
595 for file in lookup:
596 ui.warn(_("pending changes to '%s'\n") % file)
597 abort = not force
598 if abort:
599 raise error.Abort(_("cannot change sparseness due to " +
600 "pending changes (delete the files or use --force " +
601 "to bring them back dirty)"))
602
603 # Check for files that were only in the dirstate.
604 for file, state in dirstate.iteritems():
605 if not file in files:
606 old = origsparsematch(file)
607 new = sparsematch(file)
608 if old and not new:
609 dropped.append(file)
610
611 # Apply changes to disk
612 typeactions = dict((m, []) for m in 'a f g am cd dc r dm dg m e k'.split())
613 for f, (m, args, msg) in actions.iteritems():
614 if m not in typeactions:
615 typeactions[m] = []
616 typeactions[m].append((f, args, msg))
617 mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], False)
618
619 # Fix dirstate
620 for file in added:
621 dirstate.normal(file)
622
623 for file in dropped:
624 dirstate.drop(file)
625
626 for file in lookup:
627 # File exists on disk, and we're bringing it back in an unknown state.
628 dirstate.normallookup(file)
629
630 return added, dropped, lookup
540 sparse.refreshwdir(repo, oldstatus, oldsparsematch, force)
631 541
632 542 def _verbose_output(ui, opts, profilecount, includecount, excludecount, added,
633 543 dropped, lookup):
@@ -382,3 +382,102 b' def filterupdatesactions(repo, wctx, mct'
382 382 prunedactions[file] = ('r', [], '')
383 383
384 384 return prunedactions
385
386 def refreshwdir(repo, origstatus, origsparsematch, force=False):
387 """Refreshes working directory by taking sparse config into account.
388
389 The old status and sparse matcher is compared against the current sparse
390 matcher.
391
392 Will abort if a file with pending changes is being excluded or included
393 unless ``force`` is True.
394 """
395 modified, added, removed, deleted, unknown, ignored, clean = origstatus
396
397 # Verify there are no pending changes
398 pending = set()
399 pending.update(modified)
400 pending.update(added)
401 pending.update(removed)
402 sparsematch = matcher(repo)
403 abort = False
404
405 for f in pending:
406 if not sparsematch(f):
407 repo.ui.warn(_("pending changes to '%s'\n") % f)
408 abort = not force
409
410 if abort:
411 raise error.Abort(_('could not update sparseness due to pending '
412 'changes'))
413
414 # Calculate actions
415 dirstate = repo.dirstate
416 ctx = repo['.']
417 added = []
418 lookup = []
419 dropped = []
420 mf = ctx.manifest()
421 files = set(mf)
422
423 actions = {}
424
425 for file in files:
426 old = origsparsematch(file)
427 new = sparsematch(file)
428 # Add files that are newly included, or that don't exist in
429 # the dirstate yet.
430 if (new and not old) or (old and new and not file in dirstate):
431 fl = mf.flags(file)
432 if repo.wvfs.exists(file):
433 actions[file] = ('e', (fl,), '')
434 lookup.append(file)
435 else:
436 actions[file] = ('g', (fl, False), '')
437 added.append(file)
438 # Drop files that are newly excluded, or that still exist in
439 # the dirstate.
440 elif (old and not new) or (not old and not new and file in dirstate):
441 dropped.append(file)
442 if file not in pending:
443 actions[file] = ('r', [], '')
444
445 # Verify there are no pending changes in newly included files
446 abort = False
447 for file in lookup:
448 repo.ui.warn(_("pending changes to '%s'\n") % file)
449 abort = not force
450 if abort:
451 raise error.Abort(_('cannot change sparseness due to pending '
452 'changes (delete the files or use '
453 '--force to bring them back dirty)'))
454
455 # Check for files that were only in the dirstate.
456 for file, state in dirstate.iteritems():
457 if not file in files:
458 old = origsparsematch(file)
459 new = sparsematch(file)
460 if old and not new:
461 dropped.append(file)
462
463 # Apply changes to disk
464 typeactions = dict((m, []) for m in 'a f g am cd dc r dm dg m e k'.split())
465 for f, (m, args, msg) in actions.iteritems():
466 if m not in typeactions:
467 typeactions[m] = []
468 typeactions[m].append((f, args, msg))
469
470 mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], False)
471
472 # Fix dirstate
473 for file in added:
474 dirstate.normal(file)
475
476 for file in dropped:
477 dirstate.drop(file)
478
479 for file in lookup:
480 # File exists on disk, and we're bringing it back in an unknown state.
481 dirstate.normallookup(file)
482
483 return added, dropped, lookup
@@ -147,16 +147,11 b' Same tests, with -Tjson enabled to outpu'
147 147 If importing results in no new rules being added, no refresh should take place!
148 148
149 149 $ cat > $TESTTMP/trap_sparse_refresh.py <<EOF
150 > from mercurial import error, extensions
150 > from mercurial import error, sparse
151 151 > def extsetup(ui):
152 > def abort_refresh(ui, *args):
152 > def abort_refresh(*args, **kwargs):
153 153 > raise error.Abort('sparse._refresh called!')
154 > def sparseloaded(loaded):
155 > if not loaded:
156 > return
157 > sparse = extensions.find('sparse')
158 > sparse._refresh = abort_refresh
159 > extensions.afterloaded('sparse', sparseloaded)
154 > sparse.refreshwdir = abort_refresh
160 155 > EOF
161 156 $ cat >> $HGRCPATH <<EOF
162 157 > [extensions]
General Comments 0
You need to be logged in to leave comments. Login now