14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Command which looks for unsigned commits by the current user, and signs them.
20
from bzrlib.lazy_import import lazy_import
21
lazy_import(globals(), """
17
"""Command that signs unsigned commits by the current user. """
19
from __future__ import absolute_import
25
revision as _mod_revision,
26
from bzrlib.bzrdir import BzrDir
28
from bzrlib.commands import Command
29
from bzrlib.option import Option
27
from .commands import Command
28
from .option import Option
29
from .i18n import gettext, ngettext
30
from .sixish import text_type
32
33
class cmd_sign_my_commits(Command):
46
help='Don\'t actually sign anything, just print'
47
' the revisions that would be signed.'),
47
help='Don\'t actually sign anything, just print'
48
' the revisions that would be signed.'),
49
50
takes_args = ['location?', 'committer?']
51
52
def run(self, location=None, committer=None, dry_run=False):
52
53
if location is None:
53
bzrdir = BzrDir.open_containing('.')[0]
54
bzrdir = controldir.ControlDir.open_containing('.')[0]
55
56
# Passed in locations should be exact
56
bzrdir = BzrDir.open(location)
57
bzrdir = controldir.ControlDir.open(location)
57
58
branch = bzrdir.open_branch()
58
59
repo = branch.repository
59
branch_config = branch.get_config()
60
branch_config = branch.get_config_stack()
61
62
if committer is None:
62
committer = branch_config.username()
63
committer = branch_config.get('email')
63
64
gpg_strategy = gpg.GPGStrategy(branch_config)
67
with repo.lock_write():
68
graph = repo.get_graph()
68
69
repo.start_write_group()
70
for rev_id in repo.get_ancestry(branch.last_revision())[1:]:
71
for rev_id, parents in graph.iter_ancestry(
72
[branch.last_revision()]):
73
if _mod_revision.is_null(rev_id):
71
78
if repo.has_signature_for_revision_id(rev_id):
73
80
rev = repo.get_revision(rev_id)
76
83
# We have a revision without a signature who has a
77
84
# matching committer, start signing
85
self.outf.write("%s\n" % rev_id)
81
88
repo.sign_revision(rev_id, gpg_strategy)
83
90
repo.abort_write_group()
86
93
repo.commit_write_group()
89
print 'Signed %d revisions' % (count,)
95
ngettext('Signed %d revision.\n', 'Signed %d revisions.\n',
99
class cmd_verify_signatures(Command):
100
__doc__ = """Verify all commit signatures.
102
Verifies that all commits in the branch are signed by known GnuPG keys.
106
Option('acceptable-keys',
107
help='Comma separated list of GPG key patterns which are'
108
' acceptable for verification.',
114
takes_args = ['location?']
116
def run(self, acceptable_keys=None, revision=None, verbose=None,
118
bzrdir = controldir.ControlDir.open_containing(location)[0]
119
branch = bzrdir.open_branch()
120
repo = branch.repository
121
branch_config = branch.get_config_stack()
122
gpg_strategy = gpg.GPGStrategy(branch_config)
124
gpg_strategy.set_acceptable_keys(acceptable_keys)
127
self.outf.write(string + "\n")
129
def write_verbose(string):
130
self.outf.write(" " + string + "\n")
132
self.add_cleanup(repo.lock_read().unlock)
133
# get our list of revisions
135
if revision is not None:
136
if len(revision) == 1:
137
revno, rev_id = revision[0].in_history(branch)
138
revisions.append(rev_id)
139
elif len(revision) == 2:
140
from_revno, from_revid = revision[0].in_history(branch)
141
to_revno, to_revid = revision[1].in_history(branch)
143
to_revno = branch.revno()
144
if from_revno is None or to_revno is None:
145
raise errors.BzrCommandError(
146
gettext('Cannot verify a range of non-revision-history'
148
for revno in range(from_revno, to_revno + 1):
149
revisions.append(branch.get_rev_id(revno))
151
# all revisions by default including merges
152
graph = repo.get_graph()
154
for rev_id, parents in graph.iter_ancestry(
155
[branch.last_revision()]):
156
if _mod_revision.is_null(rev_id):
161
revisions.append(rev_id)
162
count, result, all_verifiable = gpg.bulk_verify_signatures(
163
repo, revisions, gpg_strategy)
165
write(gettext("All commits signed with verifiable keys"))
167
for message in gpg.verbose_valid_message(result):
168
write_verbose(message)
171
write(gpg.valid_commits_message(count))
173
for message in gpg.verbose_valid_message(result):
174
write_verbose(message)
175
write(gpg.expired_commit_message(count))
177
for message in gpg.verbose_expired_key_message(result, repo):
178
write_verbose(message)
179
write(gpg.unknown_key_message(count))
181
for message in gpg.verbose_missing_key_message(result):
182
write_verbose(message)
183
write(gpg.commit_not_valid_message(count))
185
for message in gpg.verbose_not_valid_message(result, repo):
186
write_verbose(message)
187
write(gpg.commit_not_signed_message(count))
189
for message in gpg.verbose_not_signed_message(result, repo):
190
write_verbose(message)