##// END OF EJS Templates
Re-enable the renamed check fastpath
Matt Mackall -
r1595:dca956c9 default
parent child Browse files
Show More
@@ -1,107 +1,107 b''
1 # filelog.py - file history class for mercurial
1 # filelog.py - file history class for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 import os
8 import os
9 from revlog import *
9 from revlog import *
10 from demandload import *
10 from demandload import *
11 demandload(globals(), "bdiff")
11 demandload(globals(), "bdiff")
12
12
13 class filelog(revlog):
13 class filelog(revlog):
14 def __init__(self, opener, path):
14 def __init__(self, opener, path):
15 revlog.__init__(self, opener,
15 revlog.__init__(self, opener,
16 os.path.join("data", self.encodedir(path + ".i")),
16 os.path.join("data", self.encodedir(path + ".i")),
17 os.path.join("data", self.encodedir(path + ".d")))
17 os.path.join("data", self.encodedir(path + ".d")))
18
18
19 # This avoids a collision between a file named foo and a dir named
19 # This avoids a collision between a file named foo and a dir named
20 # foo.i or foo.d
20 # foo.i or foo.d
21 def encodedir(self, path):
21 def encodedir(self, path):
22 return (path
22 return (path
23 .replace(".hg/", ".hg.hg/")
23 .replace(".hg/", ".hg.hg/")
24 .replace(".i/", ".i.hg/")
24 .replace(".i/", ".i.hg/")
25 .replace(".d/", ".d.hg/"))
25 .replace(".d/", ".d.hg/"))
26
26
27 def decodedir(self, path):
27 def decodedir(self, path):
28 return (path
28 return (path
29 .replace(".d.hg/", ".d/")
29 .replace(".d.hg/", ".d/")
30 .replace(".i.hg/", ".i/")
30 .replace(".i.hg/", ".i/")
31 .replace(".hg.hg/", ".hg/"))
31 .replace(".hg.hg/", ".hg/"))
32
32
33 def read(self, node):
33 def read(self, node):
34 t = self.revision(node)
34 t = self.revision(node)
35 if not t.startswith('\1\n'):
35 if not t.startswith('\1\n'):
36 return t
36 return t
37 s = t.find('\1\n', 2)
37 s = t.find('\1\n', 2)
38 return t[s+2:]
38 return t[s+2:]
39
39
40 def readmeta(self, node):
40 def readmeta(self, node):
41 t = self.revision(node)
41 t = self.revision(node)
42 if not t.startswith('\1\n'):
42 if not t.startswith('\1\n'):
43 return {}
43 return {}
44 s = t.find('\1\n', 2)
44 s = t.find('\1\n', 2)
45 mt = t[2:s]
45 mt = t[2:s]
46 m = {}
46 m = {}
47 for l in mt.splitlines():
47 for l in mt.splitlines():
48 k, v = l.split(": ", 1)
48 k, v = l.split(": ", 1)
49 m[k] = v
49 m[k] = v
50 return m
50 return m
51
51
52 def add(self, text, meta, transaction, link, p1=None, p2=None):
52 def add(self, text, meta, transaction, link, p1=None, p2=None):
53 if meta or text.startswith('\1\n'):
53 if meta or text.startswith('\1\n'):
54 mt = ""
54 mt = ""
55 if meta:
55 if meta:
56 mt = [ "%s: %s\n" % (k, v) for k,v in meta.items() ]
56 mt = [ "%s: %s\n" % (k, v) for k,v in meta.items() ]
57 text = "\1\n%s\1\n%s" % ("".join(mt), text)
57 text = "\1\n%s\1\n%s" % ("".join(mt), text)
58 return self.addrevision(text, transaction, link, p1, p2)
58 return self.addrevision(text, transaction, link, p1, p2)
59
59
60 def renamed(self, node):
60 def renamed(self, node):
61 if 0 and self.parents(node)[0] != nullid: # XXX
61 if self.parents(node)[0] != nullid:
62 return False
62 return False
63 m = self.readmeta(node)
63 m = self.readmeta(node)
64 if m and m.has_key("copy"):
64 if m and m.has_key("copy"):
65 return (m["copy"], bin(m["copyrev"]))
65 return (m["copy"], bin(m["copyrev"]))
66 return False
66 return False
67
67
68 def annotate(self, node):
68 def annotate(self, node):
69
69
70 def decorate(text, rev):
70 def decorate(text, rev):
71 return ([rev] * len(text.splitlines()), text)
71 return ([rev] * len(text.splitlines()), text)
72
72
73 def pair(parent, child):
73 def pair(parent, child):
74 for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
74 for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
75 child[0][b1:b2] = parent[0][a1:a2]
75 child[0][b1:b2] = parent[0][a1:a2]
76 return child
76 return child
77
77
78 # find all ancestors
78 # find all ancestors
79 needed = {node:1}
79 needed = {node:1}
80 visit = [node]
80 visit = [node]
81 while visit:
81 while visit:
82 n = visit.pop(0)
82 n = visit.pop(0)
83 for p in self.parents(n):
83 for p in self.parents(n):
84 if p not in needed:
84 if p not in needed:
85 needed[p] = 1
85 needed[p] = 1
86 visit.append(p)
86 visit.append(p)
87 else:
87 else:
88 # count how many times we'll use this
88 # count how many times we'll use this
89 needed[p] += 1
89 needed[p] += 1
90
90
91 # sort by revision which is a topological order
91 # sort by revision which is a topological order
92 visit = [ (self.rev(n), n) for n in needed.keys() ]
92 visit = [ (self.rev(n), n) for n in needed.keys() ]
93 visit.sort()
93 visit.sort()
94 hist = {}
94 hist = {}
95
95
96 for r,n in visit:
96 for r,n in visit:
97 curr = decorate(self.read(n), self.linkrev(n))
97 curr = decorate(self.read(n), self.linkrev(n))
98 for p in self.parents(n):
98 for p in self.parents(n):
99 if p != nullid:
99 if p != nullid:
100 curr = pair(hist[p], curr)
100 curr = pair(hist[p], curr)
101 # trim the history of unneeded revs
101 # trim the history of unneeded revs
102 needed[p] -= 1
102 needed[p] -= 1
103 if not needed[p]:
103 if not needed[p]:
104 del hist[p]
104 del hist[p]
105 hist[n] = curr
105 hist[n] = curr
106
106
107 return zip(hist[n][0], hist[n][1].splitlines(1))
107 return zip(hist[n][0], hist[n][1].splitlines(1))
General Comments 0
You need to be logged in to leave comments. Login now