298 result = matchmod.forceincludematcher(result, tempincludes) |
298 result = matchmod.forceincludematcher(result, tempincludes) |
299 |
299 |
300 repo._sparsematchercache[key] = result |
300 repo._sparsematchercache[key] = result |
301 |
301 |
302 return result |
302 return result |
|
303 |
|
304 def calculateupdates(orig, repo, wctx, mctx, ancestors, branchmerge, *arg, |
|
305 **kwargs): |
|
306 """Filter updates to only lay out files that match the sparse rules. |
|
307 """ |
|
308 actions, diverge, renamedelete = orig(repo, wctx, mctx, ancestors, |
|
309 branchmerge, *arg, **kwargs) |
|
310 |
|
311 oldrevs = [pctx.rev() for pctx in wctx.parents()] |
|
312 oldsparsematch = matcher(repo, oldrevs) |
|
313 |
|
314 if oldsparsematch.always(): |
|
315 return actions, diverge, renamedelete |
|
316 |
|
317 files = set() |
|
318 prunedactions = {} |
|
319 |
|
320 if branchmerge: |
|
321 # If we're merging, use the wctx filter, since we're merging into |
|
322 # the wctx. |
|
323 sparsematch = matcher(repo, [wctx.parents()[0].rev()]) |
|
324 else: |
|
325 # If we're updating, use the target context's filter, since we're |
|
326 # moving to the target context. |
|
327 sparsematch = matcher(repo, [mctx.rev()]) |
|
328 |
|
329 temporaryfiles = [] |
|
330 for file, action in actions.iteritems(): |
|
331 type, args, msg = action |
|
332 files.add(file) |
|
333 if sparsematch(file): |
|
334 prunedactions[file] = action |
|
335 elif type == 'm': |
|
336 temporaryfiles.append(file) |
|
337 prunedactions[file] = action |
|
338 elif branchmerge: |
|
339 if type != 'k': |
|
340 temporaryfiles.append(file) |
|
341 prunedactions[file] = action |
|
342 elif type == 'f': |
|
343 prunedactions[file] = action |
|
344 elif file in wctx: |
|
345 prunedactions[file] = ('r', args, msg) |
|
346 |
|
347 if len(temporaryfiles) > 0: |
|
348 repo.ui.status(_('temporarily included %d file(s) in the sparse ' |
|
349 'checkout for merging\n') % len(temporaryfiles)) |
|
350 addtemporaryincludes(repo, temporaryfiles) |
|
351 |
|
352 # Add the new files to the working copy so they can be merged, etc |
|
353 actions = [] |
|
354 message = 'temporarily adding to sparse checkout' |
|
355 wctxmanifest = repo[None].manifest() |
|
356 for file in temporaryfiles: |
|
357 if file in wctxmanifest: |
|
358 fctx = repo[None][file] |
|
359 actions.append((file, (fctx.flags(), False), message)) |
|
360 |
|
361 typeactions = collections.defaultdict(list) |
|
362 typeactions['g'] = actions |
|
363 mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], |
|
364 False) |
|
365 |
|
366 dirstate = repo.dirstate |
|
367 for file, flags, msg in actions: |
|
368 dirstate.normal(file) |
|
369 |
|
370 profiles = activeprofiles(repo) |
|
371 changedprofiles = profiles & files |
|
372 # If an active profile changed during the update, refresh the checkout. |
|
373 # Don't do this during a branch merge, since all incoming changes should |
|
374 # have been handled by the temporary includes above. |
|
375 if changedprofiles and not branchmerge: |
|
376 mf = mctx.manifest() |
|
377 for file in mf: |
|
378 old = oldsparsematch(file) |
|
379 new = sparsematch(file) |
|
380 if not old and new: |
|
381 flags = mf.flags(file) |
|
382 prunedactions[file] = ('g', (flags, False), '') |
|
383 elif old and not new: |
|
384 prunedactions[file] = ('r', [], '') |
|
385 |
|
386 return prunedactions, diverge, renamedelete |