mercurial/sparse.py
changeset 33324 33d0859c37bd
parent 33323 252500520d60
child 33325 38df146d0697
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