Mercurial > hg
comparison mercurial/manifest.py @ 31255:959ebff3505a
manifest: add match argument to diff and filesnotin
As part of removing manifest.matches (since it is O(manifest)), let's start by
adding match arguments to diff and filesnotin. As we'll see in later patches,
these are the only flows that actually use matchers, so by moving the matching
into the actual functions, other manifest implementations can make more efficient
algorithsm.
For instance, this will allow treemanifest diff's to only iterate over the files
that are different AND meet the match criteria.
No consumers are changed in this patches, but the code is fairly easy to verify
visually. Future patches will convert consumers to use it.
One test was affected because it did not use the kwargs version of the clean
parameter.
author | Durham Goode <durham@fb.com> |
---|---|
date | Tue, 07 Mar 2017 09:56:11 -0800 |
parents | 5cab44fd1257 |
children | c134a33b1d73 |
comparison
equal
deleted
inserted
replaced
31254:2140e12d3258 | 31255:959ebff3505a |
---|---|
443 return self._lm.iterkeys() | 443 return self._lm.iterkeys() |
444 | 444 |
445 def keys(self): | 445 def keys(self): |
446 return list(self.iterkeys()) | 446 return list(self.iterkeys()) |
447 | 447 |
448 def filesnotin(self, m2): | 448 def filesnotin(self, m2, match=None): |
449 '''Set of files in this manifest that are not in the other''' | 449 '''Set of files in this manifest that are not in the other''' |
450 if match: | |
451 m1 = self.matches(match) | |
452 m2 = m2.matches(match) | |
453 return m1.filesnotin(m2) | |
450 diff = self.diff(m2) | 454 diff = self.diff(m2) |
451 files = set(filepath | 455 files = set(filepath |
452 for filepath, hashflags in diff.iteritems() | 456 for filepath, hashflags in diff.iteritems() |
453 if hashflags[1][0] is None) | 457 if hashflags[1][0] is None) |
454 return files | 458 return files |
521 | 525 |
522 m = manifestdict() | 526 m = manifestdict() |
523 m._lm = self._lm.filtercopy(match) | 527 m._lm = self._lm.filtercopy(match) |
524 return m | 528 return m |
525 | 529 |
526 def diff(self, m2, clean=False): | 530 def diff(self, m2, match=None, clean=False): |
527 '''Finds changes between the current manifest and m2. | 531 '''Finds changes between the current manifest and m2. |
528 | 532 |
529 Args: | 533 Args: |
530 m2: the manifest to which this manifest should be compared. | 534 m2: the manifest to which this manifest should be compared. |
531 clean: if true, include files unchanged between these manifests | 535 clean: if true, include files unchanged between these manifests |
536 nodeid in the current/other manifest and fl1/fl2 is the flag | 540 nodeid in the current/other manifest and fl1/fl2 is the flag |
537 in the current/other manifest. Where the file does not exist, | 541 in the current/other manifest. Where the file does not exist, |
538 the nodeid will be None and the flags will be the empty | 542 the nodeid will be None and the flags will be the empty |
539 string. | 543 string. |
540 ''' | 544 ''' |
545 if match: | |
546 m1 = self.matches(match) | |
547 m2 = m2.matches(match) | |
548 return m1.diff(m2, clean=clean) | |
541 return self._lm.diff(m2._lm, clean) | 549 return self._lm.diff(m2._lm, clean) |
542 | 550 |
543 def setflag(self, key, flag): | 551 def setflag(self, key, flag): |
544 self._lm[key] = self[key], flag | 552 self._lm[key] = self[key], flag |
545 | 553 |
904 copy._copyfunc = _copyfunc | 912 copy._copyfunc = _copyfunc |
905 else: | 913 else: |
906 copy._copyfunc = self._copyfunc | 914 copy._copyfunc = self._copyfunc |
907 return copy | 915 return copy |
908 | 916 |
909 def filesnotin(self, m2): | 917 def filesnotin(self, m2, match=None): |
910 '''Set of files in this manifest that are not in the other''' | 918 '''Set of files in this manifest that are not in the other''' |
919 if match: | |
920 m1 = self.matches(match) | |
921 m2 = m2.matches(match) | |
922 return m1.filesnotin(m2) | |
923 | |
911 files = set() | 924 files = set() |
912 def _filesnotin(t1, t2): | 925 def _filesnotin(t1, t2): |
913 if t1._node == t2._node and not t1._dirty and not t2._dirty: | 926 if t1._node == t2._node and not t1._dirty and not t2._dirty: |
914 return | 927 return |
915 t1._load() | 928 t1._load() |
1023 | 1036 |
1024 if not ret._isempty(): | 1037 if not ret._isempty(): |
1025 ret._dirty = True | 1038 ret._dirty = True |
1026 return ret | 1039 return ret |
1027 | 1040 |
1028 def diff(self, m2, clean=False): | 1041 def diff(self, m2, match=None, clean=False): |
1029 '''Finds changes between the current manifest and m2. | 1042 '''Finds changes between the current manifest and m2. |
1030 | 1043 |
1031 Args: | 1044 Args: |
1032 m2: the manifest to which this manifest should be compared. | 1045 m2: the manifest to which this manifest should be compared. |
1033 clean: if true, include files unchanged between these manifests | 1046 clean: if true, include files unchanged between these manifests |
1038 nodeid in the current/other manifest and fl1/fl2 is the flag | 1051 nodeid in the current/other manifest and fl1/fl2 is the flag |
1039 in the current/other manifest. Where the file does not exist, | 1052 in the current/other manifest. Where the file does not exist, |
1040 the nodeid will be None and the flags will be the empty | 1053 the nodeid will be None and the flags will be the empty |
1041 string. | 1054 string. |
1042 ''' | 1055 ''' |
1056 if match: | |
1057 m1 = self.matches(match) | |
1058 m2 = m2.matches(match) | |
1059 return m1.diff(m2, clean=clean) | |
1043 result = {} | 1060 result = {} |
1044 emptytree = treemanifest() | 1061 emptytree = treemanifest() |
1045 def _diff(t1, t2): | 1062 def _diff(t1, t2): |
1046 if t1._node == t2._node and not t1._dirty and not t2._dirty: | 1063 if t1._node == t2._node and not t1._dirty and not t2._dirty: |
1047 return | 1064 return |