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.
17
"""Command that signs unsigned commits by the current user. """
20
from bzrlib.lazy_import import lazy_import
21
lazy_import(globals(), """
23
repository as _mod_repository,
24
revision as _mod_revision,
26
from bzrlib.bzrdir import BzrDir
28
from bzrlib.commands import Command
29
from bzrlib.option import Option
26
from .commands import Command
27
from .option import Option
28
from .i18n import gettext, ngettext
32
31
class cmd_sign_my_commits(Command):
46
help='Don\'t actually sign anything, just print'
47
' the revisions that would be signed.'),
45
help='Don\'t actually sign anything, just print'
46
' the revisions that would be signed.'),
49
48
takes_args = ['location?', 'committer?']
51
50
def run(self, location=None, committer=None, dry_run=False):
52
51
if location is None:
53
bzrdir = BzrDir.open_containing('.')[0]
52
bzrdir = controldir.ControlDir.open_containing('.')[0]
55
54
# Passed in locations should be exact
56
bzrdir = BzrDir.open(location)
55
bzrdir = controldir.ControlDir.open(location)
57
56
branch = bzrdir.open_branch()
58
57
repo = branch.repository
59
branch_config = branch.get_config()
58
branch_config = branch.get_config_stack()
61
60
if committer is None:
62
committer = branch_config.username()
61
committer = branch_config.get('email')
63
62
gpg_strategy = gpg.GPGStrategy(branch_config)
68
repo.start_write_group()
70
for rev_id in repo.get_ancestry(branch.last_revision())[1:]:
65
with repo.lock_write():
66
graph = repo.get_graph()
67
with _mod_repository.WriteGroup(repo):
68
for rev_id, parents in graph.iter_ancestry(
69
[branch.last_revision()]):
70
if _mod_revision.is_null(rev_id):
71
75
if repo.has_signature_for_revision_id(rev_id):
73
77
rev = repo.get_revision(rev_id)
76
80
# We have a revision without a signature who has a
77
81
# matching committer, start signing
82
self.outf.write("%s\n" % rev_id)
81
85
repo.sign_revision(rev_id, gpg_strategy)
83
repo.abort_write_group()
86
repo.commit_write_group()
89
print 'Signed %d revisions' % (count,)
87
ngettext('Signed %d revision.\n', 'Signed %d revisions.\n',
91
class cmd_verify_signatures(Command):
92
__doc__ = """Verify all commit signatures.
94
Verifies that all commits in the branch are signed by known GnuPG keys.
98
Option('acceptable-keys',
99
help='Comma separated list of GPG key patterns which are'
100
' acceptable for verification.',
106
takes_args = ['location?']
108
def run(self, acceptable_keys=None, revision=None, verbose=None,
110
bzrdir = controldir.ControlDir.open_containing(location)[0]
111
branch = bzrdir.open_branch()
112
repo = branch.repository
113
branch_config = branch.get_config_stack()
114
gpg_strategy = gpg.GPGStrategy(branch_config)
116
gpg_strategy.set_acceptable_keys(acceptable_keys)
119
self.outf.write(string + "\n")
121
def write_verbose(string):
122
self.outf.write(" " + string + "\n")
124
self.add_cleanup(repo.lock_read().unlock)
125
# get our list of revisions
127
if revision is not None:
128
if len(revision) == 1:
129
revno, rev_id = revision[0].in_history(branch)
130
revisions.append(rev_id)
131
elif len(revision) == 2:
132
from_revno, from_revid = revision[0].in_history(branch)
133
to_revno, to_revid = revision[1].in_history(branch)
135
to_revno = branch.revno()
136
if from_revno is None or to_revno is None:
137
raise errors.CommandError(
138
gettext('Cannot verify a range of non-revision-history'
140
for revno in range(from_revno, to_revno + 1):
141
revisions.append(branch.get_rev_id(revno))
143
# all revisions by default including merges
144
graph = repo.get_graph()
146
for rev_id, parents in graph.iter_ancestry(
147
[branch.last_revision()]):
148
if _mod_revision.is_null(rev_id):
153
revisions.append(rev_id)
154
count, result, all_verifiable = gpg.bulk_verify_signatures(
155
repo, revisions, gpg_strategy)
157
write(gettext("All commits signed with verifiable keys"))
159
for message in gpg.verbose_valid_message(result):
160
write_verbose(message)
163
write(gpg.valid_commits_message(count))
165
for message in gpg.verbose_valid_message(result):
166
write_verbose(message)
167
write(gpg.expired_commit_message(count))
169
for message in gpg.verbose_expired_key_message(result, repo):
170
write_verbose(message)
171
write(gpg.unknown_key_message(count))
173
for message in gpg.verbose_missing_key_message(result):
174
write_verbose(message)
175
write(gpg.commit_not_valid_message(count))
177
for message in gpg.verbose_not_valid_message(result, repo):
178
write_verbose(message)
179
write(gpg.commit_not_signed_message(count))
181
for message in gpg.verbose_not_signed_message(result, repo):
182
write_verbose(message)