mirror of
https://github.com/Murmele/Gittyup.git
synced 2024-09-11 02:35:41 +03:00
Merge pull request #780 from Murmele/singleParentFilter
Single parent filter
This commit is contained in:
commit
13032c3039
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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.
|
||||||
|
@ -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}")
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
9
src/ui/ConfigKeys.cpp
Normal 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
13
src/ui/ConfigKeys.h
Normal 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
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user