405 return orig(self, *args) |
406 return orig(self, *args) |
406 extensions.wrapfunction(dirstate.dirstate, func, _wrapper) |
407 extensions.wrapfunction(dirstate.dirstate, func, _wrapper) |
407 |
408 |
408 def _wraprepo(ui, repo): |
409 def _wraprepo(ui, repo): |
409 class SparseRepo(repo.__class__): |
410 class SparseRepo(repo.__class__): |
410 def readsparseconfig(self, raw): |
|
411 """Takes a string sparse config and returns the includes, |
|
412 excludes, and profiles it specified. |
|
413 """ |
|
414 includes = set() |
|
415 excludes = set() |
|
416 current = includes |
|
417 profiles = [] |
|
418 for line in raw.split('\n'): |
|
419 line = line.strip() |
|
420 if not line or line.startswith('#'): |
|
421 # empty or comment line, skip |
|
422 continue |
|
423 elif line.startswith('%include '): |
|
424 line = line[9:].strip() |
|
425 if line: |
|
426 profiles.append(line) |
|
427 elif line == '[include]': |
|
428 if current != includes: |
|
429 raise error.Abort(_('.hg/sparse cannot have includes ' + |
|
430 'after excludes')) |
|
431 continue |
|
432 elif line == '[exclude]': |
|
433 current = excludes |
|
434 elif line: |
|
435 if line.strip().startswith('/'): |
|
436 self.ui.warn(_('warning: sparse profile cannot use' + |
|
437 ' paths starting with /, ignoring %s\n') |
|
438 % line) |
|
439 continue |
|
440 current.add(line) |
|
441 |
|
442 return includes, excludes, profiles |
|
443 |
|
444 def getsparsepatterns(self, rev): |
411 def getsparsepatterns(self, rev): |
445 """Returns the include/exclude patterns specified by the |
412 """Returns the include/exclude patterns specified by the |
446 given rev. |
413 given rev. |
447 """ |
414 """ |
448 raw = self.vfs.tryread('sparse') |
415 raw = self.vfs.tryread('sparse') |
450 return set(), set(), [] |
417 return set(), set(), [] |
451 if rev is None: |
418 if rev is None: |
452 raise error.Abort(_("cannot parse sparse patterns from " + |
419 raise error.Abort(_("cannot parse sparse patterns from " + |
453 "working copy")) |
420 "working copy")) |
454 |
421 |
455 includes, excludes, profiles = self.readsparseconfig(raw) |
422 includes, excludes, profiles = sparse.parseconfig(self.ui, raw) |
456 |
423 |
457 ctx = self[rev] |
424 ctx = self[rev] |
458 if profiles: |
425 if profiles: |
459 visited = set() |
426 visited = set() |
460 while profiles: |
427 while profiles: |
473 'sparse', 'missingwarning', True): |
440 'sparse', 'missingwarning', True): |
474 self.ui.warn(msg) |
441 self.ui.warn(msg) |
475 else: |
442 else: |
476 self.ui.debug(msg) |
443 self.ui.debug(msg) |
477 continue |
444 continue |
478 pincludes, pexcludes, subprofs = \ |
445 pincludes, pexcludes, subprofs = sparse.parseconfig( |
479 self.readsparseconfig(raw) |
446 self.ui, raw) |
480 includes.update(pincludes) |
447 includes.update(pincludes) |
481 excludes.update(pexcludes) |
448 excludes.update(pexcludes) |
482 for subprofile in subprofs: |
449 for subprofile in subprofs: |
483 profiles.append(subprofile) |
450 profiles.append(subprofile) |
484 |
451 |
785 oldsparsematch = repo.sparsematch() |
752 oldsparsematch = repo.sparsematch() |
786 |
753 |
787 raw = repo.vfs.tryread('sparse') |
754 raw = repo.vfs.tryread('sparse') |
788 if raw: |
755 if raw: |
789 oldinclude, oldexclude, oldprofiles = map( |
756 oldinclude, oldexclude, oldprofiles = map( |
790 set, repo.readsparseconfig(raw)) |
757 set, sparse.parseconfig(ui, raw)) |
791 else: |
758 else: |
792 oldinclude = set() |
759 oldinclude = set() |
793 oldexclude = set() |
760 oldexclude = set() |
794 oldprofiles = set() |
761 oldprofiles = set() |
795 |
762 |
844 revs = [repo.changelog.rev(node) for node in |
811 revs = [repo.changelog.rev(node) for node in |
845 repo.dirstate.parents() if node != nullid] |
812 repo.dirstate.parents() if node != nullid] |
846 |
813 |
847 # read current configuration |
814 # read current configuration |
848 raw = repo.vfs.tryread('sparse') |
815 raw = repo.vfs.tryread('sparse') |
849 oincludes, oexcludes, oprofiles = repo.readsparseconfig(raw) |
816 oincludes, oexcludes, oprofiles = sparse.parseconfig(ui, raw) |
850 includes, excludes, profiles = map( |
817 includes, excludes, profiles = map( |
851 set, (oincludes, oexcludes, oprofiles)) |
818 set, (oincludes, oexcludes, oprofiles)) |
852 |
819 |
853 # all active rules |
820 # all active rules |
854 aincludes, aexcludes, aprofiles = set(), set(), set() |
821 aincludes, aexcludes, aprofiles = set(), set(), set() |
861 # import rules on top; only take in rules that are not yet |
828 # import rules on top; only take in rules that are not yet |
862 # part of the active rules. |
829 # part of the active rules. |
863 changed = False |
830 changed = False |
864 for file in files: |
831 for file in files: |
865 with util.posixfile(util.expandpath(file)) as importfile: |
832 with util.posixfile(util.expandpath(file)) as importfile: |
866 iincludes, iexcludes, iprofiles = repo.readsparseconfig( |
833 iincludes, iexcludes, iprofiles = sparse.parseconfig( |
867 importfile.read()) |
834 ui, importfile.read()) |
868 oldsize = len(includes) + len(excludes) + len(profiles) |
835 oldsize = len(includes) + len(excludes) + len(profiles) |
869 includes.update(iincludes - aincludes) |
836 includes.update(iincludes - aincludes) |
870 excludes.update(iexcludes - aexcludes) |
837 excludes.update(iexcludes - aexcludes) |
871 profiles.update(set(iprofiles) - aprofiles) |
838 profiles.update(set(iprofiles) - aprofiles) |
872 if len(includes) + len(excludes) + len(profiles) > oldsize: |
839 if len(includes) + len(excludes) + len(profiles) > oldsize: |
895 *fcounts) |
862 *fcounts) |
896 |
863 |
897 def _clear(ui, repo, files, force=False): |
864 def _clear(ui, repo, files, force=False): |
898 with repo.wlock(): |
865 with repo.wlock(): |
899 raw = repo.vfs.tryread('sparse') |
866 raw = repo.vfs.tryread('sparse') |
900 includes, excludes, profiles = repo.readsparseconfig(raw) |
867 includes, excludes, profiles = sparse.parseconfig(ui, raw) |
901 |
868 |
902 if includes or excludes: |
869 if includes or excludes: |
903 oldstatus = repo.status() |
870 oldstatus = repo.status() |
904 oldsparsematch = repo.sparsematch() |
871 oldsparsematch = repo.sparsematch() |
905 repo.writesparseconfig(set(), set(), profiles) |
872 repo.writesparseconfig(set(), set(), profiles) |