Show More
@@ -166,37 +166,44 b' class localrepository(object):' | |||
|
166 | 166 | return |
|
167 | 167 | s = l.split(" ", 1) |
|
168 | 168 | if len(s) != 2: |
|
169 |
self.ui.warn(_("%s: |
|
|
169 | self.ui.warn(_("%s: cannot parse entry\n") % context) | |
|
170 | 170 | return |
|
171 | 171 | node, key = s |
|
172 | key = key.strip() | |
|
172 | 173 | try: |
|
173 | 174 | bin_n = bin(node) |
|
174 | 175 | except TypeError: |
|
175 |
self.ui.warn(_("%s: |
|
|
176 | self.ui.warn(_("%s: node '%s' is not well formed\n") % | |
|
177 | (context, node)) | |
|
176 | 178 | return |
|
177 | 179 | if bin_n not in self.changelog.nodemap: |
|
178 |
self.ui.warn(_("%s: |
|
|
180 | self.ui.warn(_("%s: tag '%s' refers to unknown node\n") % | |
|
181 | (context, key)) | |
|
179 | 182 | return |
|
180 |
self.tagscache[key |
|
|
183 | self.tagscache[key] = bin_n | |
|
181 | 184 | |
|
182 |
# read |
|
|
185 | # read the tags file from each head, ending with the tip, | |
|
183 | 186 | # and add each tag found to the map, with "newer" ones |
|
184 | 187 | # taking precedence |
|
188 | heads = self.heads() | |
|
189 | heads.reverse() | |
|
185 | 190 | fl = self.file(".hgtags") |
|
186 |
|
|
|
187 | h.reverse() | |
|
188 | for r in h: | |
|
191 | for node in heads: | |
|
192 | change = self.changelog.read(node) | |
|
193 | rev = self.changelog.rev(node) | |
|
194 | fn, ff = self.manifest.find(change[0], '.hgtags') | |
|
195 | if fn is None: continue | |
|
189 | 196 | count = 0 |
|
190 |
for l in fl.read( |
|
|
197 | for l in fl.read(fn).splitlines(): | |
|
191 | 198 | count += 1 |
|
192 |
parsetag(l, ".hgtags:%d" % |
|
|
193 | ||
|
199 | parsetag(l, _(".hgtags (rev %d:%s), line %d") % | |
|
200 | (rev, short(node), count)) | |
|
194 | 201 | try: |
|
195 | 202 | f = self.opener("localtags") |
|
196 | 203 | count = 0 |
|
197 | 204 | for l in f: |
|
198 | 205 | count += 1 |
|
199 |
parsetag(l, "localtags |
|
|
206 | parsetag(l, _("localtags, line %d") % count) | |
|
200 | 207 | except IOError: |
|
201 | 208 | pass |
|
202 | 209 |
@@ -43,48 +43,61 b' class manifest(revlog):' | |||
|
43 | 43 | def diff(self, a, b): |
|
44 | 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 | 99 | def add(self, map, flags, transaction, link, p1=None, p2=None, |
|
47 | 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 | 101 | # apply the changes collected during the bisect loop to our addlist |
|
89 | 102 | # return a delta suitable for addrevision |
|
90 | 103 | def addlistdelta(addlist, x): |
@@ -137,7 +150,7 b' class manifest(revlog):' | |||
|
137 | 150 | for w in work: |
|
138 | 151 | f = w[0] |
|
139 | 152 | # bs will either be the index of the item or the insert point |
|
140 |
start, end = |
|
|
153 | start, end = self._search(addbuf, f, start) | |
|
141 | 154 | if w[1] == 0: |
|
142 | 155 | l = "%s\000%s%s\n" % (f, hex(map[f]), |
|
143 | 156 | flags[f] and "x" or '') |
@@ -32,12 +32,31 b' hg id' | |||
|
32 | 32 | hg status |
|
33 | 33 | |
|
34 | 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 | 48 | # invalid tags |
|
36 | 49 | echo "spam" >> .hgtags |
|
37 | 50 | echo >> .hgtags |
|
38 | 51 | echo "foo bar" >> .hgtags |
|
39 | 52 | echo "$T invalid" | sed "s/..../a5a5/" >> .hg/localtags |
|
40 | 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 | 60 | hg tags |
|
42 | 61 | hg tip |
|
43 | 62 |
@@ -16,17 +16,26 b' 1 files updated, 0 files merged, 0 files' | |||
|
16 | 16 | (branch merge, don't forget to commit) |
|
17 | 17 | 8216907a933d+8a3ca90d111d+ tip |
|
18 | 18 | M .hgtags |
|
19 | .hgtags:2: ignoring invalid tag | |
|
20 | .hgtags:4: ignoring invalid tag | |
|
21 | localtags:1: ignoring invalid tag | |
|
22 | tip 4:fd868a874787a7b5af31e1675666ce691c803035 | |
|
19 | tip 6:c6af9d771a81bb9c7f267ec03491224a9f8ba1cd | |
|
23 | 20 | first 0:0acdaf8983679e0aac16e811534eb49d7ee1f2b4 |
|
24 | changeset: 4:fd868a874787 | |
|
25 | .hgtags:2: ignoring invalid tag | |
|
26 | .hgtags:4: ignoring invalid tag | |
|
27 | localtags:1: ignoring invalid tag | |
|
21 | .hgtags (rev 7:39bba1bbbc4c), line 2: cannot parse entry | |
|
22 | .hgtags (rev 7:39bba1bbbc4c), line 4: node 'foo' is not well formed | |
|
23 | localtags, line 1: tag 'invalid' refers to unknown node | |
|
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 | 36 | tag: tip |
|
37 | parent: 3:b2ef3841386b | |
|
29 | 38 | user: test |
|
30 | 39 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
31 |
summary: |
|
|
40 | summary: head | |
|
32 | 41 |
General Comments 0
You need to be logged in to leave comments.
Login now