diff --git a/src/dialogs/SettingsDialog.cpp b/src/dialogs/SettingsDialog.cpp index 6fe3eb8fc..ea56ae3cf 100644 --- a/src/dialogs/SettingsDialog.cpp +++ b/src/dialogs/SettingsDialog.cpp @@ -109,6 +109,15 @@ class GeneralPanel : public QWidget { mStoreCredentials = new QCheckBox(tr("Store credentials in secure storage"), this); + mAutoSignoffCommits = + new QCheckBox(tr("Automatically signoff on commits"), this); + + mGpgSignCommits = new QCheckBox(tr("Sign all commits"), this); + + mGpgSignPushes = new QCheckBox(tr("Sign all pushes"), this); + + mGpgSignTags = new QCheckBox(tr("Sign all tags"), this); + QLabel *privacy = new QLabel(tr("View privacy policy")); connect(privacy, &QLabel::linkActivated, [] { AboutDialog::openSharedInstance(AboutDialog::Privacy); }); @@ -125,6 +134,10 @@ class GeneralPanel : public QWidget { form->addRow(QString(), mAutoPrune); form->addRow(tr("Language:"), mNoTranslation); form->addRow(tr("Credentials:"), mStoreCredentials); + form->addRow(tr("Auto Signoff:"), mAutoSignoffCommits); + form->addRow(tr("Sign Commits:"), mGpgSignCommits); + form->addRow(tr("Sign Pushes:"), mGpgSignPushes); + form->addRow(tr("Sign Tags:"), mGpgSignTags); form->addRow(QString(), privacy); #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) @@ -184,6 +197,26 @@ class GeneralPanel : public QWidget { delete CredentialHelper::instance(); }); + connect(mAutoSignoffCommits, &QCheckBox::toggled, [](bool checked) { + git::Config config = git::Config::global(); + config.setValue("format.signOff", checked); + }); + + connect(mGpgSignCommits, &QCheckBox::toggled, [](bool checked) { + git::Config config = git::Config::global(); + config.setValue("commit.gpgSign", checked); + }); + + connect(mGpgSignPushes, &QCheckBox::toggled, [](bool checked) { + git::Config config = git::Config::global(); + config.setValue("push.gpgSign", checked); + }); + + connect(mGpgSignTags, &QCheckBox::toggled, [](bool checked) { + git::Config config = git::Config::global(); + config.setValue("tag.gpgSign", checked); + }); + connect(mSingleInstance, &QCheckBox::toggled, [](bool checked) { Settings::instance()->setValue(Setting::Id::AllowSingleInstanceOnly, checked); @@ -213,6 +246,10 @@ class GeneralPanel : public QWidget { settings->value(Setting::Id::DontTranslate).toBool()); mStoreCredentials->setChecked( settings->value(Setting::Id::StoreCredentials).toBool()); + mAutoSignoffCommits->setChecked(config.value("format.signOff")); + mGpgSignCommits->setChecked(config.value("commit.gpgSign")); + mGpgSignPushes->setChecked(config.value("push.gpgSign")); + mGpgSignTags->setChecked(config.value("tag.gpgSign")); mSingleInstance->setChecked( settings->value(Setting::Id::AllowSingleInstanceOnly).toBool()); @@ -229,6 +266,10 @@ class GeneralPanel : public QWidget { QCheckBox *mAutoPrune; QCheckBox *mNoTranslation; QCheckBox *mStoreCredentials; + QCheckBox *mAutoSignoffCommits; + QCheckBox *mGpgSignCommits; + QCheckBox *mGpgSignPushes; + QCheckBox *mGpgSignTags; QCheckBox *mSingleInstance; }; diff --git a/src/git/Repository.cpp b/src/git/Repository.cpp index cd0d9692b..eeab279cf 100644 --- a/src/git/Repository.cpp +++ b/src/git/Repository.cpp @@ -31,6 +31,7 @@ #include "git2/branch.h" #include "git2/checkout.h" #include "git2/cherrypick.h" +#include "git2/commit.h" #include "git2/filter.h" #include "git2/global.h" #include "git2/ignore.h" @@ -52,6 +53,7 @@ #include #include #include +#include #ifdef Q_OS_UNIX #include @@ -602,11 +604,40 @@ Commit Repository::commit(const Signature &author, const Signature &committer, if (mergeHead.isValid()) parents.append(mergeHead.commit()); - // Create the commit. + // Create the unsigned commit. + git_buf content = GIT_BUF_INIT_CONST(nullptr, 0); + if (git_commit_create_buffer(&content, d->repo, author, committer, 0, + message.toUtf8(), tree, parents.size(), + parents.data())) { + git_buf_dispose(&content); + return Commit(); + } + + // GPG-Sign content if enabled. + const char *gpg_signature = nullptr; // TODO: Add wrapper and sign content + + // Store the commit. git_oid id; - if (git_commit_create(&id, d->repo, "HEAD", author, committer, 0, - message.toUtf8(), tree, parents.size(), parents.data())) + int error = git_commit_create_with_signature(&id, d->repo, content.ptr, + gpg_signature, "gpgsig"); + git_buf_dispose(&content); + if (error) { + return Commit(); + } + git_commit *commit = nullptr; + git_commit_lookup(&commit, d->repo, &id); + + // Update HEAD. + git_reference *ref = NULL, *ref_new = NULL; + git_reference_resolve(&ref, head()); + error = git_reference_create(&ref_new, d->repo, git_reference_name(ref), &id, + 1, git_commit_summary(commit)); + git_reference_free(ref); + git_reference_free(ref_new); + if (error) { + git_commit_free(commit); return Commit(); + } // Cleanup merge state. switch (state()) { @@ -621,8 +652,6 @@ Commit Repository::commit(const Signature &author, const Signature &committer, break; } - git_commit *commit = nullptr; - git_commit_lookup(&commit, d->repo, &id); emit d->notifier->referenceUpdated(head()); return Commit(commit); } diff --git a/test/Setting.cpp b/test/Setting.cpp index 0a146bbad..125b0cb2b 100644 --- a/test/Setting.cpp +++ b/test/Setting.cpp @@ -23,7 +23,9 @@ private slots: template QStringList settingsKeys() { QStringList settingsKeys; - foreach (const TId id, ids()) { settingsKeys.append(T::key(id)); } + foreach (const TId id, ids()) { + settingsKeys.append(T::key(id)); + } return settingsKeys; }