annotate mercurial/filelog.py @ 3131:4ea58eb3f0c9

filelog: make metadata method private
author Matt Mackall <mpm@selenic.com>
date Sun, 17 Sep 2006 22:38:06 -0500
parents b2138d846b27
children 9a478efc16cc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
1 # filelog.py - file history class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
2 #
2858
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
4 #
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
5 # This software may be used and distributed according to the terms
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
7
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
8 from revlog import *
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
9 from demandload import *
2470
fe1689273f84 use demandload more.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2222
diff changeset
10 demandload(globals(), "bdiff os")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
11
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
12 class filelog(revlog):
2222
c9e264b115e6 Use revlogng and inlined data files by default
mason@suse.com
parents: 2072
diff changeset
13 def __init__(self, opener, path, defversion=REVLOG_DEFAULT_VERSION):
144
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
14 revlog.__init__(self, opener,
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
15 os.path.join("data", self.encodedir(path + ".i")),
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 1595
diff changeset
16 os.path.join("data", self.encodedir(path + ".d")),
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 1595
diff changeset
17 defversion)
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
18
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
19 # This avoids a collision between a file named foo and a dir named
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
20 # foo.i or foo.d
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
21 def encodedir(self, path):
856
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
22 return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
23 .replace(".hg/", ".hg.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
24 .replace(".i/", ".i.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
25 .replace(".d/", ".d.hg/"))
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
26
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
27 def decodedir(self, path):
856
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
28 return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
29 .replace(".d.hg/", ".d/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
30 .replace(".i.hg/", ".i/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
31 .replace(".hg.hg/", ".hg/"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
32
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
33 def read(self, node):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
34 t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
35 if not t.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
36 return t
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2470
diff changeset
37 s = t.index('\1\n', 2)
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
38 return t[s+2:]
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
39
3131
4ea58eb3f0c9 filelog: make metadata method private
Matt Mackall <mpm@selenic.com>
parents: 2948
diff changeset
40 def _readmeta(self, node):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
41 t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
42 if not t.startswith('\1\n'):
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
43 return {}
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2470
diff changeset
44 s = t.index('\1\n', 2)
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
45 mt = t[2:s]
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
46 m = {}
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
47 for l in mt.splitlines():
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
48 k, v = l.split(": ", 1)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
49 m[k] = v
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
50 return m
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
51
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
52 def add(self, text, meta, transaction, link, p1=None, p2=None):
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
53 if meta or text.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
54 mt = ""
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
55 if meta:
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
56 mt = [ "%s: %s\n" % (k, v) for k,v in meta.items() ]
1540
8ca9f5b17257 minor optimization: save some string trash
twaldmann@thinkmo.de
parents: 1117
diff changeset
57 text = "\1\n%s\1\n%s" % ("".join(mt), text)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
58 return self.addrevision(text, transaction, link, p1, p2)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
59
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
60 def renamed(self, node):
1595
dca956c9767d Re-enable the renamed check fastpath
Matt Mackall <mpm@selenic.com>
parents: 1541
diff changeset
61 if self.parents(node)[0] != nullid:
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
62 return False
3131
4ea58eb3f0c9 filelog: make metadata method private
Matt Mackall <mpm@selenic.com>
parents: 2948
diff changeset
63 m = self._readmeta(node)
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
64 if m and m.has_key("copy"):
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
65 return (m["copy"], bin(m["copyrev"]))
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
66 return False
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
67
2918
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
68 def size(self, rev):
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
69 """return the size of a given revision"""
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
70
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
71 # for revisions with renames, we have to go the slow way
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
72 node = self.node(rev)
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
73 if self.renamed(node):
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
74 return len(self.read(node))
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
75
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
76 return revlog.size(self, rev)
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2915
diff changeset
77
2900
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
78 def cmp(self, node, text):
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
79 """compare text with a given file revision"""
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
80
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
81 # for renames, we have to go the slow way
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
82 if self.renamed(node):
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
83 t2 = self.read(node)
2915
21631c2c09a5 filelog.cmp: return 0 for equality
Matt Mackall <mpm@selenic.com>
parents: 2910
diff changeset
84 return t2 != text
2900
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
85
2910
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2900
diff changeset
86 return revlog.cmp(self, node, text)
2900
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
87
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
88 def annotate(self, node):
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
89
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
90 def decorate(text, rev):
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
91 return ([rev] * len(text.splitlines()), text)
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
92
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
93 def pair(parent, child):
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
94 for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
471
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
95 child[0][b1:b2] = parent[0][a1:a2]
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
96 return child
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
97
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
98 # find all ancestors
2948
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
99 needed = {(self, node):1}
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
100 files = [self]
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
101 visit = [(self, node)]
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
102 while visit:
2948
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
103 f, n = visit.pop(0)
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
104 rn = f.renamed(n)
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
105 if rn:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
106 f, n = rn
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
107 f = filelog(self.opener, f, self.defversion)
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
108 files.insert(0, f)
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
109 if (f, n) not in needed:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
110 needed[(f, n)] = 1
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
111 else:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
112 needed[(f, n)] += 1
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
113 for p in f.parents(n):
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
114 if p == nullid:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
115 continue
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
116 if (f, p) not in needed:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
117 needed[(f, p)] = 1
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
118 visit.append((f, p))
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
119 else:
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
120 # count how many times we'll use this
2948
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
121 needed[(f, p)] += 1
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
122
2948
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
123 # sort by revision (per file) which is a topological order
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
124 visit = []
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
125 for f in files:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
126 fn = [(f.rev(n[1]), f, n[1]) for n in needed.keys() if n[0] == f]
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
127 fn.sort()
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
128 visit.extend(fn)
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
129 hist = {}
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
130
2948
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
131 for i in range(len(visit)):
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
132 r, f, n = visit[i]
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
133 curr = decorate(f.read(n), f.linkrev(n))
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
134 if r == -1:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
135 continue
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
136 parents = f.parents(n)
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
137 # follow parents across renames
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
138 if r < 1 and i > 0:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
139 j = i
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
140 while j > 0 and visit[j][1] == f:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
141 j -= 1
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
142 parents = (visit[j][2],)
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
143 f = visit[j][1]
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
144 else:
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
145 parents = f.parents(n)
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
146 for p in parents:
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
147 if p != nullid:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
148 curr = pair(hist[p], curr)
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
149 # trim the history of unneeded revs
2948
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
150 needed[(f, p)] -= 1
b2138d846b27 Teach annotate to follow copies.
Brendan Cully <brendan@kublai.com>
parents: 2918
diff changeset
151 if not needed[(f, p)]:
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
152 del hist[p]
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
153 hist[n] = curr
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
154
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
155 return zip(hist[n][0], hist[n][1].splitlines(1))