153 ln += 1 |
158 ln += 1 |
154 |
159 |
155 # read the heads |
160 # read the heads |
156 fl = repo.file(b".hgsigs") |
161 fl = repo.file(b".hgsigs") |
157 for r in reversed(fl.heads()): |
162 for r in reversed(fl.heads()): |
158 fn = b".hgsigs|%s" % hgnode.short(r) |
163 fn = b".hgsigs|%s" % short(r) |
159 for item in parsefile(fl.read(r).splitlines(), fn): |
164 for item in parsefile(fl.read(r).splitlines(), fn): |
160 yield item |
165 yield item |
161 try: |
166 try: |
162 # read local signatures |
167 # read local signatures |
163 fn = b"localsigs" |
168 fn = b"localsigs" |
170 def getkeys(ui, repo, mygpg, sigdata, context): |
175 def getkeys(ui, repo, mygpg, sigdata, context): |
171 """get the keys who signed a data""" |
176 """get the keys who signed a data""" |
172 fn, ln = context |
177 fn, ln = context |
173 node, version, sig = sigdata |
178 node, version, sig = sigdata |
174 prefix = b"%s:%d" % (fn, ln) |
179 prefix = b"%s:%d" % (fn, ln) |
175 node = hgnode.bin(node) |
180 node = bin(node) |
176 |
181 |
177 data = node2txt(repo, node, version) |
182 data = node2txt(repo, node, version) |
178 sig = binascii.a2b_base64(sig) |
183 sig = binascii.a2b_base64(sig) |
179 keys = mygpg.verify(data, sig) |
184 keys = mygpg.verify(data, sig) |
180 |
185 |
221 continue |
226 continue |
222 revs.setdefault(r, []) |
227 revs.setdefault(r, []) |
223 revs[r].extend(keys) |
228 revs[r].extend(keys) |
224 for rev in sorted(revs, reverse=True): |
229 for rev in sorted(revs, reverse=True): |
225 for k in revs[rev]: |
230 for k in revs[rev]: |
226 r = b"%5d:%s" % (rev, hgnode.hex(repo.changelog.node(rev))) |
231 r = b"%5d:%s" % (rev, hex(repo.changelog.node(rev))) |
227 ui.write(b"%-30s %s\n" % (keystr(ui, k), r)) |
232 ui.write(b"%-30s %s\n" % (keystr(ui, k), r)) |
228 |
233 |
229 |
234 |
230 @command(b"sigcheck", [], _(b'hg sigcheck REV'), helpcategory=_HELP_CATEGORY) |
235 @command(b"sigcheck", [], _(b'hg sigcheck REV'), helpcategory=_HELP_CATEGORY) |
231 def sigcheck(ui, repo, rev): |
236 def sigcheck(ui, repo, rev): |
232 """verify all the signatures there may be for a particular revision""" |
237 """verify all the signatures there may be for a particular revision""" |
233 mygpg = newgpg(ui) |
238 mygpg = newgpg(ui) |
234 rev = repo.lookup(rev) |
239 rev = repo.lookup(rev) |
235 hexrev = hgnode.hex(rev) |
240 hexrev = hex(rev) |
236 keys = [] |
241 keys = [] |
237 |
242 |
238 for data, context in sigwalk(repo): |
243 for data, context in sigwalk(repo): |
239 node, version, sig = data |
244 node, version, sig = data |
240 if node == hexrev: |
245 if node == hexrev: |
241 k = getkeys(ui, repo, mygpg, data, context) |
246 k = getkeys(ui, repo, mygpg, data, context) |
242 if k: |
247 if k: |
243 keys.extend(k) |
248 keys.extend(k) |
244 |
249 |
245 if not keys: |
250 if not keys: |
246 ui.write(_(b"no valid signature for %s\n") % hgnode.short(rev)) |
251 ui.write(_(b"no valid signature for %s\n") % short(rev)) |
247 return |
252 return |
248 |
253 |
249 # print summary |
254 # print summary |
250 ui.write(_(b"%s is signed by:\n") % hgnode.short(rev)) |
255 ui.write(_(b"%s is signed by:\n") % short(rev)) |
251 for key in keys: |
256 for key in keys: |
252 ui.write(b" %s\n" % keystr(ui, key)) |
257 ui.write(b" %s\n" % keystr(ui, key)) |
253 |
258 |
254 |
259 |
255 def keystr(ui, key): |
260 def keystr(ui, key): |
307 opts[b'date'] = dateutil.parsedate(date) |
312 opts[b'date'] = dateutil.parsedate(date) |
308 |
313 |
309 if revs: |
314 if revs: |
310 nodes = [repo.lookup(n) for n in revs] |
315 nodes = [repo.lookup(n) for n in revs] |
311 else: |
316 else: |
312 nodes = [ |
317 nodes = [node for node in repo.dirstate.parents() if node != nullid] |
313 node for node in repo.dirstate.parents() if node != hgnode.nullid |
|
314 ] |
|
315 if len(nodes) > 1: |
318 if len(nodes) > 1: |
316 raise error.Abort( |
319 raise error.Abort( |
317 _(b'uncommitted merge - please provide a specific revision') |
320 _(b'uncommitted merge - please provide a specific revision') |
318 ) |
321 ) |
319 if not nodes: |
322 if not nodes: |
320 nodes = [repo.changelog.tip()] |
323 nodes = [repo.changelog.tip()] |
321 |
324 |
322 for n in nodes: |
325 for n in nodes: |
323 hexnode = hgnode.hex(n) |
326 hexnode = hex(n) |
324 ui.write( |
327 ui.write(_(b"signing %d:%s\n") % (repo.changelog.rev(n), short(n))) |
325 _(b"signing %d:%s\n") % (repo.changelog.rev(n), hgnode.short(n)) |
|
326 ) |
|
327 # build data |
328 # build data |
328 data = node2txt(repo, n, sigver) |
329 data = node2txt(repo, n, sigver) |
329 sig = mygpg.sign(data) |
330 sig = mygpg.sign(data) |
330 if not sig: |
331 if not sig: |
331 raise error.Abort(_(b"error while signing")) |
332 raise error.Abort(_(b"error while signing")) |
358 |
359 |
359 message = opts[b'message'] |
360 message = opts[b'message'] |
360 if not message: |
361 if not message: |
361 # we don't translate commit messages |
362 # we don't translate commit messages |
362 message = b"\n".join( |
363 message = b"\n".join( |
363 [ |
364 [b"Added signature for changeset %s" % short(n) for n in nodes] |
364 b"Added signature for changeset %s" % hgnode.short(n) |
|
365 for n in nodes |
|
366 ] |
|
367 ) |
365 ) |
368 try: |
366 try: |
369 editor = cmdutil.getcommiteditor( |
367 editor = cmdutil.getcommiteditor( |
370 editform=b'gpg.sign', **pycompat.strkwargs(opts) |
368 editform=b'gpg.sign', **pycompat.strkwargs(opts) |
371 ) |
369 ) |