Commit d3dd58cb authored by Christoph Cullmann's avatar Christoph Cullmann 🐮
Browse files

add helper to create consistent git process

helper function will e.g. ensure we have always

GIT_OPTIONAL_LOCKS=0

set like adviced for editor background calls

this allows to add more such stuff in the future
in one central place
parent d407c83a
Pipeline #72241 passed with stage
in 5 minutes and 51 seconds
......@@ -10,6 +10,10 @@ target_sources(
plugin.qrc
)
target_include_directories(kategitblameplugin PRIVATE
${CMAKE_SOURCE_DIR}/shared
)
# ensure we are able to load plugins pre-install, too, directories must match!
set_target_properties(kategitblameplugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/ktexteditor")
install(TARGETS kategitblameplugin DESTINATION ${KDE_INSTALL_PLUGINDIR}/ktexteditor)
......@@ -7,6 +7,8 @@
#include "kategitblameplugin.h"
#include "gitblametooltip.h"
#include <gitprocess.h>
#include <algorithm>
#include <KActionCollection>
......@@ -236,10 +238,8 @@ void KateGitBlamePluginView::startBlameProcess(const QUrl &url)
QDir dir{url.toLocalFile()};
dir.cdUp();
QStringList args{QStringLiteral("blame"), QStringLiteral("--date=iso-strict"), QStringLiteral("./%1").arg(fileName)};
m_blameInfoProc.setWorkingDirectory(dir.absolutePath());
m_blameInfoProc.start(QStringLiteral("git"), args, QIODevice::ReadOnly);
setupGitProcess(m_blameInfoProc, dir.absolutePath(), {QStringLiteral("blame"), QStringLiteral("--date=iso-strict"), QStringLiteral("./%1").arg(fileName)});
m_blameInfoProc.start(QIODevice::ReadOnly);
m_blameUrl = url;
}
......@@ -257,9 +257,8 @@ void KateGitBlamePluginView::startShowProcess(const QUrl &url, const QString &ha
QDir dir{url.toLocalFile()};
dir.cdUp();
QStringList args{QStringLiteral("show"), hash};
m_showProc.setWorkingDirectory(dir.absolutePath());
m_showProc.start(QStringLiteral("git"), args, QIODevice::ReadOnly);
setupGitProcess(m_showProc, dir.absolutePath(), {QStringLiteral("show"), hash});
m_showProc.start(QIODevice::ReadOnly);
}
void KateGitBlamePluginView::showCommitInfo(const QString &hash, KTextEditor::View *view)
......
......@@ -3,10 +3,13 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "comparebranchesview.h"
#include "kateprojectpluginview.h"
#include "kateprojectworker.h"
#include <gitprocess.h>
#include <QDir>
#include <QPainter>
#include <QProcess>
......@@ -155,9 +158,8 @@ void CompareBranchesView::showDiff(const QModelIndex &idx)
{
auto file = idx.data(Qt::UserRole).toString().remove(m_gitDir + QLatin1Char('/'));
QProcess git;
git.setWorkingDirectory(m_gitDir);
QStringList args{QStringLiteral("diff"), QStringLiteral("%1...%2").arg(m_fromBr).arg(m_toBr), QStringLiteral("--"), file};
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, m_gitDir, {QStringLiteral("diff"), QStringLiteral("%1...%2").arg(m_fromBr).arg(m_toBr), QStringLiteral("--"), file});
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
......
......@@ -3,8 +3,11 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "filehistorywidget.h"
#include <gitprocess.h>
#include <QDate>
#include <QDebug>
#include <QFileInfo>
......@@ -19,13 +22,12 @@
QList<QByteArray> FileHistoryWidget::getFileHistory(const QString &file)
{
QProcess git;
git.setWorkingDirectory(QFileInfo(file).absolutePath());
QStringList args{QStringLiteral("log"),
setupGitProcess(git, QFileInfo(file).absolutePath(), {QStringLiteral("log"),
QStringLiteral("--format=%H%n%aN%n%aE%n%at%n%ct%n%P%n%B"),
QStringLiteral("-z"),
QStringLiteral("--author-date-order"),
file};
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
file});
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() == QProcess::NormalExit && git.exitCode() == 0) {
return git.readAll().split(0x00);
......@@ -216,12 +218,11 @@ void FileHistoryWidget::itemClicked(const QModelIndex &idx)
{
QProcess git;
QFileInfo fi(m_file);
git.setWorkingDirectory(fi.absolutePath());
const auto commit = idx.data(CommitListModel::CommitRole).value<Commit>();
QStringList args{QStringLiteral("show"), QString::fromUtf8(commit.hash), QStringLiteral("--"), m_file};
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, fi.absolutePath(), {QStringLiteral("show"), QString::fromUtf8(commit.hash), QStringLiteral("--"), m_file});
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
return;
......
......@@ -3,8 +3,11 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "gitutils.h"
#include <gitprocess.h>
#include <QDateTime>
#include <QDebug>
#include <QProcess>
......@@ -12,9 +15,8 @@
bool GitUtils::isGitRepo(const QString &repo)
{
QProcess git;
git.setWorkingDirectory(repo);
QStringList args{QStringLiteral("rev-parse"), QStringLiteral("--is-inside-work-tree")};
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--is-inside-work-tree")});
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
return git.readAll().trimmed() == "true";
}
......@@ -25,9 +27,7 @@ std::optional<QString> GitUtils::getDotGitPath(const QString &repo)
{
/* This call is intentionally blocking because we need git path for everything else */
QProcess git;
git.setProgram(QStringLiteral("git"));
git.setWorkingDirectory(repo);
git.setArguments({QStringLiteral("rev-parse"), QStringLiteral("--absolute-git-dir")});
setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--absolute-git-dir")});
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
......@@ -57,8 +57,8 @@ QString GitUtils::getCurrentBranchName(const QString &repo)
for (int i = 0; i < 3; ++i) {
QProcess git;
git.setWorkingDirectory(repo);
git.start(QStringLiteral("git"), argsList[i], QProcess::ReadOnly);
setupGitProcess(git, repo, argsList[i]);
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() == QProcess::NormalExit && git.exitCode() == 0) {
return QString::fromUtf8(git.readAllStandardOutput().trimmed());
......@@ -73,9 +73,8 @@ QString GitUtils::getCurrentBranchName(const QString &repo)
GitUtils::CheckoutResult GitUtils::checkoutBranch(const QString &repo, const QString &branch)
{
QProcess git;
git.setWorkingDirectory(repo);
QStringList args{QStringLiteral("checkout"), branch};
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, repo, {QStringLiteral("checkout"), branch});
git.start(QProcess::ReadOnly);
CheckoutResult res;
res.branch = branch;
if (git.waitForStarted() && git.waitForFinished(-1)) {
......@@ -88,12 +87,12 @@ GitUtils::CheckoutResult GitUtils::checkoutBranch(const QString &repo, const QSt
GitUtils::CheckoutResult GitUtils::checkoutNewBranch(const QString &repo, const QString &newBranch, const QString &fromBranch)
{
QProcess git;
git.setWorkingDirectory(repo);
QStringList args{QStringLiteral("checkout"), QStringLiteral("-q"), QStringLiteral("-b"), newBranch};
if (!fromBranch.isEmpty()) {
args.append(fromBranch);
}
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, repo, args);
git.start(QProcess::ReadOnly);
CheckoutResult res;
res.branch = newBranch;
if (git.waitForStarted() && git.waitForFinished(-1)) {
......@@ -120,7 +119,6 @@ QVector<GitUtils::Branch> GitUtils::getAllBranchesAndTags(const QString &repo, R
{
// git for-each-ref --format '%(refname)' --sort=-committerdate ...
QProcess git;
git.setWorkingDirectory(repo);
QStringList args{QStringLiteral("for-each-ref"), QStringLiteral("--format"), QStringLiteral("%(refname)"), QStringLiteral("--sort=-committerdate")};
if (ref & RefType::Head) {
......@@ -134,7 +132,8 @@ QVector<GitUtils::Branch> GitUtils::getAllBranchesAndTags(const QString &repo, R
args.append(QStringLiteral("--sort=-taggerdate"));
}
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, repo, args);
git.start(QProcess::ReadOnly);
QVector<Branch> branches;
if (git.waitForStarted() && git.waitForFinished(-1)) {
QString gitout = QString::fromUtf8(git.readAllStandardOutput());
......@@ -167,9 +166,8 @@ std::pair<QString, QString> GitUtils::getLastCommitMessage(const QString &repo)
{
// git log -1 --pretty=%B
QProcess git;
git.setWorkingDirectory(repo);
const QStringList args{QStringLiteral("log"), QStringLiteral("-1"), QStringLiteral("--pretty=%B")};
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, repo, {QStringLiteral("log"), QStringLiteral("-1"), QStringLiteral("--pretty=%B")});
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitCode() != 0 || git.exitStatus() != QProcess::NormalExit) {
return {};
......
......@@ -3,6 +3,7 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "gitwidget.h"
#include "branchcheckoutdialog.h"
#include "branchesdialog.h"
......@@ -16,6 +17,8 @@
#include "pushpulldialog.h"
#include "stashdialog.h"
#include <gitprocess.h>
#include <KColorScheme>
#include <QContextMenuEvent>
#include <QCoreApplication>
......@@ -291,11 +294,10 @@ KTextEditor::MainWindow *GitWidget::mainWindow()
return m_mainWin;
}
QProcess *GitWidget::gitp()
QProcess *GitWidget::gitp(const QStringList &arguments)
{
auto git = new QProcess(this);
git->setProgram(QStringLiteral("git"));
git->setWorkingDirectory(m_gitPath);
setupGitProcess(*git, m_gitPath, arguments);
connect(git, &QProcess::errorOccurred, this, [this, git](QProcess::ProcessError pe) {
// git program missing is not an error
sendMessage(git->errorString(), pe != QProcess::FailedToStart);
......@@ -306,7 +308,17 @@ QProcess *GitWidget::gitp()
void GitWidget::getStatus(bool untracked, bool submodules)
{
auto git = gitp();
auto args = QStringList{QStringLiteral("status"), QStringLiteral("-z")};
if (!untracked) {
args.append(QStringLiteral("-uno"));
} else {
args.append(QStringLiteral("-u"));
}
if (!submodules) {
args.append(QStringLiteral("--ignore-submodules"));
}
auto git = gitp(args);
connect(git, &QProcess::finished, this, [this, git](int exitCode, QProcess::ExitStatus es) {
if (es != QProcess::NormalExit || exitCode != 0) {
// no error on status failure
......@@ -317,23 +329,12 @@ void GitWidget::getStatus(bool untracked, bool submodules)
}
git->deleteLater();
});
auto args = QStringList{QStringLiteral("status"), QStringLiteral("-z")};
if (!untracked) {
args.append(QStringLiteral("-uno"));
} else {
args.append(QStringLiteral("-u"));
}
if (!submodules) {
args.append(QStringLiteral("--ignore-submodules"));
}
git->setArguments(args);
git->start(QProcess::ReadOnly);
}
void GitWidget::runGitCmd(const QStringList &args, const QString &i18error)
{
auto git = gitp();
auto git = gitp(args);
connect(git, &QProcess::finished, this, [this, i18error, git](int exitCode, QProcess::ExitStatus es) {
if (es != QProcess::NormalExit || exitCode != 0) {
sendMessage(i18error + QStringLiteral(": ") + QString::fromUtf8(git->readAllStandardError()), true);
......@@ -342,13 +343,12 @@ void GitWidget::runGitCmd(const QStringList &args, const QString &i18error)
}
git->deleteLater();
});
git->setArguments(args);
git->start(QProcess::ReadOnly);
}
void GitWidget::runPushPullCmd(const QStringList &args)
{
auto git = gitp();
auto git = gitp(args);
git->setProcessChannelMode(QProcess::MergedChannels);
connect(git, &QProcess::finished, this, [this, args, git](int exitCode, QProcess::ExitStatus es) {
......@@ -367,7 +367,6 @@ void GitWidget::runPushPullCmd(const QStringList &args)
});
enableCancel(git);
git->setArguments(args);
git->start(QProcess::ReadOnly);
}
......@@ -424,10 +423,9 @@ void GitWidget::openAtHEAD(const QString &file)
return;
}
auto git = gitp();
auto args = QStringList{QStringLiteral("show"), QStringLiteral("--textconv")};
args.append(QStringLiteral(":") + file);
git->setArguments(args);
auto git = gitp(args);
git->start(QProcess::ReadOnly);
connect(git, &QProcess::finished, this, [this, file, git](int exitCode, QProcess::ExitStatus es) {
......@@ -461,7 +459,7 @@ void GitWidget::showDiff(const QString &file, bool staged)
args.append(file);
}
auto git = gitp();
auto git = gitp(args);
connect(git, &QProcess::finished, this, [this, file, staged, git](int exitCode, QProcess::ExitStatus es) {
if (es != QProcess::NormalExit || exitCode != 0) {
sendMessage(i18n("Failed to get Diff of file: %1", QString::fromUtf8(git->readAllStandardError())), true);
......@@ -503,8 +501,6 @@ void GitWidget::showDiff(const QString &file, bool staged)
}
git->deleteLater();
});
git->setArguments(args);
git->start(QProcess::ReadOnly);
}
......@@ -521,7 +517,8 @@ void GitWidget::launchExternalDiffTool(const QString &file, bool staged)
args.append(file);
QProcess git;
git.startDetached(QStringLiteral("git"), args, m_gitPath);
setupGitProcess(git, m_gitPath, args);
git.startDetached();
}
void GitWidget::commitChanges(const QString &msg, const QString &desc, bool signOff, bool amend)
......@@ -543,7 +540,7 @@ void GitWidget::commitChanges(const QString &msg, const QString &desc, bool sign
args.append(desc);
}
auto git = gitp();
auto git = gitp(args);
connect(git, &QProcess::finished, this, [this, git](int exitCode, QProcess::ExitStatus es) {
if (es != QProcess::NormalExit || exitCode != 0) {
......@@ -555,7 +552,6 @@ void GitWidget::commitChanges(const QString &msg, const QString &desc, bool sign
}
git->deleteLater();
});
git->setArguments(args);
git->start(QProcess::ReadOnly);
}
......@@ -598,8 +594,7 @@ void GitWidget::applyDiff(const QString &fileName, bool staged, bool hunk, KText
file->write(diff.toUtf8());
file->close();
auto git = gitp();
QStringList args{QStringLiteral("apply"), QStringLiteral("--index"), QStringLiteral("--cached"), file->fileName()};
auto git = gitp({QStringLiteral("apply"), QStringLiteral("--index"), QStringLiteral("--cached"), file->fileName()});
connect(git, &QProcess::finished, this, [=](int exitCode, QProcess::ExitStatus es) {
if (es != QProcess::NormalExit || exitCode != 0) {
......@@ -617,7 +612,6 @@ void GitWidget::applyDiff(const QString &fileName, bool staged, bool hunk, KText
delete file;
git->deleteLater();
});
git->setArguments(args);
git->start(QProcess::ReadOnly);
}
......@@ -734,8 +728,8 @@ void GitWidget::numStatForStatus(QVector<GitUtils::StatusItem> &list, bool modif
: QStringList{QStringLiteral("diff"), QStringLiteral("--numstat"), QStringLiteral("--staged"), QStringLiteral("-z")};
QProcess git;
git.setWorkingDirectory(m_gitPath);
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, m_gitPath, args);
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
return;
......@@ -755,8 +749,8 @@ void GitWidget::branchCompareFiles(const QString &from, const QString &to)
auto args = QStringList{QStringLiteral("diff"), QStringLiteral("%1...%2").arg(from).arg(to), QStringLiteral("--name-status")};
QProcess git;
git.setWorkingDirectory(m_gitPath);
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, m_gitPath, args);
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
return;
......@@ -777,8 +771,8 @@ void GitWidget::branchCompareFiles(const QString &from, const QString &to)
// get --num-stat
args = QStringList{QStringLiteral("diff"), QStringLiteral("%1...%2").arg(from).arg(to), QStringLiteral("--numstat"), QStringLiteral("-z")};
git.setArguments(args);
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, m_gitPath, args);
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
sendMessage(i18n("Failed to get numstat when diffing %1...%2", from, to), true);
......
......@@ -77,7 +77,7 @@ private:
using CancelHandle = QPointer<QProcess>;
CancelHandle m_cancelHandle;
QProcess *gitp();
QProcess *gitp(const QStringList &arguments);
void buildMenu();
void setDotGitPath();
......
......@@ -8,6 +8,8 @@
#include "kateprojectworker.h"
#include "kateprojectitem.h"
#include <gitprocess.h>
#include <QDir>
#include <QDirIterator>
#include <QFile>
......@@ -423,8 +425,8 @@ QVector<QString> KateProjectWorker::filesFromGit(const QDir &dir, bool recursive
QVector<QString> KateProjectWorker::gitFiles(const QDir &dir, bool recursive, const QStringList &args)
{
QProcess git;
git.setWorkingDirectory(dir.absolutePath());
git.start(QStringLiteral("git"), args, QProcess::ReadOnly);
setupGitProcess(git, dir.absolutePath(), args);
git.start(QProcess::ReadOnly);
QVector<QString> files;
if (!git.waitForStarted() || !git.waitForFinished(-1)) {
return files;
......
/*
SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org>
SPDX-License-Identifier: MIT
*/
#pragma once
#include <QProcess>
/**
* small helper function to setup a QProcess based "git" command.
* you pass working directory & arguments
* it will additionally setup stuff like GIT_OPTIONAL_LOCKS=0
* after this, you can just call "start" or "startDetached" for the process.
*
* @param process process to setup for git
* @param workingDirectory working directory to use for process
* @param arguments arguments to pass to git
*/
inline void setupGitProcess(QProcess &process, const QString &workingDirectory, const QStringList &arguments)
{
process.setProgram(QStringLiteral("git"));
process.setWorkingDirectory(workingDirectory);
process.setArguments(arguments);
/**
* from the git manual:
*
* If set to 0, Git will complete any requested operation without performing any optional sub-operations that require taking a lock.
* For example, this will prevent git status from refreshing the index as a side effect.
* This is useful for processes running in the background which do not want to cause lock contention with other operations on the repository.
* Defaults to 1.
*
* we use the env var as this is compatible even for "ancient" git versions pre 2.15.2
*/
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert(QStringLiteral("GIT_OPTIONAL_LOCKS"), QStringLiteral("0"));
process.setProcessEnvironment(env);
}
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