diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -107,6 +107,20 @@ indices.append('%d' % i) return '\0'.join(indices) +def decodefileindices(files, data): + try: + subset = [] + for strindex in data.split('\0'): + i = int(strindex) + if i < 0 or i >= len(files): + return None + subset.append(files[i]) + return subset + except (ValueError, IndexError): + # Perhaps someone had chosen the same key name (e.g. "added") and + # used different syntax for the value. + return None + def stripdesc(desc): """strip trailing whitespace and leading and trailing empty lines""" return '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n') @@ -202,6 +216,8 @@ user = attr.ib(default='') date = attr.ib(default=(0, 0)) files = attr.ib(default=attr.Factory(list)) + filesadded = attr.ib(default=None) + filesremoved = attr.ib(default=None) p1copies = attr.ib(default=None) p2copies = attr.ib(default=None) description = attr.ib(default='') @@ -308,6 +324,16 @@ return self._text[off[2] + 1:off[3]].split('\n') @property + def filesadded(self): + rawindices = self.extra.get('filesadded') + return rawindices and decodefileindices(self.files, rawindices) + + @property + def filesremoved(self): + rawindices = self.extra.get('filesremoved') + return rawindices and decodefileindices(self.files, rawindices) + + @property def p1copies(self): rawcopies = self.extra.get('p1copies') return rawcopies and decodecopies(rawcopies) diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -469,12 +469,24 @@ modified.difference_update(self.filesremoved()) return sorted(modified) def filesadded(self): + source = self._repo.ui.config('experimental', 'copies.read-from') + if (source == 'changeset-only' or + (source == 'compatibility' and + self._changeset.filesadded is not None)): + return self._changeset.filesadded or [] + added = [] for f in self.files(): if not any(f in p for p in self.parents()): added.append(f) return added def filesremoved(self): + source = self._repo.ui.config('experimental', 'copies.read-from') + if (source == 'changeset-only' or + (source == 'compatibility' and + self._changeset.filesremoved is not None)): + return self._changeset.filesremoved or [] + removed = [] for f in self.files(): if f not in self: