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