summaryrefslogtreecommitdiff
path: root/src/plugins/git
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/git')
-rw-r--r--src/plugins/git/gitclient.cpp65
-rw-r--r--src/plugins/git/gitclient.h5
-rw-r--r--src/plugins/git/gitgrep.cpp13
-rw-r--r--src/plugins/git/gitplugin.cpp27
4 files changed, 62 insertions, 48 deletions
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 8062383945..5ac84c5ac4 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -648,7 +648,7 @@ public:
static bool gitHasRgbColors()
{
- const unsigned gitVersion = GitClient::instance()->gitVersion();
+ const unsigned gitVersion = GitClient::instance()->gitVersion().result();
return gitVersion >= 0x020300U;
}
@@ -3611,36 +3611,10 @@ QString GitClient::readOneLine(const FilePath &workingDirectory, const QStringLi
return proc.cleanedStdOut().trimmed();
}
-// determine version as '(major << 16) + (minor << 8) + patch' or 0.
-unsigned GitClient::gitVersion(QString *errorMessage) const
-{
- const FilePath newGitBinary = vcsBinary();
- if (m_gitVersionForBinary != newGitBinary && !newGitBinary.isEmpty()) {
- // Do not execute repeatedly if that fails (due to git
- // not being installed) until settings are changed.
- m_cachedGitVersion = synchronousGitVersion(errorMessage);
- m_gitVersionForBinary = newGitBinary;
- }
- return m_cachedGitVersion;
-}
-
-// determine version as '(major << 16) + (minor << 8) + patch' or 0.
-unsigned GitClient::synchronousGitVersion(QString *errorMessage) const
+static unsigned parseGitVersion(const QString &output)
{
- if (vcsBinary().isEmpty())
- return 0;
-
- // run git --version
- QtcProcess proc;
- vcsSynchronousExec(proc, {}, {"--version"}, silentFlags);
- if (proc.result() != ProcessResult::FinishedWithSuccess) {
- msgCannotRun(tr("Cannot determine Git version: %1").arg(proc.cleanedStdErr()), errorMessage);
- return 0;
- }
-
// cut 'git version 1.6.5.1.sha'
// another form: 'git version 1.9.rc1'
- const QString output = proc.cleanedStdOut();
const QRegularExpression versionPattern("^[^\\d]+(\\d+)\\.(\\d+)\\.(\\d+|rc\\d).*$");
QTC_ASSERT(versionPattern.isValid(), return 0);
const QRegularExpressionMatch match = versionPattern.match(output);
@@ -3651,6 +3625,41 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const
return version(majorV, minorV, patchV);
}
+// determine version as '(major << 16) + (minor << 8) + patch' or 0.
+QFuture<unsigned> GitClient::gitVersion() const
+{
+ QFutureInterface<unsigned> fi;
+ fi.reportStarted();
+
+ // Do not execute repeatedly if that fails (due to git
+ // not being installed) until settings are changed.
+ const FilePath newGitBinary = vcsBinary();
+ const bool needToRunGit = m_gitVersionForBinary != newGitBinary && !newGitBinary.isEmpty();
+ if (needToRunGit) {
+ auto proc = new QtcProcess(const_cast<GitClient *>(this));
+ connect(proc, &QtcProcess::done, this, [this, proc, fi, newGitBinary]() mutable {
+ if (proc->result() == ProcessResult::FinishedWithSuccess) {
+ m_cachedGitVersion = parseGitVersion(proc->cleanedStdOut());
+ m_gitVersionForBinary = newGitBinary;
+ fi.reportResult(m_cachedGitVersion);
+ fi.reportFinished();
+ }
+ proc->deleteLater();
+ });
+
+ proc->setTimeoutS(vcsTimeoutS());
+ proc->setEnvironment(processEnvironment());
+ proc->setCommand({newGitBinary, {"--version"}});
+ proc->start();
+ } else {
+ // already cached
+ fi.reportResult(m_cachedGitVersion);
+ fi.reportFinished();
+ }
+
+ return fi.future();
+}
+
bool GitClient::StashInfo::init(const FilePath &workingDirectory, const QString &command,
StashFlag flag, PushAction pushAction)
{
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index c356f79ff4..1571183d5c 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -145,7 +145,7 @@ public:
static GitSettings &settings();
Utils::FilePath vcsBinary() const override;
- unsigned gitVersion(QString *errorMessage = nullptr) const;
+ QFuture<unsigned> gitVersion() const;
VcsBase::VcsCommand *vcsExecAbortable(const Utils::FilePath &workingDirectory,
const QStringList &arguments,
@@ -387,9 +387,6 @@ private:
const Utils::FilePath &workingDirectory,
std::function<GitBaseDiffEditorController *(Core::IDocument *)> factory) const;
- // determine version as '(major << 16) + (minor << 8) + patch' or 0.
- unsigned synchronousGitVersion(QString *errorMessage = nullptr) const;
-
QString readOneLine(const Utils::FilePath &workingDirectory, const QStringList &arguments) const;
enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed };
diff --git a/src/plugins/git/gitgrep.cpp b/src/plugins/git/gitgrep.cpp
index 4395c96bd1..fa2d9cdadd 100644
--- a/src/plugins/git/gitgrep.cpp
+++ b/src/plugins/git/gitgrep.cpp
@@ -247,10 +247,15 @@ GitGrep::GitGrep(GitClient *client)
const QRegularExpression refExpression("[\\S]*");
m_treeLineEdit->setValidator(new QRegularExpressionValidator(refExpression, this));
layout->addWidget(m_treeLineEdit);
- if (client->gitVersion() >= 0x021300) {
- m_recurseSubmodules = new QCheckBox(tr("Recurse submodules"));
- layout->addWidget(m_recurseSubmodules);
- }
+ // asynchronously check git version, add "recurse submodules" option if available
+ Utils::onResultReady(client->gitVersion(),
+ this,
+ [this, pLayout = QPointer<QHBoxLayout>(layout)](unsigned version) {
+ if (version >= 0x021300 && pLayout) {
+ m_recurseSubmodules = new QCheckBox(tr("Recurse submodules"));
+ pLayout->addWidget(m_recurseSubmodules);
+ }
+ });
TextEditor::FindInFiles *findInFiles = TextEditor::FindInFiles::instance();
QTC_ASSERT(findInFiles, return);
connect(findInFiles, &TextEditor::FindInFiles::pathChanged,
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 74faef36dd..f007303c4d 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -66,6 +66,7 @@
#include <utils/parameteraction.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
+#include <utils/runextensions.h>
#include <utils/stringutils.h>
#include <utils/utilsicons.h>
@@ -1367,20 +1368,22 @@ void GitPluginPrivate::startCommit(CommitType commitType)
void GitPluginPrivate::updateVersionWarning()
{
- unsigned version = m_gitClient.gitVersion();
- if (!version || version >= minimumRequiredVersion)
- return;
- IDocument *curDocument = EditorManager::currentDocument();
+ QPointer<IDocument> curDocument = EditorManager::currentDocument();
if (!curDocument)
return;
- InfoBar *infoBar = curDocument->infoBar();
- Id gitVersionWarning("GitVersionWarning");
- if (!infoBar->canInfoBeAdded(gitVersionWarning))
- return;
- infoBar->addInfo(InfoBarEntry(gitVersionWarning,
- tr("Unsupported version of Git found. Git %1 or later required.")
- .arg(versionString(minimumRequiredVersion)),
- InfoBarEntry::GlobalSuppression::Enabled));
+ Utils::onResultReady(m_gitClient.gitVersion(), this, [curDocument](unsigned version) {
+ if (!curDocument || !version || version >= minimumRequiredVersion)
+ return;
+ InfoBar *infoBar = curDocument->infoBar();
+ Id gitVersionWarning("GitVersionWarning");
+ if (!infoBar->canInfoBeAdded(gitVersionWarning))
+ return;
+ infoBar->addInfo(
+ InfoBarEntry(gitVersionWarning,
+ tr("Unsupported version of Git found. Git %1 or later required.")
+ .arg(versionString(minimumRequiredVersion)),
+ InfoBarEntry::GlobalSuppression::Enabled));
+ });
}
IEditor *GitPluginPrivate::openSubmitEditor(const QString &fileName, const CommitData &cd)