Skip to content

Commit c453d2b

Browse files
committed
Add initial signoff and gpg-signing support
Added UI checkboxes to graphically manage global config options regarding automatically signing-off on commits and gpg-enabled signing Signed-off-by: Odin Vex <[email protected]>
1 parent 8569757 commit c453d2b

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

src/dialogs/SettingsDialog.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ class GeneralPanel : public QWidget {
109109
mStoreCredentials =
110110
new QCheckBox(tr("Store credentials in secure storage"), this);
111111

112+
mAutoSignoffCommits =
113+
new QCheckBox(tr("Automatically signoff on commits"), this);
114+
115+
mGpgSignCommits = new QCheckBox(tr("Sign all commits"), this);
116+
117+
mGpgSignPushes = new QCheckBox(tr("Sign all pushes"), this);
118+
119+
mGpgSignTags = new QCheckBox(tr("Sign all tags"), this);
120+
112121
QLabel *privacy = new QLabel(tr("<a href='view'>View privacy policy</a>"));
113122
connect(privacy, &QLabel::linkActivated,
114123
[] { AboutDialog::openSharedInstance(AboutDialog::Privacy); });
@@ -125,6 +134,10 @@ class GeneralPanel : public QWidget {
125134
form->addRow(QString(), mAutoPrune);
126135
form->addRow(tr("Language:"), mNoTranslation);
127136
form->addRow(tr("Credentials:"), mStoreCredentials);
137+
form->addRow(tr("Auto Signoff:"), mAutoSignoffCommits);
138+
form->addRow(tr("Sign Commits:"), mGpgSignCommits);
139+
form->addRow(tr("Sign Pushes:"), mGpgSignPushes);
140+
form->addRow(tr("Sign Tags:"), mGpgSignTags);
128141
form->addRow(QString(), privacy);
129142

130143
#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
@@ -184,6 +197,26 @@ class GeneralPanel : public QWidget {
184197
delete CredentialHelper::instance();
185198
});
186199

200+
connect(mAutoSignoffCommits, &QCheckBox::toggled, [](bool checked) {
201+
git::Config config = git::Config::global();
202+
config.setValue("format.signOff", checked);
203+
});
204+
205+
connect(mGpgSignCommits, &QCheckBox::toggled, [](bool checked) {
206+
git::Config config = git::Config::global();
207+
config.setValue("commit.gpgSign", checked);
208+
});
209+
210+
connect(mGpgSignPushes, &QCheckBox::toggled, [](bool checked) {
211+
git::Config config = git::Config::global();
212+
config.setValue("push.gpgSign", checked);
213+
});
214+
215+
connect(mGpgSignTags, &QCheckBox::toggled, [](bool checked) {
216+
git::Config config = git::Config::global();
217+
config.setValue("tag.gpgSign", checked);
218+
});
219+
187220
connect(mSingleInstance, &QCheckBox::toggled, [](bool checked) {
188221
Settings::instance()->setValue(Setting::Id::AllowSingleInstanceOnly,
189222
checked);
@@ -213,6 +246,10 @@ class GeneralPanel : public QWidget {
213246
settings->value(Setting::Id::DontTranslate).toBool());
214247
mStoreCredentials->setChecked(
215248
settings->value(Setting::Id::StoreCredentials).toBool());
249+
mAutoSignoffCommits->setChecked(config.value<bool>("format.signOff"));
250+
mGpgSignCommits->setChecked(config.value<bool>("commit.gpgSign"));
251+
mGpgSignPushes->setChecked(config.value<bool>("push.gpgSign"));
252+
mGpgSignTags->setChecked(config.value<bool>("tag.gpgSign"));
216253

217254
mSingleInstance->setChecked(
218255
settings->value(Setting::Id::AllowSingleInstanceOnly).toBool());
@@ -229,6 +266,10 @@ class GeneralPanel : public QWidget {
229266
QCheckBox *mAutoPrune;
230267
QCheckBox *mNoTranslation;
231268
QCheckBox *mStoreCredentials;
269+
QCheckBox *mAutoSignoffCommits;
270+
QCheckBox *mGpgSignCommits;
271+
QCheckBox *mGpgSignPushes;
272+
QCheckBox *mGpgSignTags;
232273
QCheckBox *mSingleInstance;
233274
};
234275

src/git/Repository.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "git2/branch.h"
3232
#include "git2/checkout.h"
3333
#include "git2/cherrypick.h"
34+
#include "git2/commit.h"
3435
#include "git2/filter.h"
3536
#include "git2/global.h"
3637
#include "git2/ignore.h"
@@ -52,6 +53,7 @@
5253
#include <QStandardPaths>
5354
#include <QTextCodec>
5455
#include <QVector>
56+
#include <QDebug>
5557

5658
#ifdef Q_OS_UNIX
5759
#include <pwd.h>
@@ -602,11 +604,40 @@ Commit Repository::commit(const Signature &author, const Signature &committer,
602604
if (mergeHead.isValid())
603605
parents.append(mergeHead.commit());
604606

605-
// Create the commit.
607+
// Create the unsigned commit.
608+
git_buf content = GIT_BUF_INIT_CONST(nullptr, 0);
609+
if (git_commit_create_buffer(&content, d->repo, author, committer, 0,
610+
message.toUtf8(), tree, parents.size(),
611+
parents.data())) {
612+
git_buf_dispose(&content);
613+
return Commit();
614+
}
615+
616+
// GPG-Sign content if enabled.
617+
const char *gpg_signature = nullptr; // TODO: Add wrapper and sign content
618+
619+
// Store the commit.
606620
git_oid id;
607-
if (git_commit_create(&id, d->repo, "HEAD", author, committer, 0,
608-
message.toUtf8(), tree, parents.size(), parents.data()))
621+
int error = git_commit_create_with_signature(&id, d->repo, content.ptr,
622+
gpg_signature, "gpgsig");
623+
git_buf_dispose(&content);
624+
if (error) {
625+
return Commit();
626+
}
627+
git_commit *commit = nullptr;
628+
git_commit_lookup(&commit, d->repo, &id);
629+
630+
// Update HEAD.
631+
git_reference *ref = NULL, *ref_new = NULL;
632+
git_reference_resolve(&ref, head());
633+
error = git_reference_create(&ref_new, d->repo, git_reference_name(ref), &id,
634+
1, git_commit_summary(commit));
635+
git_reference_free(ref);
636+
git_reference_free(ref_new);
637+
if (error) {
638+
git_commit_free(commit);
609639
return Commit();
640+
}
610641

611642
// Cleanup merge state.
612643
switch (state()) {
@@ -621,8 +652,6 @@ Commit Repository::commit(const Signature &author, const Signature &committer,
621652
break;
622653
}
623654

624-
git_commit *commit = nullptr;
625-
git_commit_lookup(&commit, d->repo, &id);
626655
emit d->notifier->referenceUpdated(head());
627656
return Commit(commit);
628657
}

test/Setting.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ private slots:
2323

2424
template <class T, typename TId> QStringList settingsKeys() {
2525
QStringList settingsKeys;
26-
foreach (const TId id, ids<TId>()) { settingsKeys.append(T::key(id)); }
26+
foreach (const TId id, ids<TId>()) {
27+
settingsKeys.append(T::key(id));
28+
}
2729
return settingsKeys;
2830
}
2931

0 commit comments

Comments
 (0)