diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -87,6 +87,18 @@ ] return "\n".join(items) +def decodecopies(data): + try: + copies = {} + for l in data.split('\n'): + k, v = l.split('\0') + copies[_string_unescape(k)] = _string_unescape(v) + return copies + except ValueError: + # Perhaps someone had chosen the same key name (e.g. "p1copies") 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') @@ -286,6 +298,16 @@ return self._text[off[2] + 1:off[3]].split('\n') @property + def p1copies(self): + rawcopies = self.extra.get('p1copies') + return rawcopies and decodecopies(rawcopies) + + @property + def p2copies(self): + rawcopies = self.extra.get('p2copies') + return rawcopies and decodecopies(rawcopies) + + @property def description(self): return encoding.tolocal(self._text[self._offsets[3] + 2:]) diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -441,6 +441,21 @@ return self._changeset.files @propertycache def _copies(self): + source = self._repo.ui.config('experimental', 'copies.read-from') + p1copies = self._changeset.p1copies + p2copies = self._changeset.p2copies + # If config says to get copy metadata only from changeset, then return + # that, defaulting to {} if there was no copy metadata. + # In compatibility mode, we return copy data from the changeset if + # it was recorded there, and otherwise we fall back to getting it from + # the filelogs (below). + if (source == 'changeset-only' or + (source == 'compatibility' and p1copies is not None)): + return p1copies or {}, p2copies or {} + + # Otherwise (config said to read only from filelog, or we are in + # compatiblity mode and there is not data in the changeset), we get + # the copy metadata from the filelogs. p1copies = {} p2copies = {} p1 = self.p1() diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -162,8 +162,8 @@ def usechangesetcentricalgo(repo): """Checks if we should use changeset-centric copy algorithms""" - return (repo.ui.config('experimental', 'copies.read-from') == - 'compatibility') + return (repo.ui.config('experimental', 'copies.read-from') in + ('changeset-only', 'compatibility')) def _committedforwardcopies(a, b, match): """Like _forwardcopies(), but b.rev() cannot be None (working copy)""" diff --git a/tests/test-copies-in-changeset.t b/tests/test-copies-in-changeset.t --- a/tests/test-copies-in-changeset.t +++ b/tests/test-copies-in-changeset.t @@ -2,11 +2,13 @@ $ cat >> $HGRCPATH << EOF > [experimental] > copies.write-to=changeset-only + > copies.read-from=changeset-only > [alias] > changesetcopies = log -r . -T "files: {files} > p1copies: {get(extras,'p1copies')} > p2copies: {get(extras,'p2copies')} > " + > showcopies = log -r . -T '{file_copies % "{source} -> {name}\n"}' > EOF Check that copies are recorded correctly @@ -26,6 +28,15 @@ c\x00a (esc) d\x00a (esc) p2copies: + $ hg showcopies + a -> b + a -> c + a -> d + $ hg showcopies --config experimental.copies.read-from=compatibility + a -> b + a -> c + a -> d + $ hg showcopies --config experimental.copies.read-from=filelog-only Check that renames are recorded correctly @@ -35,6 +46,8 @@ files: b b2 p1copies: b2\x00b (esc) p2copies: + $ hg showcopies + b -> b2 Rename onto existing file. This should get recorded in the changeset files list and in the extras, even though there is no filelog entry. @@ -51,6 +64,8 @@ files: c p1copies: c\x00b2 (esc) p2copies: + $ hg showcopies + b2 -> c $ hg debugindex c rev linkrev nodeid p1 p2 0 1 b789fdd96dc2 000000000000 000000000000 @@ -79,6 +94,10 @@ p1copies: g\x00a (esc) i\x00f (esc) p2copies: h\x00d (esc) + $ hg showcopies + a -> g + d -> h + f -> i Test writing to both changeset and filelog @@ -94,6 +113,12 @@ copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 \x01 (esc) a + $ hg showcopies + a -> j + $ hg showcopies --config experimental.copies.read-from=compatibility + a -> j + $ hg showcopies --config experimental.copies.read-from=filelog-only + a -> j Test writing only to filelog @@ -109,5 +134,10 @@ copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 \x01 (esc) a + $ hg showcopies + $ hg showcopies --config experimental.copies.read-from=compatibility + a -> k + $ hg showcopies --config experimental.copies.read-from=filelog-only + a -> k $ cd ..