comparison mercurial/sparse.py @ 33324:33d0859c37bd

sparse: move working directory refreshing into core This is a pretty straightforward move of the code. I converted the "force" argument to a keyword argument. Like other recent changes, this code is tightly coupled with working directory update code in merge.py. I suspect the code will become more tightly coupled over time, possibly even moved to merge.py. For now, let's get the code in core.
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 06 Jul 2017 14:53:08 -0700
parents 252500520d60
children 38df146d0697
comparison
equal deleted inserted replaced
33323:252500520d60 33324:33d0859c37bd
380 prunedactions[file] = ('g', (flags, False), '') 380 prunedactions[file] = ('g', (flags, False), '')
381 elif old and not new: 381 elif old and not new:
382 prunedactions[file] = ('r', [], '') 382 prunedactions[file] = ('r', [], '')
383 383
384 return prunedactions 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