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 |