248 def _refreshoncommit(orig, self, node): |
248 def _refreshoncommit(orig, self, node): |
249 """Refresh the checkout when commits touch .hgsparse |
249 """Refresh the checkout when commits touch .hgsparse |
250 """ |
250 """ |
251 orig(self, node) |
251 orig(self, node) |
252 repo = self._repo |
252 repo = self._repo |
253 if util.safehasattr(repo, 'getsparsepatterns'): |
253 |
254 ctx = repo[node] |
254 ctx = repo[node] |
255 _, _, profiles = repo.getsparsepatterns(ctx.rev()) |
255 profiles = sparse.patternsforrev(repo, ctx.rev())[2] |
256 if set(profiles) & set(ctx.files()): |
256 |
257 origstatus = repo.status() |
257 # profiles will only have data if sparse is enabled. |
258 origsparsematch = repo.sparsematch() |
258 if set(profiles) & set(ctx.files()): |
259 _refresh(repo.ui, repo, origstatus, origsparsematch, True) |
259 origstatus = repo.status() |
260 |
260 origsparsematch = repo.sparsematch() |
|
261 _refresh(repo.ui, repo, origstatus, origsparsematch, True) |
|
262 |
|
263 if util.safehasattr(repo, 'prunetemporaryincludes'): |
261 repo.prunetemporaryincludes() |
264 repo.prunetemporaryincludes() |
262 |
265 |
263 extensions.wrapfunction(context.committablectx, 'markcommitted', |
266 extensions.wrapfunction(context.committablectx, 'markcommitted', |
264 _refreshoncommit) |
267 _refreshoncommit) |
265 |
268 |
408 return orig(self, *args) |
411 return orig(self, *args) |
409 extensions.wrapfunction(dirstate.dirstate, func, _wrapper) |
412 extensions.wrapfunction(dirstate.dirstate, func, _wrapper) |
410 |
413 |
411 def _wraprepo(ui, repo): |
414 def _wraprepo(ui, repo): |
412 class SparseRepo(repo.__class__): |
415 class SparseRepo(repo.__class__): |
413 def getsparsepatterns(self, rev): |
|
414 """Returns the include/exclude patterns specified by the |
|
415 given rev. |
|
416 """ |
|
417 raw = self.vfs.tryread('sparse') |
|
418 if not raw: |
|
419 return set(), set(), [] |
|
420 if rev is None: |
|
421 raise error.Abort(_("cannot parse sparse patterns from " + |
|
422 "working copy")) |
|
423 |
|
424 includes, excludes, profiles = sparse.parseconfig(self.ui, raw) |
|
425 |
|
426 ctx = self[rev] |
|
427 if profiles: |
|
428 visited = set() |
|
429 while profiles: |
|
430 profile = profiles.pop() |
|
431 if profile in visited: |
|
432 continue |
|
433 visited.add(profile) |
|
434 |
|
435 try: |
|
436 raw = sparse.readprofile(self, profile, rev) |
|
437 except error.ManifestLookupError: |
|
438 msg = ( |
|
439 "warning: sparse profile '%s' not found " |
|
440 "in rev %s - ignoring it\n" % (profile, ctx)) |
|
441 if self.ui.configbool( |
|
442 'sparse', 'missingwarning', True): |
|
443 self.ui.warn(msg) |
|
444 else: |
|
445 self.ui.debug(msg) |
|
446 continue |
|
447 pincludes, pexcludes, subprofs = sparse.parseconfig( |
|
448 self.ui, raw) |
|
449 includes.update(pincludes) |
|
450 excludes.update(pexcludes) |
|
451 for subprofile in subprofs: |
|
452 profiles.append(subprofile) |
|
453 |
|
454 profiles = visited |
|
455 |
|
456 if includes: |
|
457 includes.add('.hg*') |
|
458 return includes, excludes, profiles |
|
459 |
|
460 def _sparsechecksum(self, path): |
416 def _sparsechecksum(self, path): |
461 data = self.vfs.read(path) |
417 data = self.vfs.read(path) |
462 return hashlib.sha1(data).hexdigest() |
418 return hashlib.sha1(data).hexdigest() |
463 |
419 |
464 def _sparsesignature(self, includetemp=True): |
420 def _sparsesignature(self, includetemp=True): |
519 return result |
475 return result |
520 |
476 |
521 matchers = [] |
477 matchers = [] |
522 for rev in revs: |
478 for rev in revs: |
523 try: |
479 try: |
524 includes, excludes, profiles = self.getsparsepatterns(rev) |
480 includes, excludes, profiles = sparse.patternsforrev( |
|
481 self, rev) |
525 |
482 |
526 if includes or excludes: |
483 if includes or excludes: |
527 # Explicitly include subdirectories of includes so |
484 # Explicitly include subdirectories of includes so |
528 # status will walk them down to the actual include. |
485 # status will walk them down to the actual include. |
529 subdirs = set() |
486 subdirs = set() |
564 revs = [self.changelog.rev(node) for node in |
521 revs = [self.changelog.rev(node) for node in |
565 self.dirstate.parents() if node != nullid] |
522 self.dirstate.parents() if node != nullid] |
566 |
523 |
567 activeprofiles = set() |
524 activeprofiles = set() |
568 for rev in revs: |
525 for rev in revs: |
569 _, _, profiles = self.getsparsepatterns(rev) |
526 _, _, profiles = sparse.patternsforrev(self, rev) |
570 activeprofiles.update(profiles) |
527 activeprofiles.update(profiles) |
571 |
528 |
572 return activeprofiles |
529 return activeprofiles |
573 |
530 |
574 def writesparseconfig(self, include, exclude, profiles): |
531 def writesparseconfig(self, include, exclude, profiles): |
815 set, (oincludes, oexcludes, oprofiles)) |
772 set, (oincludes, oexcludes, oprofiles)) |
816 |
773 |
817 # all active rules |
774 # all active rules |
818 aincludes, aexcludes, aprofiles = set(), set(), set() |
775 aincludes, aexcludes, aprofiles = set(), set(), set() |
819 for rev in revs: |
776 for rev in revs: |
820 rincludes, rexcludes, rprofiles = repo.getsparsepatterns(rev) |
777 rincludes, rexcludes, rprofiles = sparse.patternsforrev(repo, rev) |
821 aincludes.update(rincludes) |
778 aincludes.update(rincludes) |
822 aexcludes.update(rexcludes) |
779 aexcludes.update(rexcludes) |
823 aprofiles.update(rprofiles) |
780 aprofiles.update(rprofiles) |
824 |
781 |
825 # import rules on top; only take in rules that are not yet |
782 # import rules on top; only take in rules that are not yet |