##// END OF EJS Templates
copies: add config option for writing copy metadata to file and/or changset...
Martin von Zweigbergk -
r42312:36d70c14 default draft
parent child Browse files
Show More
@@ -0,0 +1,105 b''
1
2 $ cat >> $HGRCPATH << EOF
3 > [experimental]
4 > copies.write-to=changeset-only
5 > [alias]
6 > changesetcopies = log -r . -T 'files: {files}
7 > {extras % "{ifcontains("copies", key, "{key}: {value}\n")}"}'
8 > EOF
9
10 Check that copies are recorded correctly
11
12 $ hg init repo
13 $ cd repo
14 $ echo a > a
15 $ hg add a
16 $ hg ci -m initial
17 $ hg cp a b
18 $ hg cp a c
19 $ hg cp a d
20 $ hg ci -m 'copy a to b, c, and d'
21 $ hg changesetcopies
22 files: b c d
23 p1copies: b\x00a (esc)
24 c\x00a (esc)
25 d\x00a (esc)
26
27 Check that renames are recorded correctly
28
29 $ hg mv b b2
30 $ hg ci -m 'rename b to b2'
31 $ hg changesetcopies
32 files: b b2
33 p1copies: b2\x00b (esc)
34
35 Rename onto existing file. This should get recorded in the changeset files list and in the extras,
36 even though there is no filelog entry.
37
38 $ hg cp b2 c --force
39 $ hg st --copies
40 M c
41 b2
42 $ hg debugindex c
43 rev linkrev nodeid p1 p2
44 0 1 b789fdd96dc2 000000000000 000000000000
45 $ hg ci -m 'move b onto d'
46 $ hg changesetcopies
47 files: c
48 p1copies: c\x00b2 (esc)
49 $ hg debugindex c
50 rev linkrev nodeid p1 p2
51 0 1 b789fdd96dc2 000000000000 000000000000
52
53 Create a merge commit with copying done during merge.
54
55 $ hg co 0
56 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
57 $ hg cp a e
58 $ hg cp a f
59 $ hg ci -m 'copy a to e and f'
60 created new head
61 $ hg merge 3
62 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 (branch merge, don't forget to commit)
64 File 'a' exists on both sides, so 'g' could be recorded as being from p1 or p2, but we currently
65 always record it as being from p1
66 $ hg cp a g
67 File 'd' exists only in p2, so 'h' should be from p2
68 $ hg cp d h
69 File 'f' exists only in p1, so 'i' should be from p1
70 $ hg cp f i
71 $ hg ci -m 'merge'
72 $ hg changesetcopies
73 files: g h i
74 p1copies: g\x00a (esc)
75 i\x00f (esc)
76 p2copies: h\x00d (esc)
77
78 Test writing to both changeset and filelog
79
80 $ hg cp a j
81 $ hg ci -m 'copy a to j' --config experimental.copies.write-to=compatibility
82 $ hg changesetcopies
83 files: j
84 p1copies: j\x00a (esc)
85 $ hg debugdata j 0
86 \x01 (esc)
87 copy: a
88 copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
89 \x01 (esc)
90 a
91
92 Test writing only to filelog
93
94 $ hg cp a k
95 $ hg ci -m 'copy a to k' --config experimental.copies.write-to=filelog-only
96 $ hg changesetcopies
97 files: k
98 $ hg debugdata k 0
99 \x01 (esc)
100 copy: a
101 copyrev: b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
102 \x01 (esc)
103 a
104
105 $ cd ..
@@ -80,6 +80,13 b' def encodeextra(d):'
80 80 ]
81 81 return "\0".join(items)
82 82
83 def encodecopies(copies):
84 items = [
85 '%s\0%s' % (k, copies[k])
86 for k in sorted(copies)
87 ]
88 return "\n".join(items)
89
83 90 def stripdesc(desc):
84 91 """strip trailing whitespace and leading and trailing empty lines"""
85 92 return '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
@@ -533,7 +540,7 b' class changelog(revlog.revlog):'
533 540 return l[3:]
534 541
535 542 def add(self, manifest, files, desc, transaction, p1, p2,
536 user, date=None, extra=None):
543 user, date=None, extra=None, p1copies=None, p2copies=None):
537 544 # Convert to UTF-8 encoded bytestrings as the very first
538 545 # thing: calling any method on a localstr object will turn it
539 546 # into a str object and the cached UTF-8 string is thus lost.
@@ -562,6 +569,13 b' class changelog(revlog.revlog):'
562 569 elif branch in (".", "null", "tip"):
563 570 raise error.StorageError(_('the name \'%s\' is reserved')
564 571 % branch)
572 if (p1copies or p2copies) and extra is None:
573 extra = {}
574 if p1copies:
575 extra['p1copies'] = encodecopies(p1copies)
576 if p2copies:
577 extra['p2copies'] = encodecopies(p2copies)
578
565 579 if extra:
566 580 extra = encodeextra(extra)
567 581 parseddate = "%s %s" % (parseddate, extra)
@@ -488,6 +488,9 b" coreconfigitem('experimental', 'copytrac"
488 488 coreconfigitem('experimental', 'copies.read-from',
489 489 default="filelog-only",
490 490 )
491 coreconfigitem('experimental', 'copies.write-to',
492 default='filelog-only',
493 )
491 494 coreconfigitem('experimental', 'crecordtest',
492 495 default=None,
493 496 )
@@ -2324,7 +2324,8 b' class localrepository(object):'
2324 2324 """Returns the wlock if it's held, or None if it's not."""
2325 2325 return self._currentlock(self._wlockref)
2326 2326
2327 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
2327 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist,
2328 includecopymeta):
2328 2329 """
2329 2330 commit an individual file as part of a larger transaction
2330 2331 """
@@ -2383,8 +2384,9 b' class localrepository(object):'
2383 2384
2384 2385 if cnode:
2385 2386 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(cnode)))
2386 meta["copy"] = cfname
2387 meta["copyrev"] = hex(cnode)
2387 if includecopymeta:
2388 meta["copy"] = cfname
2389 meta["copyrev"] = hex(cnode)
2388 2390 fparent1, fparent2 = nullid, newfparent
2389 2391 else:
2390 2392 self.ui.warn(_("warning: can't find ancestor for '%s' "
@@ -2552,6 +2554,12 b' class localrepository(object):'
2552 2554 p1, p2 = ctx.p1(), ctx.p2()
2553 2555 user = ctx.user()
2554 2556
2557 writecopiesto = self.ui.config('experimental', 'copies.write-to')
2558 writefilecopymeta = writecopiesto != 'changeset-only'
2559 p1copies, p2copies = None, None
2560 if writecopiesto in ('changeset-only', 'compatibility'):
2561 p1copies = ctx.p1copies()
2562 p2copies = ctx.p2copies()
2555 2563 with self.lock(), self.transaction("commit") as tr:
2556 2564 trp = weakref.proxy(tr)
2557 2565
@@ -2585,7 +2593,8 b' class localrepository(object):'
2585 2593 else:
2586 2594 added.append(f)
2587 2595 m[f] = self._filecommit(fctx, m1, m2, linkrev,
2588 trp, changed)
2596 trp, changed,
2597 writefilecopymeta)
2589 2598 m.setflag(f, fctx.flags())
2590 2599 except OSError:
2591 2600 self.ui.warn(_("trouble committing %s!\n") %
@@ -2639,7 +2648,8 b' class localrepository(object):'
2639 2648 self.changelog.delayupdate(tr)
2640 2649 n = self.changelog.add(mn, files, ctx.description(),
2641 2650 trp, p1.node(), p2.node(),
2642 user, ctx.date(), ctx.extra().copy())
2651 user, ctx.date(), ctx.extra().copy(),
2652 p1copies, p2copies)
2643 2653 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
2644 2654 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
2645 2655 parent2=xp2)
@@ -438,7 +438,7 b' and its ancestor by overriding "repo._fi'
438 438 > def reposetup(ui, repo):
439 439 > class legacyrepo(repo.__class__):
440 440 > def _filecommit(self, fctx, manifest1, manifest2,
441 > linkrev, tr, changelist):
441 > linkrev, tr, changelist, includecopymeta):
442 442 > fname = fctx.path()
443 443 > text = fctx.data()
444 444 > flog = self.file(fname)
@@ -443,7 +443,7 b' and its ancestor by overriding "repo._fi'
443 443 > def reposetup(ui, repo):
444 444 > class legacyrepo(repo.__class__):
445 445 > def _filecommit(self, fctx, manifest1, manifest2,
446 > linkrev, tr, changelist):
446 > linkrev, tr, changelist, includecopymeta):
447 447 > fname = fctx.path()
448 448 > text = fctx.data()
449 449 > flog = self.file(fname)
General Comments 0
You need to be logged in to leave comments. Login now