D6186: changelog: parse copy metadata if available in extras
martinvonz (Martin von Zweigbergk)
phabricator at mercurial-scm.org
Tue Apr 2 19:31:30 UTC 2019
martinvonz created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
This lets read back the copy metadata we just started writing. There
are still many places left to teach about getting the copy information
from the changeset, but we have enough ({file_copies}, specifically)
that we can add it now and have some test coverage of it.
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D6186
AFFECTED FILES
mercurial/changelog.py
mercurial/context.py
mercurial/copies.py
tests/test-copies-in-changeset.t
CHANGE DETAILS
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 ..
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/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/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:])
To: martinvonz, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list