Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
### vX.X.X - 2026-01-07 (DEV)

Bug Fix and Feature release

#### Added

* Add more information about the credential stores to give the user the possibility to easily see the tradeoffs of every credential store

----

### v2.0.0 - 2025-11-30

Bug Fix and Feature release
Expand Down
9 changes: 8 additions & 1 deletion rsrc/linux/com.github.Murmele.Gittyup.appdata.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
<project_license>MIT</project_license>
<name>Gittyup</name>
<summary>Graphical Git client designed to help you understand and manage your source code history</summary>
<developer_name>Gittyup Community</developer_name>
<developer>
<id>@GITTYUP_IDENTIFIER@</id>
<name>Gittyup Community</name>
</developer>

<description>
<p>Graphical Git client designed to help you understand and manage your source code history</p>
Expand All @@ -22,6 +25,10 @@
</ul>
</description>

<categories>
<category>Development</category>
</categories>

<launchable type="desktop-id">@GITTYUP_IDENTIFIER@.desktop</launchable>

<screenshots>
Expand Down
37 changes: 27 additions & 10 deletions src/cred/CredentialHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ namespace {
const QString kLogKey = "credential/log";

const QString cacheStoreName = "cache";
const QString storeStoreName = "store";
const QString storeStoreName = "git-credential-store";
const QString storeStoreNameOld = "store";
const QString osxKeyChainStoreName = "osxkeychain";
const QString winCredStoreName = "wincred";
const QString libSecretStoreName = "libsecret";
Expand All @@ -41,7 +42,8 @@ CredentialHelper *CredentialHelper::instance() {
if (isHelperValid(helperName)) {
if (helperName == cacheStoreName) {
instance = new Cache;
} else if (helperName == storeStoreName) {
} else if (helperName == storeStoreName ||
helperName == storeStoreNameOld) {
auto path =
QString::fromLocal8Bit(qgetenv("HOME") + "/.git-credentials");
instance = new Store(path);
Expand All @@ -61,22 +63,37 @@ bool CredentialHelper::isHelperValid(const QString &name) {
return !name.isEmpty();
}

QStringList CredentialHelper::getAvailableHelperNames() {
QStringList list;
list.append(cacheStoreName);
list.append(storeStoreName);
QVector<CredentialHelper::HelperInformation>
CredentialHelper::getAvailableHelperInformation() {
QVector<HelperInformation> list;
list.append(HelperInformation(
cacheStoreName, tr("Caching the credentials in the RAM. Required to "
"enter credentials on every startup")));
list.append(HelperInformation(
storeStoreName, tr("Storing the credentials unencrypted on disk, "
"protected only by filesystem permissions <a "
"href=\"https://git-scm.com/docs/"
"git-credential-store\">git-credential-store</a>")));
#if defined(Q_OS_MAC)
list.append(osxKeyChainStoreName);
list.append(
HelperInformation(osxKeyChainStoreName, tr("MacOS credential manager")));
#elif defined(Q_OS_WIN)
list.append(winCredStoreName);
list.append(
HelperInformation(winCredStoreName, tr("Windows credential manager")));
#else
QLibrary lib("secret-1", 0);
if (lib.load()) {
list.append(libSecretStoreName);
list.append(HelperInformation(libSecretStoreName,
tr("Secret Service D-Bus client library")));
}
// libsecret replaces libgnome-keyring.
QLibrary lib2(gnomeKeyringStoreName, 0);
if (lib2.load()) {
list.append(gnomeKeyringStoreName);
list.append(HelperInformation(
gnomeKeyringStoreName,
tr("Prefer <a "
"href=\"https://wiki.gnome.org/Projects/Libsecret\">libsecret</a> "
"over gnome-keyring if available")));
}
#endif
return list;
Expand Down
9 changes: 8 additions & 1 deletion src/cred/CredentialHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ class CredentialHelper : public QObject {
static bool isLoggingEnabled();
static void setLoggingEnabled(bool enabled);

static QStringList getAvailableHelperNames();
struct HelperInformation {
HelperInformation(const QString &name, const QString &description)
: name(name), description(description) {}
QString name;
QString description;
};

static QVector<HelperInformation> getAvailableHelperInformation();
static bool isHelperValid(const QString &name);

protected:
Expand Down
6 changes: 6 additions & 0 deletions src/cred/Store.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
#include "CredentialHelper.h"
#include <QMap>

/*!
* \brief The Store class
* git-credential-store
* https://git-scm.com/docs/git-credential-store
* Storing the credentials encoded but unencrypted on disk
*/
class Store : public CredentialHelper {
public:
Store(const QString &path);
Expand Down
25 changes: 22 additions & 3 deletions src/dialogs/SettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <QStackedWidget>
#include <QStandardItemModel>
#include <QToolBar>
#include <QMessageBox>

#ifdef Q_OS_UNIX
#include "cli/Installer.h"
Expand Down Expand Up @@ -124,6 +125,8 @@ class GeneralPanel : public QWidget {
connect(privacy, &QLabel::linkActivated,
[] { AboutDialog::openSharedInstance(AboutDialog::Privacy); });

mCredentialStoresDescription = new QLabel();

QFormLayout *form = new QFormLayout;
form->addRow(tr("User name:"), mName);
form->addRow(tr("User email:"), mEmail);
Expand All @@ -135,6 +138,8 @@ class GeneralPanel : public QWidget {
form->addRow(tr("Language:"), mLanguages);
form->addRow(tr("Credentials:"), mStoreCredentials);
form->addRow(tr("Credential store type:"), mAvailableStores);
form->addRow(tr("Available Credential stores:"),
mCredentialStoresDescription);
form->addRow(QString(), privacy);

mSingleInstance =
Expand Down Expand Up @@ -260,12 +265,25 @@ class GeneralPanel : public QWidget {

auto currentHelper = config.value<QString>("credential.helper");
auto checked = CredentialHelper::isHelperValid(currentHelper);
if (!checked) {
QMessageBox msg(QMessageBox::Information, tr("No credential store set"),
tr("No credential store is set. Go to the application "
"settings to set the desired credential store"));
msg.exec();
}
mStoreCredentials->setChecked(checked);

auto availableHelpers = CredentialHelper::getAvailableHelperNames();
foreach (auto helper, availableHelpers) {
mAvailableStores->addItem(helper);
QString info = tr("") + "<table>";
for (const auto &helper :
CredentialHelper::getAvailableHelperInformation()) {
info += QStringLiteral("<tr><td><b>%1</b></td><td>%2</td><td>")
.arg(helper.name, helper.description);
mAvailableStores->addItem(helper.name);
}
info += "</table>";
mCredentialStoresDescription->setText(info);
mAvailableStores->setToolTip(tr("Available Credential stores"));
mAvailableStores->setWhatsThis(info);
mAvailableStores->setEditable(true);
mAvailableStores->setCurrentText(currentHelper);

Expand All @@ -286,6 +304,7 @@ class GeneralPanel : public QWidget {
QComboBox *mLanguages;
QCheckBox *mStoreCredentials;
QComboBox *mAvailableStores;
QLabel *mCredentialStoresDescription;
QCheckBox *mSingleInstance;
};

Expand Down
Loading