##// END OF EJS Templates
fix parsing of tags. make parse errors useful. add new tag tests....
Vadim Gelfer -
r2320:dbdce3b9 default
parent child Browse files
Show More
@@ -166,37 +166,44 b' class localrepository(object):'
166 return
166 return
167 s = l.split(" ", 1)
167 s = l.split(" ", 1)
168 if len(s) != 2:
168 if len(s) != 2:
169 self.ui.warn(_("%s: ignoring invalid tag\n") % context)
169 self.ui.warn(_("%s: cannot parse entry\n") % context)
170 return
170 return
171 node, key = s
171 node, key = s
172 key = key.strip()
172 try:
173 try:
173 bin_n = bin(node)
174 bin_n = bin(node)
174 except TypeError:
175 except TypeError:
175 self.ui.warn(_("%s: ignoring invalid tag\n") % context)
176 self.ui.warn(_("%s: node '%s' is not well formed\n") %
177 (context, node))
176 return
178 return
177 if bin_n not in self.changelog.nodemap:
179 if bin_n not in self.changelog.nodemap:
178 self.ui.warn(_("%s: ignoring invalid tag\n") % context)
180 self.ui.warn(_("%s: tag '%s' refers to unknown node\n") %
181 (context, key))
179 return
182 return
180 self.tagscache[key.strip()] = bin_n
183 self.tagscache[key] = bin_n
181
184
182 # read each head of the tags file, ending with the tip
185 # read the tags file from each head, ending with the tip,
183 # and add each tag found to the map, with "newer" ones
186 # and add each tag found to the map, with "newer" ones
184 # taking precedence
187 # taking precedence
188 heads = self.heads()
189 heads.reverse()
185 fl = self.file(".hgtags")
190 fl = self.file(".hgtags")
186 h = fl.heads()
191 for node in heads:
187 h.reverse()
192 change = self.changelog.read(node)
188 for r in h:
193 rev = self.changelog.rev(node)
194 fn, ff = self.manifest.find(change[0], '.hgtags')
195 if fn is None: continue
189 count = 0
196 count = 0
190 for l in fl.read(r).splitlines():
197 for l in fl.read(fn).splitlines():
191 count += 1
198 count += 1
192 parsetag(l, ".hgtags:%d" % count)
199 parsetag(l, _(".hgtags (rev %d:%s), line %d") %
193
200 (rev, short(node), count))
194 try:
201 try:
195 f = self.opener("localtags")
202 f = self.opener("localtags")
196 count = 0
203 count = 0
197 for l in f:
204 for l in f:
198 count += 1
205 count += 1
199 parsetag(l, "localtags:%d" % count)
206 parsetag(l, _("localtags, line %d") % count)
200 except IOError:
207 except IOError:
201 pass
208 pass
202
209
@@ -43,48 +43,61 b' class manifest(revlog):'
43 def diff(self, a, b):
43 def diff(self, a, b):
44 return mdiff.textdiff(str(a), str(b))
44 return mdiff.textdiff(str(a), str(b))
45
45
46 def _search(self, m, s, lo=0, hi=None):
47 '''return a tuple (start, end) that says where to find s within m.
48
49 If the string is found m[start:end] are the line containing
50 that string. If start == end the string was not found and
51 they indicate the proper sorted insertion point. This was
52 taken from bisect_left, and modified to find line start/end as
53 it goes along.
54
55 m should be a buffer or a string
56 s is a string'''
57 def advance(i, c):
58 while i < lenm and m[i] != c:
59 i += 1
60 return i
61 lenm = len(m)
62 if not hi:
63 hi = lenm
64 while lo < hi:
65 mid = (lo + hi) // 2
66 start = mid
67 while start > 0 and m[start-1] != '\n':
68 start -= 1
69 end = advance(start, '\0')
70 if m[start:end] < s:
71 # we know that after the null there are 40 bytes of sha1
72 # this translates to the bisect lo = mid + 1
73 lo = advance(end + 40, '\n') + 1
74 else:
75 # this translates to the bisect hi = mid
76 hi = start
77 end = advance(lo, '\0')
78 found = m[lo:end]
79 if cmp(s, found) == 0:
80 # we know that after the null there are 40 bytes of sha1
81 end = advance(end + 40, '\n')
82 return (lo, end+1)
83 else:
84 return (lo, lo)
85
86 def find(self, node, f):
87 '''look up entry for a single file efficiently.
88 return (node, flag) pair if found, (None, None) if not.'''
89 if self.mapcache and node == self.mapcache[0]:
90 return self.mapcache[1].get(f), self.mapcache[2].get(f)
91 text = self.revision(node)
92 start, end = self._search(text, f)
93 if start == end:
94 return None, None
95 l = text[start:end]
96 f, n = l.split('\0')
97 return bin(n[:40]), n[40:-1] == 'x'
98
46 def add(self, map, flags, transaction, link, p1=None, p2=None,
99 def add(self, map, flags, transaction, link, p1=None, p2=None,
47 changed=None):
100 changed=None):
48
49 # returns a tuple (start, end). If the string is found
50 # m[start:end] are the line containing that string. If start == end
51 # the string was not found and they indicate the proper sorted
52 # insertion point. This was taken from bisect_left, and modified
53 # to find line start/end as it goes along.
54 #
55 # m should be a buffer or a string
56 # s is a string
57 #
58 def manifestsearch(m, s, lo=0, hi=None):
59 def advance(i, c):
60 while i < lenm and m[i] != c:
61 i += 1
62 return i
63 lenm = len(m)
64 if not hi:
65 hi = lenm
66 while lo < hi:
67 mid = (lo + hi) // 2
68 start = mid
69 while start > 0 and m[start-1] != '\n':
70 start -= 1
71 end = advance(start, '\0')
72 if m[start:end] < s:
73 # we know that after the null there are 40 bytes of sha1
74 # this translates to the bisect lo = mid + 1
75 lo = advance(end + 40, '\n') + 1
76 else:
77 # this translates to the bisect hi = mid
78 hi = start
79 end = advance(lo, '\0')
80 found = m[lo:end]
81 if cmp(s, found) == 0:
82 # we know that after the null there are 40 bytes of sha1
83 end = advance(end + 40, '\n')
84 return (lo, end+1)
85 else:
86 return (lo, lo)
87
88 # apply the changes collected during the bisect loop to our addlist
101 # apply the changes collected during the bisect loop to our addlist
89 # return a delta suitable for addrevision
102 # return a delta suitable for addrevision
90 def addlistdelta(addlist, x):
103 def addlistdelta(addlist, x):
@@ -137,7 +150,7 b' class manifest(revlog):'
137 for w in work:
150 for w in work:
138 f = w[0]
151 f = w[0]
139 # bs will either be the index of the item or the insert point
152 # bs will either be the index of the item or the insert point
140 start, end = manifestsearch(addbuf, f, start)
153 start, end = self._search(addbuf, f, start)
141 if w[1] == 0:
154 if w[1] == 0:
142 l = "%s\000%s%s\n" % (f, hex(map[f]),
155 l = "%s\000%s%s\n" % (f, hex(map[f]),
143 flags[f] and "x" or '')
156 flags[f] and "x" or '')
@@ -32,12 +32,31 b' hg id'
32 hg status
32 hg status
33
33
34 hg commit -m "merge" -d "1000000 0"
34 hg commit -m "merge" -d "1000000 0"
35
36 # create fake head, make sure tag not visible afterwards
37 cp .hgtags tags
38 hg tag -d "1000000 0" last
39 hg rm .hgtags
40 hg commit -m "remove" -d "1000000 0"
41
42 mv tags .hgtags
43 hg add .hgtags
44 hg commit -m "readd" -d "1000000 0"
45
46 hg tags
47
35 # invalid tags
48 # invalid tags
36 echo "spam" >> .hgtags
49 echo "spam" >> .hgtags
37 echo >> .hgtags
50 echo >> .hgtags
38 echo "foo bar" >> .hgtags
51 echo "foo bar" >> .hgtags
39 echo "$T invalid" | sed "s/..../a5a5/" >> .hg/localtags
52 echo "$T invalid" | sed "s/..../a5a5/" >> .hg/localtags
40 hg commit -m "tags" -d "1000000 0"
53 hg commit -m "tags" -d "1000000 0"
54
55 # report tag parse error on other head
56 hg up 3
57 echo 'x y' >> .hgtags
58 hg commit -m "head" -d "1000000 0"
59
41 hg tags
60 hg tags
42 hg tip
61 hg tip
43
62
@@ -16,17 +16,26 b' 1 files updated, 0 files merged, 0 files'
16 (branch merge, don't forget to commit)
16 (branch merge, don't forget to commit)
17 8216907a933d+8a3ca90d111d+ tip
17 8216907a933d+8a3ca90d111d+ tip
18 M .hgtags
18 M .hgtags
19 .hgtags:2: ignoring invalid tag
19 tip 6:c6af9d771a81bb9c7f267ec03491224a9f8ba1cd
20 .hgtags:4: ignoring invalid tag
21 localtags:1: ignoring invalid tag
22 tip 4:fd868a874787a7b5af31e1675666ce691c803035
23 first 0:0acdaf8983679e0aac16e811534eb49d7ee1f2b4
20 first 0:0acdaf8983679e0aac16e811534eb49d7ee1f2b4
24 changeset: 4:fd868a874787
21 .hgtags (rev 7:39bba1bbbc4c), line 2: cannot parse entry
25 .hgtags:2: ignoring invalid tag
22 .hgtags (rev 7:39bba1bbbc4c), line 4: node 'foo' is not well formed
26 .hgtags:4: ignoring invalid tag
23 localtags, line 1: tag 'invalid' refers to unknown node
27 localtags:1: ignoring invalid tag
24 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 .hgtags (rev 7:39bba1bbbc4c), line 2: cannot parse entry
26 .hgtags (rev 7:39bba1bbbc4c), line 4: node 'foo' is not well formed
27 .hgtags (rev 8:4ca6f1b1a68c), line 2: node 'x' is not well formed
28 localtags, line 1: tag 'invalid' refers to unknown node
29 tip 8:4ca6f1b1a68c77be687a03aaeb1614671ba59b20
30 first 0:0acdaf8983679e0aac16e811534eb49d7ee1f2b4
31 changeset: 8:4ca6f1b1a68c
32 .hgtags (rev 7:39bba1bbbc4c), line 2: cannot parse entry
33 .hgtags (rev 7:39bba1bbbc4c), line 4: node 'foo' is not well formed
34 .hgtags (rev 8:4ca6f1b1a68c), line 2: node 'x' is not well formed
35 localtags, line 1: tag 'invalid' refers to unknown node
28 tag: tip
36 tag: tip
37 parent: 3:b2ef3841386b
29 user: test
38 user: test
30 date: Mon Jan 12 13:46:40 1970 +0000
39 date: Mon Jan 12 13:46:40 1970 +0000
31 summary: tags
40 summary: head
32
41
General Comments 0
You need to be logged in to leave comments. Login now