diff --git a/hgext/sparse.py b/hgext/sparse.py --- a/hgext/sparse.py +++ b/hgext/sparse.py @@ -74,8 +74,6 @@ certain files:: from __future__ import absolute_import -import collections - from mercurial.i18n import _ from mercurial.node import nullid from mercurial import ( @@ -139,91 +137,8 @@ def replacefilecache(cls, propname, repl propname)) def _setupupdates(ui): - def _calculateupdates(orig, repo, wctx, mctx, ancestors, branchmerge, *arg, - **kwargs): - """Filter updates to only lay out files that match the sparse rules. - """ - actions, diverge, renamedelete = orig(repo, wctx, mctx, ancestors, - branchmerge, *arg, **kwargs) - - oldrevs = [pctx.rev() for pctx in wctx.parents()] - oldsparsematch = sparse.matcher(repo, oldrevs) - - if oldsparsematch.always(): - return actions, diverge, renamedelete - - files = set() - prunedactions = {} - - if branchmerge: - # If we're merging, use the wctx filter, since we're merging into - # the wctx. - sparsematch = sparse.matcher(repo, [wctx.parents()[0].rev()]) - else: - # If we're updating, use the target context's filter, since we're - # moving to the target context. - sparsematch = sparse.matcher(repo, [mctx.rev()]) - - temporaryfiles = [] - for file, action in actions.iteritems(): - type, args, msg = action - files.add(file) - if sparsematch(file): - prunedactions[file] = action - elif type == 'm': - temporaryfiles.append(file) - prunedactions[file] = action - elif branchmerge: - if type != 'k': - temporaryfiles.append(file) - prunedactions[file] = action - elif type == 'f': - prunedactions[file] = action - elif file in wctx: - prunedactions[file] = ('r', args, msg) - - if len(temporaryfiles) > 0: - ui.status(_("temporarily included %d file(s) in the sparse checkout" - " for merging\n") % len(temporaryfiles)) - sparse.addtemporaryincludes(repo, temporaryfiles) - - # Add the new files to the working copy so they can be merged, etc - actions = [] - message = 'temporarily adding to sparse checkout' - wctxmanifest = repo[None].manifest() - for file in temporaryfiles: - if file in wctxmanifest: - fctx = repo[None][file] - actions.append((file, (fctx.flags(), False), message)) - - typeactions = collections.defaultdict(list) - typeactions['g'] = actions - mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], - False) - - dirstate = repo.dirstate - for file, flags, msg in actions: - dirstate.normal(file) - - profiles = sparse.activeprofiles(repo) - changedprofiles = profiles & files - # If an active profile changed during the update, refresh the checkout. - # Don't do this during a branch merge, since all incoming changes should - # have been handled by the temporary includes above. - if changedprofiles and not branchmerge: - mf = mctx.manifest() - for file in mf: - old = oldsparsematch(file) - new = sparsematch(file) - if not old and new: - flags = mf.flags(file) - prunedactions[file] = ('g', (flags, False), '') - elif old and not new: - prunedactions[file] = ('r', [], '') - - return prunedactions, diverge, renamedelete - - extensions.wrapfunction(mergemod, 'calculateupdates', _calculateupdates) + extensions.wrapfunction(mergemod, 'calculateupdates', + sparse.calculateupdates) def _setupcommit(ui): def _refreshoncommit(orig, self, node): diff --git a/mercurial/sparse.py b/mercurial/sparse.py --- a/mercurial/sparse.py +++ b/mercurial/sparse.py @@ -300,3 +300,87 @@ def matcher(repo, revs=None, includetemp repo._sparsematchercache[key] = result return result + +def calculateupdates(orig, repo, wctx, mctx, ancestors, branchmerge, *arg, + **kwargs): + """Filter updates to only lay out files that match the sparse rules. + """ + actions, diverge, renamedelete = orig(repo, wctx, mctx, ancestors, + branchmerge, *arg, **kwargs) + + oldrevs = [pctx.rev() for pctx in wctx.parents()] + oldsparsematch = matcher(repo, oldrevs) + + if oldsparsematch.always(): + return actions, diverge, renamedelete + + files = set() + prunedactions = {} + + if branchmerge: + # If we're merging, use the wctx filter, since we're merging into + # the wctx. + sparsematch = matcher(repo, [wctx.parents()[0].rev()]) + else: + # If we're updating, use the target context's filter, since we're + # moving to the target context. + sparsematch = matcher(repo, [mctx.rev()]) + + temporaryfiles = [] + for file, action in actions.iteritems(): + type, args, msg = action + files.add(file) + if sparsematch(file): + prunedactions[file] = action + elif type == 'm': + temporaryfiles.append(file) + prunedactions[file] = action + elif branchmerge: + if type != 'k': + temporaryfiles.append(file) + prunedactions[file] = action + elif type == 'f': + prunedactions[file] = action + elif file in wctx: + prunedactions[file] = ('r', args, msg) + + if len(temporaryfiles) > 0: + repo.ui.status(_('temporarily included %d file(s) in the sparse ' + 'checkout for merging\n') % len(temporaryfiles)) + addtemporaryincludes(repo, temporaryfiles) + + # Add the new files to the working copy so they can be merged, etc + actions = [] + message = 'temporarily adding to sparse checkout' + wctxmanifest = repo[None].manifest() + for file in temporaryfiles: + if file in wctxmanifest: + fctx = repo[None][file] + actions.append((file, (fctx.flags(), False), message)) + + typeactions = collections.defaultdict(list) + typeactions['g'] = actions + mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], + False) + + dirstate = repo.dirstate + for file, flags, msg in actions: + dirstate.normal(file) + + profiles = activeprofiles(repo) + changedprofiles = profiles & files + # If an active profile changed during the update, refresh the checkout. + # Don't do this during a branch merge, since all incoming changes should + # have been handled by the temporary includes above. + if changedprofiles and not branchmerge: + mf = mctx.manifest() + for file in mf: + old = oldsparsematch(file) + new = sparsematch(file) + if not old and new: + flags = mf.flags(file) + prunedactions[file] = ('g', (flags, False), '') + elif old and not new: + prunedactions[file] = ('r', [], '') + + return prunedactions, diverge, renamedelete