annotate mercurial/filelog.py @ 2072:74d3f5336b66

Implement revlogng. revlogng results in smaller indexes, can address larger data files, and supports flags and version numbers. By default the original revlog format is used. To use the new format, use the following .hgrc field: [revlog] # format choices are 0 (classic revlog format) and 1 revlogng format=1
author mason@suse.com
date Tue, 04 Apr 2006 16:38:43 -0400
parents dca956c9767d
children c9e264b115e6
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 #
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
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
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
8 import os
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
9 from revlog import *
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
10 from demandload import *
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
11 demandload(globals(), "bdiff")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
12
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
13 class filelog(revlog):
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 1595
diff changeset
14 def __init__(self, opener, path, defversion=0):
144
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
15 revlog.__init__(self, opener,
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
16 os.path.join("data", self.encodedir(path + ".i")),
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 1595
diff changeset
17 os.path.join("data", self.encodedir(path + ".d")),
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 1595
diff changeset
18 defversion)
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
19
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
20 # 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
21 # foo.i or foo.d
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
22 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
23 return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
24 .replace(".hg/", ".hg.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
25 .replace(".i/", ".i.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
26 .replace(".d/", ".d.hg/"))
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
27
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
28 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
29 return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
30 .replace(".d.hg/", ".d/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
31 .replace(".i.hg/", ".i/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
32 .replace(".hg.hg/", ".hg/"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
33
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
34 def read(self, node):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
35 t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
36 if not t.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
37 return t
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
38 s = t.find('\1\n', 2)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
39 return t[s+2:]
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
40
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
41 def readmeta(self, node):
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
42 t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
43 if not t.startswith('\1\n'):
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
44 return {}
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
45 s = t.find('\1\n', 2)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
46 mt = t[2:s]
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
47 m = {}
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
48 for l in mt.splitlines():
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
49 k, v = l.split(": ", 1)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
50 m[k] = v
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
51 return m
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
52
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
53 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
54 if meta or text.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
55 mt = ""
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
56 if meta:
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
57 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
58 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
59 return self.addrevision(text, transaction, link, p1, p2)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
60
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
61 def renamed(self, node):
1595
dca956c9767d Re-enable the renamed check fastpath
Matt Mackall <mpm@selenic.com>
parents: 1541
diff changeset
62 if self.parents(node)[0] != nullid:
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
63 return False
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
64 m = self.readmeta(node)
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
65 if m and m.has_key("copy"):
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
66 return (m["copy"], bin(m["copyrev"]))
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
67 return False
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
68
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
69 def annotate(self, node):
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
70
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
71 def decorate(text, rev):
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
72 return ([rev] * len(text.splitlines()), text)
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
73
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
74 def pair(parent, child):
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
75 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
76 child[0][b1:b2] = parent[0][a1:a2]
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
77 return child
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
78
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
79 # find all ancestors
216
201115f2859b hg annotate: actually annotate the given version
mpm@selenic.com
parents: 210
diff changeset
80 needed = {node:1}
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
81 visit = [node]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
82 while visit:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
83 n = visit.pop(0)
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
84 for p in self.parents(n):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
85 if p not in needed:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
86 needed[p] = 1
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
87 visit.append(p)
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
88 else:
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
89 # count how many times we'll use this
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
90 needed[p] += 1
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
91
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
92 # sort by revision which is a topological order
471
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
93 visit = [ (self.rev(n), n) for n in needed.keys() ]
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
94 visit.sort()
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
95 hist = {}
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
96
471
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
97 for r,n in visit:
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
98 curr = decorate(self.read(n), self.linkrev(n))
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
99 for p in self.parents(n):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
100 if p != nullid:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
101 curr = pair(hist[p], curr)
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
102 # trim the history of unneeded revs
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
103 needed[p] -= 1
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
104 if not needed[p]:
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
105 del hist[p]
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
106 hist[n] = curr
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
107
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
108 return zip(hist[n][0], hist[n][1].splitlines(1))