From 3be6065b04c771a3469eb11a8d7785ecd1191d00 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 31 Jul 2013 21:12:41 +0300 Subject: [PATCH] Git: Fix crash on quit while rebase-todo editor is open Change-Id: I458cbb2168642f226583b406e34596d223c7d5ea Reviewed-by: Tobias Hunger --- src/plugins/git/gitclient.cpp | 16 ++++++++++------ src/plugins/vcsbase/command.cpp | 33 ++++++++++++++++++--------------- src/plugins/vcsbase/command.h | 12 ++++++++---- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 59c38d60c68..949705242c8 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -687,12 +687,16 @@ public: ~ConflictHandler() { - GitClient *client = GitPlugin::instance()->gitClient(); - if (m_commit.isEmpty() && m_files.isEmpty()) { - if (client->checkCommandInProgress(m_workingDirectory) == GitClient::NoCommand) - client->endStashScope(m_workingDirectory); - } else { - client->handleMergeConflicts(m_workingDirectory, m_commit, m_files, m_command); + // If interactive rebase editor window is closed, plugin is terminated + // but referenced here when the command ends + if (GitPlugin *plugin = GitPlugin::instance()) { + GitClient *client = plugin->gitClient(); + if (m_commit.isEmpty() && m_files.isEmpty()) { + if (client->checkCommandInProgress(m_workingDirectory) == GitClient::NoCommand) + client->endStashScope(m_workingDirectory); + } else { + client->handleMergeConflicts(m_workingDirectory, m_commit, m_files, m_command); + } } } diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp index 1872f16fabf..1f37b83638e 100644 --- a/src/plugins/vcsbase/command.cpp +++ b/src/plugins/vcsbase/command.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -202,7 +203,7 @@ void Command::execute() return; // For some reason QtConcurrent::run() only works on this - QFuture task = QtConcurrent::run(this, &Command::run); + QFuture task = QtConcurrent::run(&Command::run, this); QString binary = QFileInfo(d->m_binaryPath).baseName(); if (!binary.isEmpty()) binary = binary.replace(0, 1, binary[0].toUpper()); // Upper the first letter @@ -226,7 +227,7 @@ QString Command::msgTimeout(int seconds) return tr("Error: VCS timed out after %1s.").arg(seconds); } -void Command::run() +void Command::run(QFutureInterface &future) { // Check that the binary path is not empty if (binaryPath().trimmed().isEmpty()) { @@ -284,23 +285,25 @@ void Command::run() } } - if (ok && d->m_jobs.front().arguments.at(0) == QLatin1String("status")) - removeColorCodes(&stdOut); + if (!future.isCanceled()) { + if (ok && d->m_jobs.front().arguments.at(0) == QLatin1String("status")) + removeColorCodes(&stdOut); - d->m_lastExecSuccess = ok; - d->m_lastExecExitCode = exitCode; + d->m_lastExecSuccess = ok; + d->m_lastExecExitCode = exitCode; - if (ok) - emit outputData(stdOut); + if (ok) + emit outputData(stdOut); - if (!error.isEmpty()) - emit errorText(error); + if (!error.isEmpty()) + emit errorText(error); - emit finished(ok, exitCode, cookie()); - if (ok) { - emit success(cookie()); - if (d->m_expectChanges) - Core::ICore::vcsManager()->emitRepositoryChanged(d->m_workingDirectory); + emit finished(ok, exitCode, cookie()); + if (ok) { + emit success(cookie()); + if (d->m_expectChanges) + Core::ICore::vcsManager()->emitRepositoryChanged(d->m_workingDirectory); + } } // As it is used asynchronously, we need to delete ourselves diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h index b84bf12cdf8..efc71e46691 100644 --- a/src/plugins/vcsbase/command.h +++ b/src/plugins/vcsbase/command.h @@ -34,9 +34,13 @@ #include -QT_FORWARD_DECLARE_CLASS(QStringList) -QT_FORWARD_DECLARE_CLASS(QVariant) -QT_FORWARD_DECLARE_CLASS(QProcessEnvironment) +QT_BEGIN_NAMESPACE +class QStringList; +class QVariant; +class QProcessEnvironment; +template +class QFutureInterface; +QT_END_NAMESPACE namespace VcsBase { @@ -94,7 +98,7 @@ public: void setCookie(const QVariant &cookie); private: - void run(); + void run(QFutureInterface &future); signals: void outputData(const QByteArray &);