##// END OF EJS Templates
filelog: test behaviour for data starting with "\1\n"...
Nicolas Dumazet -
r11540:2370e270 stable
parent child Browse files
Show More
@@ -0,0 +1,50 b''
1 #!/usr/bin/env python
2 """
3 Tests the behaviour of filelog w.r.t. data starting with '\1\n'
4 """
5 from mercurial import ui, hg
6 from mercurial.node import nullid, hex
7
8 myui = ui.ui()
9 repo = hg.repository(myui, path='.', create=True)
10
11 fl = repo.file('foobar')
12
13 def addrev(text, renamed=False):
14 if renamed:
15 # data doesnt matter. Just make sure filelog.renamed() returns True
16 meta = dict(copyrev=hex(nullid), copy='bar')
17 else:
18 meta = {}
19
20 t = repo.transaction('commit')
21 try:
22 node = fl.add(text, meta, t, 0, nullid, nullid)
23 return node
24 finally:
25 t.close()
26
27 def error(text):
28 print 'ERROR: ' + text
29
30 textwith = '\1\nfoo'
31 without = 'foo'
32
33 node = addrev(textwith)
34 if not textwith == fl.read(node):
35 error('filelog.read for data starting with \\1\\n')
36 if fl.cmp(node, textwith) or not fl.cmp(node, without):
37 error('filelog.cmp for data starting with \\1\\n')
38 if fl.size(0) != len(textwith):
39 error('FIXME: This is a known failure of filelog.size for data starting '
40 'with \\1\\n')
41
42 node = addrev(textwith, renamed=True)
43 if not textwith == fl.read(node):
44 error('filelog.read for a renaming + data starting with \\1\\n')
45 if fl.cmp(node, textwith) or not fl.cmp(node, without):
46 error('filelog.cmp for a renaming + data starting with \\1\\n')
47 if fl.size(1) != len(textwith):
48 error('filelog.size for a renaming + data starting with \\1\\n')
49
50 print 'OK.'
@@ -0,0 +1,2 b''
1 ERROR: FIXME: This is a known failure of filelog.size for data starting with \1\n
2 OK.
@@ -1,69 +1,70 b''
1 # filelog.py - file history class for mercurial
1 # filelog.py - file history class for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import revlog
8 import revlog
9
9
10 class filelog(revlog.revlog):
10 class filelog(revlog.revlog):
11 def __init__(self, opener, path):
11 def __init__(self, opener, path):
12 revlog.revlog.__init__(self, opener,
12 revlog.revlog.__init__(self, opener,
13 "/".join(("data", path + ".i")))
13 "/".join(("data", path + ".i")))
14
14
15 def read(self, node):
15 def read(self, node):
16 t = self.revision(node)
16 t = self.revision(node)
17 if not t.startswith('\1\n'):
17 if not t.startswith('\1\n'):
18 return t
18 return t
19 s = t.index('\1\n', 2)
19 s = t.index('\1\n', 2)
20 return t[s + 2:]
20 return t[s + 2:]
21
21
22 def _readmeta(self, node):
22 def _readmeta(self, node):
23 t = self.revision(node)
23 t = self.revision(node)
24 if not t.startswith('\1\n'):
24 if not t.startswith('\1\n'):
25 return {}
25 return {}
26 s = t.index('\1\n', 2)
26 s = t.index('\1\n', 2)
27 mt = t[2:s]
27 mt = t[2:s]
28 m = {}
28 m = {}
29 for l in mt.splitlines():
29 for l in mt.splitlines():
30 k, v = l.split(": ", 1)
30 k, v = l.split(": ", 1)
31 m[k] = v
31 m[k] = v
32 return m
32 return m
33
33
34 def add(self, text, meta, transaction, link, p1=None, p2=None):
34 def add(self, text, meta, transaction, link, p1=None, p2=None):
35 if meta or text.startswith('\1\n'):
35 if meta or text.startswith('\1\n'):
36 mt = ["%s: %s\n" % (k, v) for k, v in sorted(meta.iteritems())]
36 mt = ["%s: %s\n" % (k, v) for k, v in sorted(meta.iteritems())]
37 text = "\1\n%s\1\n%s" % ("".join(mt), text)
37 text = "\1\n%s\1\n%s" % ("".join(mt), text)
38 return self.addrevision(text, transaction, link, p1, p2)
38 return self.addrevision(text, transaction, link, p1, p2)
39
39
40 def renamed(self, node):
40 def renamed(self, node):
41 if self.parents(node)[0] != revlog.nullid:
41 if self.parents(node)[0] != revlog.nullid:
42 return False
42 return False
43 m = self._readmeta(node)
43 m = self._readmeta(node)
44 if m and "copy" in m:
44 if m and "copy" in m:
45 return (m["copy"], revlog.bin(m["copyrev"]))
45 return (m["copy"], revlog.bin(m["copyrev"]))
46 return False
46 return False
47
47
48 def size(self, rev):
48 def size(self, rev):
49 """return the size of a given revision"""
49 """return the size of a given revision"""
50
50
51 # for revisions with renames, we have to go the slow way
51 # for revisions with renames, we have to go the slow way
52 node = self.node(rev)
52 node = self.node(rev)
53 if self.renamed(node):
53 if self.renamed(node):
54 return len(self.read(node))
54 return len(self.read(node))
55
55
56 # XXX if self.read(node).startswith("\1\n"), this returns (size+4)
56 return revlog.revlog.size(self, rev)
57 return revlog.revlog.size(self, rev)
57
58
58 def cmp(self, node, text):
59 def cmp(self, node, text):
59 """compare text with a given file revision
60 """compare text with a given file revision
60
61
61 returns True if text is different than what is stored.
62 returns True if text is different than what is stored.
62 """
63 """
63
64
64 # for renames, we have to go the slow way
65 # for renames, we have to go the slow way
65 if text.startswith('\1\n') or self.renamed(node):
66 if text.startswith('\1\n') or self.renamed(node):
66 t2 = self.read(node)
67 t2 = self.read(node)
67 return t2 != text
68 return t2 != text
68
69
69 return revlog.revlog.cmp(self, node, text)
70 return revlog.revlog.cmp(self, node, text)
General Comments 0
You need to be logged in to leave comments. Login now