forked from qt-creator/qt-creator
Git: Do not run 'git --version' synchronously at startup
We can easily delay this, and if git acts up for some reason, we don't have to block startup. Task-number: QTCREATORBUG-27765 Change-Id: I25aa6f8d04d1fd4b9d87f8ccf7ffd591f7bbe519 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
@@ -648,7 +648,7 @@ public:
|
|||||||
|
|
||||||
static bool gitHasRgbColors()
|
static bool gitHasRgbColors()
|
||||||
{
|
{
|
||||||
const unsigned gitVersion = GitClient::instance()->gitVersion();
|
const unsigned gitVersion = GitClient::instance()->gitVersion().result();
|
||||||
return gitVersion >= 0x020300U;
|
return gitVersion >= 0x020300U;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3611,36 +3611,10 @@ QString GitClient::readOneLine(const FilePath &workingDirectory, const QStringLi
|
|||||||
return proc.cleanedStdOut().trimmed();
|
return proc.cleanedStdOut().trimmed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine version as '(major << 16) + (minor << 8) + patch' or 0.
|
static unsigned parseGitVersion(const QString &output)
|
||||||
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
|
|
||||||
{
|
|
||||||
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'
|
// cut 'git version 1.6.5.1.sha'
|
||||||
// another form: 'git version 1.9.rc1'
|
// another form: 'git version 1.9.rc1'
|
||||||
const QString output = proc.cleanedStdOut();
|
|
||||||
const QRegularExpression versionPattern("^[^\\d]+(\\d+)\\.(\\d+)\\.(\\d+|rc\\d).*$");
|
const QRegularExpression versionPattern("^[^\\d]+(\\d+)\\.(\\d+)\\.(\\d+|rc\\d).*$");
|
||||||
QTC_ASSERT(versionPattern.isValid(), return 0);
|
QTC_ASSERT(versionPattern.isValid(), return 0);
|
||||||
const QRegularExpressionMatch match = versionPattern.match(output);
|
const QRegularExpressionMatch match = versionPattern.match(output);
|
||||||
@@ -3651,6 +3625,41 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const
|
|||||||
return version(majorV, minorV, patchV);
|
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,
|
bool GitClient::StashInfo::init(const FilePath &workingDirectory, const QString &command,
|
||||||
StashFlag flag, PushAction pushAction)
|
StashFlag flag, PushAction pushAction)
|
||||||
{
|
{
|
||||||
|
@@ -145,7 +145,7 @@ public:
|
|||||||
static GitSettings &settings();
|
static GitSettings &settings();
|
||||||
|
|
||||||
Utils::FilePath vcsBinary() const override;
|
Utils::FilePath vcsBinary() const override;
|
||||||
unsigned gitVersion(QString *errorMessage = nullptr) const;
|
QFuture<unsigned> gitVersion() const;
|
||||||
|
|
||||||
VcsBase::VcsCommand *vcsExecAbortable(const Utils::FilePath &workingDirectory,
|
VcsBase::VcsCommand *vcsExecAbortable(const Utils::FilePath &workingDirectory,
|
||||||
const QStringList &arguments,
|
const QStringList &arguments,
|
||||||
@@ -387,9 +387,6 @@ private:
|
|||||||
const Utils::FilePath &workingDirectory,
|
const Utils::FilePath &workingDirectory,
|
||||||
std::function<GitBaseDiffEditorController *(Core::IDocument *)> factory) const;
|
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;
|
QString readOneLine(const Utils::FilePath &workingDirectory, const QStringList &arguments) const;
|
||||||
|
|
||||||
enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed };
|
enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed };
|
||||||
|
@@ -247,10 +247,15 @@ GitGrep::GitGrep(GitClient *client)
|
|||||||
const QRegularExpression refExpression("[\\S]*");
|
const QRegularExpression refExpression("[\\S]*");
|
||||||
m_treeLineEdit->setValidator(new QRegularExpressionValidator(refExpression, this));
|
m_treeLineEdit->setValidator(new QRegularExpressionValidator(refExpression, this));
|
||||||
layout->addWidget(m_treeLineEdit);
|
layout->addWidget(m_treeLineEdit);
|
||||||
if (client->gitVersion() >= 0x021300) {
|
// asynchronously check git version, add "recurse submodules" option if available
|
||||||
m_recurseSubmodules = new QCheckBox(tr("Recurse submodules"));
|
Utils::onResultReady(client->gitVersion(),
|
||||||
layout->addWidget(m_recurseSubmodules);
|
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();
|
TextEditor::FindInFiles *findInFiles = TextEditor::FindInFiles::instance();
|
||||||
QTC_ASSERT(findInFiles, return);
|
QTC_ASSERT(findInFiles, return);
|
||||||
connect(findInFiles, &TextEditor::FindInFiles::pathChanged,
|
connect(findInFiles, &TextEditor::FindInFiles::pathChanged,
|
||||||
|
@@ -66,6 +66,7 @@
|
|||||||
#include <utils/parameteraction.h>
|
#include <utils/parameteraction.h>
|
||||||
#include <utils/pathchooser.h>
|
#include <utils/pathchooser.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/runextensions.h>
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
@@ -1367,20 +1368,22 @@ void GitPluginPrivate::startCommit(CommitType commitType)
|
|||||||
|
|
||||||
void GitPluginPrivate::updateVersionWarning()
|
void GitPluginPrivate::updateVersionWarning()
|
||||||
{
|
{
|
||||||
unsigned version = m_gitClient.gitVersion();
|
QPointer<IDocument> curDocument = EditorManager::currentDocument();
|
||||||
if (!version || version >= minimumRequiredVersion)
|
|
||||||
return;
|
|
||||||
IDocument *curDocument = EditorManager::currentDocument();
|
|
||||||
if (!curDocument)
|
if (!curDocument)
|
||||||
return;
|
return;
|
||||||
InfoBar *infoBar = curDocument->infoBar();
|
Utils::onResultReady(m_gitClient.gitVersion(), this, [curDocument](unsigned version) {
|
||||||
Id gitVersionWarning("GitVersionWarning");
|
if (!curDocument || !version || version >= minimumRequiredVersion)
|
||||||
if (!infoBar->canInfoBeAdded(gitVersionWarning))
|
return;
|
||||||
return;
|
InfoBar *infoBar = curDocument->infoBar();
|
||||||
infoBar->addInfo(InfoBarEntry(gitVersionWarning,
|
Id gitVersionWarning("GitVersionWarning");
|
||||||
tr("Unsupported version of Git found. Git %1 or later required.")
|
if (!infoBar->canInfoBeAdded(gitVersionWarning))
|
||||||
.arg(versionString(minimumRequiredVersion)),
|
return;
|
||||||
InfoBarEntry::GlobalSuppression::Enabled));
|
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)
|
IEditor *GitPluginPrivate::openSubmitEditor(const QString &fileName, const CommitData &cd)
|
||||||
|
Reference in New Issue
Block a user