Merge pull request #780 from Murmele/singleParentFilter

Single parent filter
This commit is contained in:
Murmele 2024-06-14 08:05:22 +02:00 committed by GitHub
commit 13032c3039
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 97 additions and 43 deletions

View File

@ -1,6 +1,16 @@
### v1.4.0 - 2024-04-24 (DEV) ### vX.X.X - 2024-06-13 (DEV)
Description Bug Fix and Feature release
#### Added
* Add commit filter to show only the first parent in the commit list view
----
### v1.4.0 - 2024-04-24
Bug Fix and Feature release
#### Added #### Added

View File

@ -200,7 +200,7 @@ QList<Reference> Commit::refs() const {
return refs; return refs;
} }
RevWalk Commit::walker(int sort) const { RevWalk Commit::walker(int sort, bool firstCommitOnly) const {
git_revwalk *revwalk = nullptr; git_revwalk *revwalk = nullptr;
if (git_revwalk_new(&revwalk, git_object_owner(d.data()))) if (git_revwalk_new(&revwalk, git_object_owner(d.data())))
return RevWalk(); return RevWalk();
@ -209,6 +209,9 @@ RevWalk Commit::walker(int sort) const {
if (git_revwalk_push(revwalk, git_object_id(d.data()))) if (git_revwalk_push(revwalk, git_object_id(d.data())))
return RevWalk(); return RevWalk();
if (firstCommitOnly && git_revwalk_simplify_first_parent(revwalk))
return RevWalk();
git_revwalk_sorting(revwalk, sort); git_revwalk_sorting(revwalk, sort);
return walker; return walker;

View File

@ -56,7 +56,7 @@ public:
QList<Reference> refs() const; QList<Reference> refs() const;
// Create a walker starting from this commit. // Create a walker starting from this commit.
RevWalk walker(int sort = GIT_SORT_NONE) const; RevWalk walker(int sort = GIT_SORT_NONE, bool firstCommitOnly = false) const;
// Calculate difference in commits between this and the given commit. // Calculate difference in commits between this and the given commit.
// Commits that have diverged calculate the distance to a common base. // Commits that have diverged calculate the distance to a common base.

View File

@ -111,13 +111,15 @@ template <> void Config::setValue<QString>(const QString &, const QString &);
template <typename T> template <typename T>
T Config::value(const QString &key, const T &defaultValue) const { T Config::value(const QString &key, const T &defaultValue) const {
static_assert(sizeof(T) == 0, "no specialization found"); static_assert(sizeof(T) == 0, "no specialization found. Please implement "
"specialization for this type!");
return T(); return T();
} }
template <typename T> template <typename T>
void Config::setValue(const QString &key, const T &value) { void Config::setValue(const QString &key, const T &value) {
static_assert(sizeof(T) == 0, "no specialization found"); static_assert(sizeof(T) == 0, "no specialization found. Please implement "
"specialization for this type!");
} }
} // namespace git } // namespace git

View File

@ -73,9 +73,9 @@ QString Reference::qualifiedName() const {
return git_reference_name(d.data()); return git_reference_name(d.data());
} }
RevWalk Reference::walker(int sort) const { RevWalk Reference::walker(int sort, bool firstCommitOnly) const {
Commit commit = target(); Commit commit = target();
return commit.isValid() ? commit.walker(sort) : RevWalk(); return commit.isValid() ? commit.walker(sort, firstCommitOnly) : RevWalk();
} }
int Reference::difference(const Reference &ref) const { int Reference::difference(const Reference &ref) const {

View File

@ -47,7 +47,7 @@ public:
QString qualifiedName() const; QString qualifiedName() const;
// Create a walker over the referenced commit. // Create a walker over the referenced commit.
RevWalk walker(int sort = GIT_SORT_NONE) const; RevWalk walker(int sort = GIT_SORT_NONE, bool firstCommitOnly = false) const;
// Calculate difference in commits between this and the given reference. // Calculate difference in commits between this and the given reference.
// References that have diverged calculate the distance to a common base. // References that have diverged calculate the distance to a common base.

View File

@ -53,7 +53,8 @@ add_library(
TreeProxy.cpp TreeProxy.cpp
TreeView.cpp TreeView.cpp
TreeWidget.cpp TreeWidget.cpp
ViewDelegate.cpp) ViewDelegate.cpp
ConfigKeys.cpp)
target_compile_definitions(ui PRIVATE BUILD_DESCRIPTION="${BUILD_DESCRIPTION}") target_compile_definitions(ui PRIVATE BUILD_DESCRIPTION="${BUILD_DESCRIPTION}")

View File

@ -14,6 +14,7 @@
#include "ProgressIndicator.h" #include "ProgressIndicator.h"
#include "RepoView.h" #include "RepoView.h"
#include "Debug.h" #include "Debug.h"
#include "ConfigKeys.h"
#include "app/Application.h" #include "app/Application.h"
#include "conf/Settings.h" #include "conf/Settings.h"
#include "dialogs/MergeDialog.h" #include "dialogs/MergeDialog.h"
@ -208,7 +209,8 @@ public:
sort |= GIT_SORT_TOPOLOGICAL; sort |= GIT_SORT_TOPOLOGICAL;
} }
mWalker = mRef.walker(sort); mWalker = mRef.walker(
sort, mRefsFilter == CommitList::RefsFilter::SelectedRefIgnoreMerge);
if (mRef.isLocalBranch()) { if (mRef.isLocalBranch()) {
// Add the upstream branch. // Add the upstream branch.
if (git::Branch upstream = git::Branch(mRef).upstream()) if (git::Branch upstream = git::Branch(mRef).upstream())
@ -221,7 +223,7 @@ public:
mWalker.push(mergeHead); mWalker.push(mergeHead);
} }
if (mRefsAll) { if (mRefsFilter == CommitList::RefsFilter::AllRefs) {
foreach (const git::Reference ref, mRepo.refs()) { foreach (const git::Reference ref, mRepo.refs()) {
if (!ref.isStash()) if (!ref.isStash())
mWalker.push(ref); mWalker.push(ref);
@ -237,10 +239,11 @@ public:
void resetSettings(bool walk = false) { void resetSettings(bool walk = false) {
git::Config config = mRepo.appConfig(); git::Config config = mRepo.appConfig();
mRefsAll = config.value<bool>("commit.refs.all", true); mRefsFilter = static_cast<CommitList::RefsFilter>(config.value<int>(
mSortDate = config.value<bool>("commit.sort.date", true); ConfigKeys::kRefsKey, (int)CommitList::RefsFilter::AllRefs));
mShowCleanStatus = config.value<bool>("commit.show.status", true); mSortDate = config.value<bool>(ConfigKeys::kSortKey, true);
mGraphVisible = config.value<bool>("commit.graph.visible", true); mShowCleanStatus = config.value<bool>(ConfigKeys::kStatusKey, true);
mGraphVisible = config.value<bool>(ConfigKeys::kGraphKey, true);
if (walk) if (walk)
resetWalker(); resetWalker();
@ -273,6 +276,9 @@ public:
// FIXME: Mark commits that point to existing parent? // FIXME: Mark commits that point to existing parent?
if (indexOf(parent) < 0 && !contains(parent, rows)) if (indexOf(parent) < 0 && !contains(parent, rows))
replacements.append(parent); replacements.append(parent);
if (mRefsFilter == CommitList::RefsFilter::SelectedRefIgnoreMerge) {
break;
}
} }
// Set parents for next row. // Set parents for next row.
@ -557,7 +563,7 @@ private:
// walker settings // walker settings
bool mSuppressResetWalker{false}; bool mSuppressResetWalker{false};
bool mRefsAll = true; CommitList::RefsFilter mRefsFilter{CommitList::RefsFilter::AllRefs};
bool mSortDate = true; bool mSortDate = true;
bool mShowCleanStatus = true; bool mShowCleanStatus = true;
bool mGraphVisible = true; bool mGraphVisible = true;

View File

@ -25,6 +25,11 @@ class CommitList : public QListView {
public: public:
enum Role { DiffRole = Qt::UserRole, CommitRole, GraphRole, GraphColorRole }; enum Role { DiffRole = Qt::UserRole, CommitRole, GraphRole, GraphColorRole };
enum class RefsFilter {
AllRefs,
SelectedRef,
SelectedRefIgnoreMerge,
};
CommitList(Index *index, QWidget *parent = nullptr); CommitList(Index *index, QWidget *parent = nullptr);

View File

@ -8,8 +8,10 @@
// //
#include "CommitToolBar.h" #include "CommitToolBar.h"
#include "CommitList.h"
#include "ContextMenuButton.h" #include "ContextMenuButton.h"
#include "RepoView.h" #include "RepoView.h"
#include "ConfigKeys.h"
#include "conf/Settings.h" #include "conf/Settings.h"
#include "git/Config.h" #include "git/Config.h"
#include <QApplication> #include <QApplication>
@ -22,10 +24,6 @@
namespace { namespace {
const QString kRefsKey = "commit.refs.all";
const QString kSortKey = "commit.sort.date";
const QString kGraphKey = "commit.graph.visible";
const QString kStatusKey = "commit.show.status";
const QString kStyleSheet = "QToolBar {" const QString kStyleSheet = "QToolBar {"
" border: none" " border: none"
"}" "}"
@ -34,17 +32,16 @@ const QString kStyleSheet = "QToolBar {"
" border-radius: 4px;" " border-radius: 4px;"
" padding-right: 12px" " padding-right: 12px"
"}"; "}";
template <typename T> struct SettingsEntry {
struct SettingsEntry {
QString key; QString key;
bool value; T value;
}; };
using SettingsMap = QMap<QString, SettingsEntry>; template <typename T> using SettingsMap = QMap<QString, SettingsEntry<T>>;
class ToolButton : public QToolButton { template <typename T> class ToolButton : public QToolButton {
public: public:
ToolButton(const SettingsMap &map, CommitToolBar *parent) ToolButton(const SettingsMap<T> &map, CommitToolBar *parent, T defaultValue)
: QToolButton(parent) { : QToolButton(parent) {
setPopupMode(QToolButton::InstantPopup); setPopupMode(QToolButton::InstantPopup);
@ -58,8 +55,8 @@ public:
action->setCheckable(true); action->setCheckable(true);
actions->addAction(action); actions->addAction(action);
const SettingsEntry &entry = map.value(key); const SettingsEntry<T> &entry = map.value(key);
if (config.value<bool>(entry.key, true) == entry.value) { if (config.value<T>(entry.key, defaultValue) == entry.value) {
action->setChecked(true); action->setChecked(true);
setText(action->text()); setText(action->text());
} }
@ -119,15 +116,22 @@ CommitToolBar::CommitToolBar(QWidget *parent) : QToolBar(parent) {
setStyleSheet(kStyleSheet); setStyleSheet(kStyleSheet);
setToolButtonStyle(Qt::ToolButtonTextOnly); setToolButtonStyle(Qt::ToolButtonTextOnly);
SettingsMap refsMap; SettingsMap<int> refsMap;
refsMap.insert(tr("Show All Branches"), {kRefsKey, true}); refsMap.insert(tr("Show All Branches"),
refsMap.insert(tr("Show Selected Branch"), {kRefsKey, false}); {ConfigKeys::kRefsKey, (int)CommitList::RefsFilter::AllRefs});
addWidget(new ToolButton(refsMap, this)); refsMap.insert(
tr("Show Selected Branch"),
{ConfigKeys::kRefsKey, (int)CommitList::RefsFilter::SelectedRef});
refsMap.insert(tr("Show Selected Branch, First Parent Only"),
{ConfigKeys::kRefsKey,
(int)CommitList::RefsFilter::SelectedRefIgnoreMerge});
addWidget(
new ToolButton<int>(refsMap, this, (int)CommitList::RefsFilter::AllRefs));
SettingsMap sortMap; SettingsMap<bool> sortMap;
sortMap.insert(tr("Sort by Date"), {kSortKey, true}); sortMap.insert(tr("Sort by Date"), {ConfigKeys::kSortKey, true});
sortMap.insert(tr("Sort Topologically"), {kSortKey, false}); sortMap.insert(tr("Sort Topologically"), {ConfigKeys::kSortKey, false});
addWidget(new ToolButton(sortMap, this)); addWidget(new ToolButton(sortMap, this, true));
QWidget *spacer = new QWidget(this); QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
@ -145,20 +149,20 @@ CommitToolBar::CommitToolBar(QWidget *parent) : QToolBar(parent) {
QAction *graph = menu->addAction(tr("Show Graph")); QAction *graph = menu->addAction(tr("Show Graph"));
graph->setCheckable(true); graph->setCheckable(true);
graph->setChecked(config.value<bool>(kGraphKey, true)); graph->setChecked(config.value<bool>(ConfigKeys::kGraphKey, true));
connect(graph, &QAction::triggered, [this](bool checked) { connect(graph, &QAction::triggered, [this](bool checked) {
RepoView *view = RepoView::parentView(this); RepoView *view = RepoView::parentView(this);
git::Config config = view->repo().appConfig(); git::Config config = view->repo().appConfig();
config.setValue(kGraphKey, checked); config.setValue(ConfigKeys::kGraphKey, checked);
emit settingsChanged(); emit settingsChanged();
}); });
QAction *status = menu->addAction(tr("Show Clean Status")); QAction *status = menu->addAction(tr("Show Clean Status"));
status->setCheckable(true); status->setCheckable(true);
status->setChecked(config.value<bool>(kStatusKey, true)); status->setChecked(config.value<bool>(ConfigKeys::kStatusKey, true));
connect(status, &QAction::triggered, [this](bool checked) { connect(status, &QAction::triggered, [this](bool checked) {
RepoView *view = RepoView::parentView(this); RepoView *view = RepoView::parentView(this);
view->repo().appConfig().setValue(kStatusKey, checked); view->repo().appConfig().setValue(ConfigKeys::kStatusKey, checked);
emit settingsChanged(); emit settingsChanged();
}); });

9
src/ui/ConfigKeys.cpp Normal file
View File

@ -0,0 +1,9 @@
#include <QString>
#include "ConfigKeys.h"
namespace ConfigKeys {
const QString kRefsKey = "commit.refs.all";
const QString kSortKey = "commit.sort.date";
const QString kGraphKey = "commit.graph.visible";
const QString kStatusKey = "commit.show.status";
} // namespace ConfigKeys

13
src/ui/ConfigKeys.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef CONFIGKEYS_H
#define CONFIGKEYS_H
#include <QString>
namespace ConfigKeys {
extern const QString kRefsKey;
extern const QString kSortKey;
extern const QString kGraphKey;
extern const QString kStatusKey;
} // namespace ConfigKeys
#endif // CONFIGKEYS_H

View File

@ -9,6 +9,7 @@
#include "ReferenceWidget.h" #include "ReferenceWidget.h"
#include "ExpandButton.h" #include "ExpandButton.h"
#include "ConfigKeys.h"
#include "git/Config.h" #include "git/Config.h"
#include "git/Reference.h" #include "git/Reference.h"
#include "git/Repository.h" #include "git/Repository.h"
@ -88,7 +89,7 @@ public:
QItemSelectionModel::SelectionFlags command) override { QItemSelectionModel::SelectionFlags command) override {
QModelIndex current = index; QModelIndex current = index;
git::Reference head = mRepo.head(); git::Reference head = mRepo.head();
bool all = mRepo.appConfig().value<bool>("commit.refs.all", true); bool all = mRepo.appConfig().value<bool>(ConfigKeys::kRefsKey, true);
git::Reference ref = index.data(Qt::UserRole).value<git::Reference>(); git::Reference ref = index.data(Qt::UserRole).value<git::Reference>();
if (all && ref && !ref.isHead() && !ref.isStash() && head.isValid()) if (all && ref && !ref.isHead() && !ref.isStash() && head.isValid())
current = findReference(model(), head); current = findReference(model(), head);
@ -201,7 +202,7 @@ void ReferenceWidget::updateLabel(const git::Reference &ref) {
git::Reference ReferenceWidget::currentReference() const { git::Reference ReferenceWidget::currentReference() const {
git::Reference ref = mView->currentReference(); git::Reference ref = mView->currentReference();
bool all = mRepo.appConfig().value<bool>("commit.refs.all", true); bool all = mRepo.appConfig().value<bool>(ConfigKeys::kRefsKey, true);
return (!all || (ref.isValid() && ref.isStash())) ? ref : mRepo.head(); return (!all || (ref.isValid() && ref.isStash())) ? ref : mRepo.head();
} }