Commit 8d3d1ee5 authored by Christoph Cullmann's avatar Christoph Cullmann 🐮
Browse files

cleanup git version detection code

move implementation to an .cpp file
cache the results
fixup coding style
parent 8356221e
Pipeline #150359 passed with stage
in 2 minutes and 26 seconds
kate_add_plugin(compilerexplorer)
target_compile_definitions(compilerexplorer PRIVATE TRANSLATION_DOMAIN="compilerexplorer")
target_link_libraries(compilerexplorer PRIVATE KF5::I18n KF5::TextEditor)
target_link_libraries(compilerexplorer PRIVATE kateshared KF5::I18n KF5::TextEditor)
target_sources(
compilerexplorer
......@@ -12,10 +12,3 @@ target_sources(
AsmViewModel.cpp
compiledbreader.cpp
)
target_include_directories(
compilerexplorer
PUBLIC
${CMAKE_SOURCE_DIR}/shared
)
kate_add_plugin(kategitblameplugin)
target_compile_definitions(kategitblameplugin PRIVATE TRANSLATION_DOMAIN="kategitblameplugin")
target_link_libraries(kategitblameplugin PRIVATE KF5::I18n KF5::TextEditor)
target_link_libraries(kategitblameplugin PRIVATE kateshared KF5::I18n KF5::TextEditor)
target_sources(
kategitblameplugin
......@@ -10,8 +10,3 @@ target_sources(
commitfilesview.cpp
plugin.qrc
)
target_include_directories(kategitblameplugin PRIVATE
${CMAKE_SOURCE_DIR}/shared
)
......@@ -442,16 +442,14 @@ QVector<QString> KateProjectWorker::filesFromGit(const QDir &dir, bool recursive
QStringLiteral("--exclude-standard"),
QStringLiteral(".")};
/**
* for recent enough git versions ensure we don't show duplicated files
*/
const auto [major, minor] = getGitVersion(dir.absolutePath());
if(major > 2 || (major == 2 && minor >= 31))
{
lsFilesArgs.insert(3, QStringLiteral("--deduplicate"));
lsFilesUntrackedArgs.insert(4, QStringLiteral("--deduplicate"));
} else {
qDebug() << "Your git version is too old, please update.";
}
if (major > 2 || (major == 2 && minor >= 31)) {
lsFilesArgs.insert(3, QStringLiteral("--deduplicate"));
lsFilesUntrackedArgs.insert(4, QStringLiteral("--deduplicate"));
}
// ls-files + ls-files untracked
return gitFiles(dir, recursive, lsFilesArgs, false) << gitFiles(dir, recursive, lsFilesUntrackedArgs, true);
......
add_library(kateshared STATIC
gitprocess.cpp
quickdialog.cpp
signal_watcher.cpp
)
......
/*
SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org>
SPDX-License-Identifier: MIT
*/
#include "gitprocess.h"
#include <QRegularExpression>
#include <QStandardPaths>
bool setupGitProcess(QProcess &process, const QString &workingDirectory, const QStringList &arguments)
{
// only use git from PATH
static const auto gitExecutable = QStandardPaths::findExecutable(QStringLiteral("git"));
if (gitExecutable.isEmpty()) {
// ensure we have no valid QProcess setup
process.setProgram(QString());
return false;
}
// setup program and arguments, ensure we do run git in the right working directory
process.setProgram(gitExecutable);
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);
return true;
}
// internal helper for the external caching accessor
static std::pair<int, int> getGitVersionUncached(const QString &workingDir)
{
QProcess git;
if (!setupGitProcess(git, workingDir, {QStringLiteral("--version")})) {
return {-1, -1};
}
// try to run, no version output feasible if not possible
git.start(QProcess::ReadOnly);
if (!git.waitForStarted() || !git.waitForFinished() || git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
return {-1, -1};
}
// match the version output
const QString gitVersion = QString::fromUtf8(git.readAllStandardOutput());
const QRegularExpression gitRegex(QStringLiteral("git version\\s*(\\d+).(\\d+).(\\d+)+.*"));
const QRegularExpressionMatch gitMatch = gitRegex.match(gitVersion);
bool okMajor = false;
bool okMinor = false;
const int versionMajor = gitMatch.captured(1).toInt(&okMajor);
const int versionMinor = gitMatch.captured(2).toInt(&okMinor);
if (okMajor && okMinor) {
return {versionMajor, versionMinor};
}
// no version properly detected
return {-1, -1};
}
std::pair<int, int> getGitVersion(const QString &workingDir)
{
// cache internal result to avoid expensive recalculation
static const auto cachedVersion = getGitVersionUncached(workingDir);
return cachedVersion;
}
......@@ -21,70 +21,11 @@
* @param arguments arguments to pass to git
* @return could set setup the process or did that fail, e.g. because the git executable is not available?
*/
inline bool setupGitProcess(QProcess &process, const QString &workingDirectory, const QStringList &arguments)
{
// only use git from PATH
static const auto gitExecutable = QStandardPaths::findExecutable(QStringLiteral("git"));
if (gitExecutable.isEmpty()) {
// ensure we have no valid QProcess setup
process.setProgram(QString());
return false;
}
// setup program and arguments, ensure we do run git in the right working directory
process.setProgram(gitExecutable);
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);
return true;
}
bool setupGitProcess(QProcess &process, const QString &workingDirectory, const QStringList &arguments);
/**
* helper function to get the git version
* @param dir
* @param workingDirectory working directory to use for process
* @return git major and minor version as pair, -1,-1 if infeasible to determine
*/
inline std::pair<int, int> getGitVersion(const QString &workingDir)
{
QProcess git;
if (!setupGitProcess(git, workingDir, {QStringLiteral("--version")})) {
return {-1, -1};
}
git.start(QProcess::ReadOnly);
if (git.waitForStarted() && git.waitForFinished(-1)) {
if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) {
return {-1, -1};
}
QString gitVersion = QString::fromUtf8(git.readAllStandardOutput());
QString expression = QStringLiteral("git version\\s*(\\d+).(\\d+).(\\d+)+.*");
QRegularExpression gitRegex(expression);
QRegularExpressionMatch gitMatch = gitRegex.match(gitVersion);
bool okMajor;
bool okMinor;
int versionMajor = gitMatch.captured(1).toInt(&okMajor);
int versionMinor = gitMatch.captured(2).toInt(&okMinor);
if(okMajor && okMinor)
{
return {versionMajor, versionMinor};
} else {
return {-1, -1};
}
}
return {-1, -1};
}
std::pair<int, int> getGitVersion(const QString &workingDir);
Supports Markdown
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