@@ -1,4 +1,4 @@
-#testcases filelog compatibility
+#testcases filelog compatibility changeset
$ cat >> $HGRCPATH << EOF
> [extensions]
@@ -14,6 +14,14 @@
> EOF
#endif
+#if changeset
+ $ cat >> $HGRCPATH << EOF
+ > [experimental]
+ > copies.read-from = changeset-only
+ > copies.write-to = changeset-only
+ > EOF
+#endif
+
$ REPONUM=0
$ newrepo() {
> cd $TESTTMP
@@ -376,11 +384,13 @@
o 0 add x on branch 1
x
$ hg debugp1copies -r 2
+ x -> z (changeset !)
$ hg debugp2copies -r 2
- x -> z
+ x -> z (no-changeset !)
$ hg debugpathcopies 1 2
+ x -> z (changeset !)
$ hg debugpathcopies 0 2
- x -> z
+ x -> z (no-changeset !)
Copy x->y on one side of merge and copy x->z on the other side. Pathcopies from one parent
of the merge to the merge should include the copy from the other side.
@@ -539,6 +549,9 @@
Grafting revision 4 on top of revision 2, showing that it respect the rename:
+TODO: Make this work with copy info in changesets (probably by writing a
+changeset-centric version of copies.mergecopies())
+#if no-changeset
$ hg up 2 -q
$ hg graft -r 4 --base 3 --hidden
grafting 4:af28412ec03c "added d, modified b" (tip)
@@ -554,6 +567,8 @@
b
+baba
+#endif
+
Test to make sure that fullcopytracing algorithm don't fail when both the merging csets are dirty
(a dirty cset is one who is not the descendant of merge base)
-------------------------------------------------------------------------------------------------
@@ -2,9 +2,11 @@
$ cat >> $HGRCPATH << EOF
> [experimental]
> copies.write-to=changeset-only
+ > copies.read-from=changeset-only
> [alias]
> changesetcopies = log -r . -T 'files: {files}
> {extras % "{ifcontains("copies", key, "{key}: {value}\n")}"}'
+ > showcopies = log -r . -T '{file_copies % "{source} -> {name}\n"}'
> EOF
Check that copies are recorded correctly
@@ -21,14 +23,25 @@
$ hg changesetcopies
files: b c d
p1copies: b\0a\nc\0a\nd\0a
+ $ 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
$ hg mv b b2
$ hg ci -m 'rename b to b2'
$ hg changesetcopies
files: b b2
p1copies: b2\0b
+ $ 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.
@@ -44,6 +57,8 @@
$ hg changesetcopies
files: c
p1copies: c\0b2
+ $ hg showcopies
+ b2 -> c
$ hg debugindex c
rev linkrev nodeid p1 p2
0 1 b789fdd96dc2 000000000000 000000000000
@@ -71,6 +86,10 @@
files: g h i
p1copies: g\0a\ni\0f
p2copies: h\0d
+ $ hg showcopies
+ a -> g
+ d -> h
+ f -> i
Test writing to both changeset and filelog
@@ -85,6 +104,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
@@ -98,5 +123,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 ..
@@ -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)"""
@@ -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()
@@ -87,6 +87,18 @@
]
return _string_escape("\n".join(items))
+def decodecopies(data):
+ try:
+ copies = {}
+ for l in _string_unescape(data).split('\n'):
+ k, v = l.split('\0')
+ copies[k] = 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:])