annotate mercurial/filelog.py @ 6858:8f256bf98219

Add support for multiple possible bisect results (issue1228, issue1182) The real reason for both issue is that bisect can not handle cases where there are multiple possibilities for the result. Example (from issue1228): rev 0 -> good rev 1 -> skipped rev 2 -> skipped rev 3 -> skipped rev 4 -> bad Note that this patch does not only fix the reported Assertion Error but also the problem of a non converging bisect: hg init for i in `seq 3`; do echo $i > $i; hg add $i; hg ci -m$i; done hg bisect -b 2 hg bisect -g 0 hg bisect -s From this state on, you can: a) mark as bad forever (non converging!) b) mark as good to get an inconsistent state c) skip for the Assertion Error Minor description and code edits by pmezard.
author Bernhard Leiner <bleiner@gmail.com>
date Sat, 02 Aug 2008 22:10:10 +0200
parents e75aab656f46
children 4dd7b28003d2
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 #
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 #
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
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5915
diff changeset
8 from node import bin, nullid
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5915
diff changeset
9 from revlog import revlog
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
10
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
11 class filelog(revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
12 def __init__(self, opener, path):
144
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
13 revlog.__init__(self, opener,
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
14 "/".join(("data", self.encodedir(path + ".i"))))
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
15
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
16 # 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
17 # foo.i or foo.d
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
18 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
19 return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
20 .replace(".hg/", ".hg.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
21 .replace(".i/", ".i.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
22 .replace(".d/", ".d.hg/"))
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
23
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
24 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
25 return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
26 .replace(".d.hg/", ".d/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
27 .replace(".i.hg/", ".i/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
28 .replace(".hg.hg/", ".hg/"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
29
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
30 def read(self, node):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
31 t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
32 if not t.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
33 return t
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2470
diff changeset
34 s = t.index('\1\n', 2)
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
35 return t[s+2:]
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
36
3123
4ea58eb3f0c9 filelog: make metadata method private
Matt Mackall <mpm@selenic.com>
parents: 2948
diff changeset
37 def _readmeta(self, node):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
38 t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
39 if not t.startswith('\1\n'):
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
40 return {}
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2470
diff changeset
41 s = t.index('\1\n', 2)
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
42 mt = t[2:s]
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
43 m = {}
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
44 for l in mt.splitlines():
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
45 k, v = l.split(": ", 1)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
46 m[k] = v
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
47 return m
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
48
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
49 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
50 if meta or text.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
51 mt = ""
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
52 if meta:
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
53 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
54 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
55 return self.addrevision(text, transaction, link, p1, p2)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
56
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
57 def renamed(self, node):
1595
dca956c9767d Re-enable the renamed check fastpath
Matt Mackall <mpm@selenic.com>
parents: 1541
diff changeset
58 if self.parents(node)[0] != nullid:
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
59 return False
3123
4ea58eb3f0c9 filelog: make metadata method private
Matt Mackall <mpm@selenic.com>
parents: 2948
diff changeset
60 m = self._readmeta(node)
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 4635
diff changeset
61 if m and "copy" in m:
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
62 return (m["copy"], bin(m["copyrev"]))
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
2898
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
65 def size(self, rev):
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
66 """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
67
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
68 # 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
69 node = self.node(rev)
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
70 if self.renamed(node):
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
71 return len(self.read(node))
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
72
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
73 return revlog.size(self, rev)
db397c38005d merge: use file size stored in revlog index
Matt Mackall <mpm@selenic.com>
parents: 2895
diff changeset
74
2887
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
75 def cmp(self, node, text):
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
76 """compare text with a given file revision"""
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
77
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
78 # for renames, we have to go the slow way
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
79 if self.renamed(node):
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
80 t2 = self.read(node)
2895
21631c2c09a5 filelog.cmp: return 0 for equality
Matt Mackall <mpm@selenic.com>
parents: 2890
diff changeset
81 return t2 != text
2887
05257fd28591 filelog: add hash-based comparisons
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
82
2890
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2887
diff changeset
83 return revlog.cmp(self, node, text)