82 except (LookupError, ValueError): |
82 except (LookupError, ValueError): |
83 del filetags[t] |
83 del filetags[t] |
84 |
84 |
85 _updatetags(filetags, "local", alltags, tagtypes) |
85 _updatetags(filetags, "local", alltags, tagtypes) |
86 |
86 |
87 def _readtags(ui, repo, lines, fn, recode=None): |
87 def _readtaghist(ui, repo, lines, fn, recode=None, calcnodelines=False): |
|
88 '''Read tag definitions from a file (or any source of lines). |
|
89 This function returns two sortdicts with similar information: |
|
90 - the first dict, bingtaglist, contains the tag information as expected by |
|
91 the _readtags function, i.e. a mapping from tag name to (node, hist): |
|
92 - node is the node id from the last line read for that name, |
|
93 - hist is the list of node ids previously associated with it (in file |
|
94 order). All node ids are binary, not hex. |
|
95 - the second dict, hextaglines, is a mapping from tag name to a list of |
|
96 [hexnode, line number] pairs, ordered from the oldest to the newest node. |
|
97 When calcnodelines is False the hextaglines dict is not calculated (an |
|
98 empty dict is returned). This is done to improve this function's |
|
99 performance in cases where the line numbers are not needed. |
|
100 ''' |
|
101 |
|
102 bintaghist = util.sortdict() |
|
103 hextaglines = util.sortdict() |
|
104 count = 0 |
|
105 |
|
106 def warn(msg): |
|
107 ui.warn(_("%s, line %s: %s\n") % (fn, count, msg)) |
|
108 |
|
109 for nline, line in enumerate(lines): |
|
110 count += 1 |
|
111 if not line: |
|
112 continue |
|
113 try: |
|
114 (nodehex, name) = line.split(" ", 1) |
|
115 except ValueError: |
|
116 warn(_("cannot parse entry")) |
|
117 continue |
|
118 name = name.strip() |
|
119 if recode: |
|
120 name = recode(name) |
|
121 try: |
|
122 nodebin = bin(nodehex) |
|
123 except TypeError: |
|
124 warn(_("node '%s' is not well formed") % nodehex) |
|
125 continue |
|
126 |
|
127 # update filetags |
|
128 if calcnodelines: |
|
129 # map tag name to a list of line numbers |
|
130 if name not in hextaglines: |
|
131 hextaglines[name] = [] |
|
132 hextaglines[name].append([nodehex, nline]) |
|
133 continue |
|
134 # map tag name to (node, hist) |
|
135 if name not in bintaghist: |
|
136 bintaghist[name] = [] |
|
137 bintaghist[name].append(nodebin) |
|
138 return bintaghist, hextaglines |
|
139 |
|
140 def _readtags(ui, repo, lines, fn, recode=None, calcnodelines=False): |
88 '''Read tag definitions from a file (or any source of lines). |
141 '''Read tag definitions from a file (or any source of lines). |
89 Return a mapping from tag name to (node, hist): node is the node id |
142 Return a mapping from tag name to (node, hist): node is the node id |
90 from the last line read for that name, and hist is the list of node |
143 from the last line read for that name, and hist is the list of node |
91 ids previously associated with it (in file order). All node ids are |
144 ids previously associated with it (in file order). All node ids are |
92 binary, not hex.''' |
145 binary, not hex.''' |
93 |
146 filetags, nodelines = _readtaghist(ui, repo, lines, fn, recode=recode, |
94 filetags = util.sortdict() # map tag name to (node, hist) |
147 calcnodelines=calcnodelines) |
95 count = 0 |
148 for tag, taghist in filetags.items(): |
96 |
149 filetags[tag] = (taghist[-1], taghist[:-1]) |
97 def warn(msg): |
|
98 ui.warn(_("%s, line %s: %s\n") % (fn, count, msg)) |
|
99 |
|
100 for line in lines: |
|
101 count += 1 |
|
102 if not line: |
|
103 continue |
|
104 try: |
|
105 (nodehex, name) = line.split(" ", 1) |
|
106 except ValueError: |
|
107 warn(_("cannot parse entry")) |
|
108 continue |
|
109 name = name.strip() |
|
110 if recode: |
|
111 name = recode(name) |
|
112 try: |
|
113 nodebin = bin(nodehex) |
|
114 except TypeError: |
|
115 warn(_("node '%s' is not well formed") % nodehex) |
|
116 continue |
|
117 |
|
118 # update filetags |
|
119 hist = [] |
|
120 if name in filetags: |
|
121 n, hist = filetags[name] |
|
122 hist.append(n) |
|
123 filetags[name] = (nodebin, hist) |
|
124 return filetags |
150 return filetags |
125 |
151 |
126 def _updatetags(filetags, tagtype, alltags, tagtypes): |
152 def _updatetags(filetags, tagtype, alltags, tagtypes): |
127 '''Incorporate the tag info read from one file into the two |
153 '''Incorporate the tag info read from one file into the two |
128 dictionaries, alltags and tagtypes, that contain all tag |
154 dictionaries, alltags and tagtypes, that contain all tag |