Mercurial > hg
annotate mercurial/filelog.py @ 25087:559f24e3957d
tags: use try/except/finally
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Fri, 15 May 2015 09:58:02 -0500 |
parents | 4bfe9f2d9761 |
children | 34bd1a5eef5b |
rev | line source |
---|---|
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 # |
4635
63b9d2deed48
Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4258
diff
changeset
|
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7634
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
7 |
24255
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
8 import error, mdiff, revlog |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
9 import re, struct |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
10 |
14074
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
11 _mdre = re.compile('\1\n') |
22421
30a610424eff
filelog: make parsemeta a public module function, to be used by censor module
Mike Edgar <adgar@google.com>
parents:
22420
diff
changeset
|
12 def parsemeta(text): |
14074
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
13 """return (metadatadict, keylist, metadatasize)""" |
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
14 # text can be buffer, so we can't use .startswith or .index |
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
15 if text[:2] != '\1\n': |
22422
75bb7c702317
filelog: parsemeta stops returning unused key list
Mike Edgar <adgar@google.com>
parents:
22421
diff
changeset
|
16 return None, None |
14074
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
17 s = _mdre.search(text, 2).start() |
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
18 mtext = text[2:s] |
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
19 meta = {} |
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
20 for l in mtext.splitlines(): |
13240
e5060aa22043
filelog: move metadata parsing to a helper function
Matt Mackall <mpm@selenic.com>
parents:
11541
diff
changeset
|
21 k, v = l.split(": ", 1) |
14074
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
22 meta[k] = v |
22422
75bb7c702317
filelog: parsemeta stops returning unused key list
Mike Edgar <adgar@google.com>
parents:
22421
diff
changeset
|
23 return meta, (s + 2) |
14074
e8271159c8c2
filelog: extract metadata parsing and packing
Sune Foldager <cryo@cyanite.org>
parents:
13240
diff
changeset
|
24 |
22420
4669e26747c3
filelog: make packmeta a public module function, to be used by censor
Mike Edgar <adgar@google.com>
parents:
19148
diff
changeset
|
25 def packmeta(meta, text): |
4669e26747c3
filelog: make packmeta a public module function, to be used by censor
Mike Edgar <adgar@google.com>
parents:
19148
diff
changeset
|
26 keys = sorted(meta.iterkeys()) |
4669e26747c3
filelog: make packmeta a public module function, to be used by censor
Mike Edgar <adgar@google.com>
parents:
19148
diff
changeset
|
27 metatext = "".join("%s: %s\n" % (k, meta[k]) for k in keys) |
4669e26747c3
filelog: make packmeta a public module function, to be used by censor
Mike Edgar <adgar@google.com>
parents:
19148
diff
changeset
|
28 return "\1\n%s\1\n%s" % (metatext, text) |
13240
e5060aa22043
filelog: move metadata parsing to a helper function
Matt Mackall <mpm@selenic.com>
parents:
11541
diff
changeset
|
29 |
22596
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
30 def _censoredtext(text): |
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
31 m, offs = parsemeta(text) |
24117
9cfd7c4f22f5
filelog: allow censored files to contain padding data
Mike Edgar <adgar@google.com>
parents:
24003
diff
changeset
|
32 return m and "censored" in m |
22596
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
33 |
7634
14a4337a9b9b
revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents:
7622
diff
changeset
|
34 class filelog(revlog.revlog): |
4258
b11a2fb59cf5
revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents:
4257
diff
changeset
|
35 def __init__(self, opener, path): |
19148
3bda242bf244
filelog: use super() for calling base functions
Durham Goode <durham@fb.com>
parents:
14287
diff
changeset
|
36 super(filelog, self).__init__(opener, |
8531
810387f59696
filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8225
diff
changeset
|
37 "/".join(("data", path + ".i"))) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
38 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
39 def read(self, node): |
360 | 40 t = self.revision(node) |
686
d7d68d27ebe5
Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents:
681
diff
changeset
|
41 if not t.startswith('\1\n'): |
360 | 42 return t |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2470
diff
changeset
|
43 s = t.index('\1\n', 2) |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
44 return t[s + 2:] |
360 | 45 |
46 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
|
47 if meta or text.startswith('\1\n'): |
22420
4669e26747c3
filelog: make packmeta a public module function, to be used by censor
Mike Edgar <adgar@google.com>
parents:
19148
diff
changeset
|
48 text = packmeta(meta, text) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
49 return self.addrevision(text, transaction, link, p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
50 |
1116 | 51 def renamed(self, node): |
7634
14a4337a9b9b
revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents:
7622
diff
changeset
|
52 if self.parents(node)[0] != revlog.nullid: |
1116 | 53 return False |
13240
e5060aa22043
filelog: move metadata parsing to a helper function
Matt Mackall <mpm@selenic.com>
parents:
11541
diff
changeset
|
54 t = self.revision(node) |
22421
30a610424eff
filelog: make parsemeta a public module function, to be used by censor module
Mike Edgar <adgar@google.com>
parents:
22420
diff
changeset
|
55 m = parsemeta(t)[0] |
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
4635
diff
changeset
|
56 if m and "copy" in m: |
7634
14a4337a9b9b
revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents:
7622
diff
changeset
|
57 return (m["copy"], revlog.bin(m["copyrev"])) |
1116 | 58 return False |
59 | |
2898
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
60 def size(self, rev): |
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
61 """return the size of a given revision""" |
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
62 |
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
63 # 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:
2895
diff
changeset
|
64 node = self.node(rev) |
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
65 if self.renamed(node): |
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
66 return len(self.read(node)) |
24118
76f6ae06ddf5
revlog: add "iscensored()" to revlog public API
Mike Edgar <adgar@google.com>
parents:
24117
diff
changeset
|
67 if self.iscensored(rev): |
22597
58ec36686f0e
filelog: censored files compare against empty data, have 0 size
Mike Edgar <adgar@google.com>
parents:
22596
diff
changeset
|
68 return 0 |
2898
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
69 |
11540
2370e270a29a
filelog: test behaviour for data starting with "\1\n"
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11539
diff
changeset
|
70 # XXX if self.read(node).startswith("\1\n"), this returns (size+4) |
19148
3bda242bf244
filelog: use super() for calling base functions
Durham Goode <durham@fb.com>
parents:
14287
diff
changeset
|
71 return super(filelog, self).size(rev) |
2898
db397c38005d
merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents:
2895
diff
changeset
|
72 |
2887
05257fd28591
filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents:
2859
diff
changeset
|
73 def cmp(self, node, text): |
11539
a463e3c50212
cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
10706
diff
changeset
|
74 """compare text with a given file revision |
a463e3c50212
cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
10706
diff
changeset
|
75 |
a463e3c50212
cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
10706
diff
changeset
|
76 returns True if text is different than what is stored. |
a463e3c50212
cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
10706
diff
changeset
|
77 """ |
2887
05257fd28591
filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents:
2859
diff
changeset
|
78 |
11541
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
79 t = text |
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
80 if text.startswith('\1\n'): |
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
81 t = '\1\n\1\n' + text |
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
82 |
19148
3bda242bf244
filelog: use super() for calling base functions
Durham Goode <durham@fb.com>
parents:
14287
diff
changeset
|
83 samehashes = not super(filelog, self).cmp(node, t) |
11541
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
84 if samehashes: |
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
85 return False |
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
86 |
22597
58ec36686f0e
filelog: censored files compare against empty data, have 0 size
Mike Edgar <adgar@google.com>
parents:
22596
diff
changeset
|
87 # censored files compare against the empty file |
24118
76f6ae06ddf5
revlog: add "iscensored()" to revlog public API
Mike Edgar <adgar@google.com>
parents:
24117
diff
changeset
|
88 if self.iscensored(self.rev(node)): |
22597
58ec36686f0e
filelog: censored files compare against empty data, have 0 size
Mike Edgar <adgar@google.com>
parents:
22596
diff
changeset
|
89 return text != '' |
58ec36686f0e
filelog: censored files compare against empty data, have 0 size
Mike Edgar <adgar@google.com>
parents:
22596
diff
changeset
|
90 |
11541
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
91 # renaming a file produces a different hash, even if the data |
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
92 # remains unchanged. Check if it's the case (slow): |
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
93 if self.renamed(node): |
2887
05257fd28591
filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents:
2859
diff
changeset
|
94 t2 = self.read(node) |
2895
21631c2c09a5
filelog.cmp: return 0 for equality
Matt Mackall <mpm@selenic.com>
parents:
2890
diff
changeset
|
95 return t2 != text |
2887
05257fd28591
filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents:
2859
diff
changeset
|
96 |
11541
ab9fa7a85dd9
filelog: cmp: don't read data if hashes are identical (issue2273)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
11540
diff
changeset
|
97 return True |
14287
7c231754a621
filelog: add file function to open other filelogs
Sune Foldager <cryo@cyanite.org>
parents:
14074
diff
changeset
|
98 |
22596
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
99 def checkhash(self, text, p1, p2, node, rev=None): |
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
100 try: |
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
101 super(filelog, self).checkhash(text, p1, p2, node, rev=rev) |
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
102 except error.RevlogError: |
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
103 if _censoredtext(text): |
24190
903c7e8c97ad
changegroup: emit full-replacement deltas if either revision is censored
Mike Edgar <adgar@google.com>
parents:
24118
diff
changeset
|
104 raise error.CensoredNodeError(self.indexfile, node, text) |
22596
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
105 raise |
27e2317efe89
filelog: raise CensoredNodeError when hash checks fail with censor metadata
Mike Edgar <adgar@google.com>
parents:
22422
diff
changeset
|
106 |
24118
76f6ae06ddf5
revlog: add "iscensored()" to revlog public API
Mike Edgar <adgar@google.com>
parents:
24117
diff
changeset
|
107 def iscensored(self, rev): |
22597
58ec36686f0e
filelog: censored files compare against empty data, have 0 size
Mike Edgar <adgar@google.com>
parents:
22596
diff
changeset
|
108 """Check if a file revision is censored.""" |
23858
22a979d1ae56
filelog: use censored revlog flag bit to quickly check if a node is censored
Mike Edgar <adgar@google.com>
parents:
22597
diff
changeset
|
109 return self.flags(rev) & revlog.REVIDX_ISCENSORED |
24255
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
110 |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
111 def _peek_iscensored(self, baserev, delta, flush): |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
112 """Quickly check if a delta produces a censored revision.""" |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
113 # Fragile heuristic: unless new file meta keys are added alphabetically |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
114 # preceding "censored", all censored revisions are prefixed by |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
115 # "\1\ncensored:". A delta producing such a censored revision must be a |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
116 # full-replacement delta, so we inspect the first and only patch in the |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
117 # delta for this prefix. |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
118 hlen = struct.calcsize(">lll") |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
119 if len(delta) <= hlen: |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
120 return False |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
121 |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
122 oldlen = self.rawsize(baserev) |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
123 newlen = len(delta) - hlen |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
124 if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen): |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
125 return False |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
126 |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
127 add = "\1\ncensored:" |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
128 addlen = len(add) |
4bfe9f2d9761
revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents:
24190
diff
changeset
|
129 return newlen >= addlen and delta[hlen:hlen + addlen] == add |