Commit 834e06e7 authored by Waqar Ahmed's avatar Waqar Ahmed
Browse files

Git: Allow deleting branches



Allow deleting branches from within kate. Much faster than manually
git branch -D ...

Support deleting local branches only.
Signed-off-by: Waqar Ahmed's avatarWaqar Ahmed <waqar.17a@gmail.com>
parent c429a24f
Pipeline #79037 passed with stage
in 6 minutes and 34 seconds
......@@ -72,6 +72,7 @@ target_sources(
${CMAKE_SOURCE_DIR}/shared/quickdialog.cpp
pushpulldialog.cpp
comparebranchesview.cpp
branchdeletedialog.cpp
tools/kateprojectcodeanalysistoolcppcheck.cpp
tools/kateprojectcodeanalysistoolflake8.cpp
......
#include "branchdeletedialog.h"
#include "git/gitutils.h"
#include <QDialogButtonBox>
#include <QFont>
#include <QFontDatabase>
#include <QPushButton>
#include <QVBoxLayout>
#include <KLocalizedString>
#include <KMessageBox>
#include <ktexteditor/editor.h>
#include <ktexteditor_version.h>
BranchDeleteDialog::BranchDeleteDialog(const QString &dotGitPath, QWidget *parent)
: QDialog(parent)
{
loadBranches(dotGitPath);
auto l = new QVBoxLayout(this);
l->addWidget(&m_listView);
m_listView.setModel(&m_model);
// setup the buttons
using Btns = QDialogButtonBox::StandardButton;
auto dlgBtns = new QDialogButtonBox(Btns::Cancel, Qt::Horizontal, this);
auto deleteBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Delete"));
dlgBtns->addButton(deleteBtn, QDialogButtonBox::DestructiveRole);
connect(dlgBtns, &QDialogButtonBox::clicked, this, [this, deleteBtn, dlgBtns](QAbstractButton *btn) {
if (btn == deleteBtn) {
auto count = branchesToDelete().count();
QString ques = i18np("Are you sure you want to delete the selected branch?", "Are you sure you want to delete the selected branches?", count);
auto ret = KMessageBox::questionYesNo(this, ques, {}, KStandardGuiItem::yes(), KStandardGuiItem::no(), {}, KMessageBox::Dangerous);
if (ret == KMessageBox::Yes) {
accept();
} else {
// do nothing
}
} else if (dlgBtns->button(QDialogButtonBox::Cancel) == btn) {
reject();
}
});
connect(dlgBtns, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(dlgBtns, &QDialogButtonBox::rejected, this, &QDialog::reject);
l->addWidget(dlgBtns);
resize(500, 500);
}
void BranchDeleteDialog::loadBranches(const QString &dotGitPath)
{
#if KTEXTEDITOR_VERSION >= QT_VERSION_CHECK(5, 80, 0)
QFont f = KTextEditor::Editor::instance()->font();
#else
QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont);
#endif
static const auto branchIcon = QIcon::fromTheme(QStringLiteral("vcs-branch"));
const auto branches = GitUtils::getAllBranchesAndTags(dotGitPath, GitUtils::RefType::Head);
for (const auto &branch : branches) {
auto item = new QStandardItem(branchIcon, branch.name);
item->setFont(f);
item->setCheckable(true);
m_model.appendRow(item);
}
}
QStringList BranchDeleteDialog::branchesToDelete() const
{
QStringList branches;
int rowCount = m_model.rowCount();
for (int i = 0; i < rowCount; ++i) {
auto item = m_model.item(i);
if (item->checkState() == Qt::Checked) {
branches << item->text();
}
}
return branches;
}
#include <QDialog>
#include <QLabel>
#include <QListView>
#include <QStandardItemModel>
class BranchDeleteDialog : public QDialog
{
Q_OBJECT
public:
BranchDeleteDialog(const QString &dotGitPath, QWidget *parent = nullptr);
QStringList branchesToDelete() const;
private:
void loadBranches(const QString &dotGitPath);
void updateLabel(QStandardItem *item);
QStandardItemModel m_model;
QListView m_listView;
};
......@@ -190,3 +190,19 @@ std::pair<QString, QString> GitUtils::getLastCommitMessage(const QString &repo)
}
return {};
}
GitUtils::Result GitUtils::deleteBranches(const QStringList &branches, const QString &repo)
{
QStringList args = {QStringLiteral("branch"), QStringLiteral("-D")};
args << branches;
QProcess git;
setupGitProcess(git, repo, args);
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
QString out = QString::fromLatin1(git.readAllStandardError()) + QString::fromLatin1(git.readAllStandardOutput());
return {out, git.exitCode()};
}
Q_UNREACHABLE();
return {QString(), -1};
}
......@@ -31,12 +31,15 @@ struct Branch {
RefType type;
};
struct CheckoutResult {
QString branch;
struct Result {
QString error;
int returnCode;
};
struct CheckoutResult : public Result {
QString branch;
};
struct StatusEntry {
QString file;
char x;
......@@ -85,6 +88,8 @@ QVector<Branch> getAllBranches(const QString &repo);
QVector<Branch> getAllBranchesAndTags(const QString &repo, RefType ref = RefType::All);
std::pair<QString, QString> getLastCommitMessage(const QString &repo);
Result deleteBranches(const QStringList &branches, const QString &repo);
}
Q_DECLARE_TYPEINFO(GitUtils::Branch, Q_MOVABLE_TYPE);
......
......@@ -6,6 +6,7 @@
#include "gitwidget.h"
#include "branchcheckoutdialog.h"
#include "branchdeletedialog.h"
#include "branchesdialog.h"
#include "comparebranchesview.h"
#include "git/gitdiff.h"
......@@ -826,6 +827,15 @@ void GitWidget::buildMenu()
});
a->setIcon(QIcon::fromTheme(QStringLiteral("vcs-branch")));
a = m_gitMenu->addAction(i18n("Delete Branch"), this, [this] {
BranchDeleteDialog dlg(m_gitPath, this);
if (dlg.exec() == QDialog::Accepted) {
auto result = GitUtils::deleteBranches(dlg.branchesToDelete(), m_gitPath);
sendMessage(result.error, result.returnCode != 0);
}
});
a->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
a = m_gitMenu->addAction(i18n("Compare Branch with ..."), this, [this] {
BranchesDialog bd(m_mainWin->window(), m_pluginView, m_project->baseDir());
using GitUtils::RefType;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment