author | Thomas Arendsen Hein <thomas@intevation.de> |
Tue, 25 Apr 2006 19:38:19 +0200 | |
changeset 2127 | 8a85dbbadddf |
parent 2072 | 74d3f5336b66 |
child 2222 | c9e264b115e6 |
permissions | -rw-r--r-- |
1089 | 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 | 8 |
import os |
262 | 9 |
from revlog import * |
10 |
from demandload import * |
|
1089 | 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 | 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 | 17 |
os.path.join("data", self.encodedir(path + ".d")), |
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 | 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 | 37 |
return t |
38 |
s = t.find('\1\n', 2) |
|
39 |
return t[s+2:] |
|
40 |
||
41 |
def readmeta(self, node): |
|
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 | 44 |
return {} |
360 | 45 |
s = t.find('\1\n', 2) |
46 |
mt = t[2:s] |
|
1116 | 47 |
m = {} |
360 | 48 |
for l in mt.splitlines(): |
49 |
k, v = l.split(": ", 1) |
|
50 |
m[k] = v |
|
51 |
return m |
|
52 |
||
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 | 55 |
mt = "" |
56 |
if meta: |
|
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 | 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 | 63 |
return False |
64 |
m = self.readmeta(node) |
|
65 |
if m and m.has_key("copy"): |
|
66 |
return (m["copy"], bin(m["copyrev"])) |
|
67 |
return False |
|
68 |
||
79 | 69 |
def annotate(self, node): |
199 | 70 |
|
71 |
def decorate(text, rev): |
|
436 | 72 |
return ([rev] * len(text.splitlines()), text) |
199 | 73 |
|
74 |
def pair(parent, child): |
|
436 | 75 |
for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]): |
471 | 76 |
child[0][b1:b2] = parent[0][a1:a2] |
77 |
return child |
|
199 | 78 |
|
200 | 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 | 81 |
visit = [node] |
82 |
while visit: |
|
83 |
n = visit.pop(0) |
|
84 |
for p in self.parents(n): |
|
85 |
if p not in needed: |
|
86 |
needed[p] = 1 |
|
87 |
visit.append(p) |
|
200 | 88 |
else: |
89 |
# count how many times we'll use this |
|
90 |
needed[p] += 1 |
|
199 | 91 |
|
200 | 92 |
# sort by revision which is a topological order |
471 | 93 |
visit = [ (self.rev(n), n) for n in needed.keys() ] |
199 | 94 |
visit.sort() |
95 |
hist = {} |
|
96 |
||
471 | 97 |
for r,n in visit: |
199 | 98 |
curr = decorate(self.read(n), self.linkrev(n)) |
99 |
for p in self.parents(n): |
|
100 |
if p != nullid: |
|
101 |
curr = pair(hist[p], curr) |
|
200 | 102 |
# trim the history of unneeded revs |
103 |
needed[p] -= 1 |
|
104 |
if not needed[p]: |
|
105 |
del hist[p] |
|
199 | 106 |
hist[n] = curr |
107 |
||
436 | 108 |
return zip(hist[n][0], hist[n][1].splitlines(1)) |