diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index ce8cef68e58f6e37e91f6cd1234da19676b66a92..4ccc4d064af4da450f800f975e18ea3effe604cb 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -386,6 +386,11 @@ void VcsManager::promptToAdd(const QString &directory, const QStringList &fileNa } } +void VcsManager::emitRepositoryChanged(const QString &repository) +{ + emit repositoryChanged(repository); +} + void VcsManager::clearVersionControlCache() { QStringList repoList = d->m_cachedMatches.keys(); diff --git a/src/plugins/coreplugin/vcsmanager.h b/src/plugins/coreplugin/vcsmanager.h index e8f43623a5810f2b74fa68c49de4e3990644bec5..2b8a91463e98a080131c8dc700ac530d58fb039c 100644 --- a/src/plugins/coreplugin/vcsmanager.h +++ b/src/plugins/coreplugin/vcsmanager.h @@ -86,6 +86,8 @@ public: // added to revision control. Calls vcsAdd for each file. void promptToAdd(const QString &directory, const QStringList &fileNames); + void emitRepositoryChanged(const QString &repository); + // Utility messages for adding files static QString msgAddToVcsTitle(); static QString msgPromptToAddToVcs(const QStringList &files, const IVersionControl *vc); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 4df88bd163d4e322fcce58cc673d5cd95b4e664a..6b81b23ffecde046d94b31b3fc61e5a193869a24 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -643,6 +643,7 @@ public: m_command(command) { if (parentCommand) { + parentCommand->setExpectChanges(true); connect(parentCommand, SIGNAL(outputData(QByteArray)), this, SLOT(readStdOut(QByteArray))); connect(parentCommand, SIGNAL(errorText(QString)), this, SLOT(readStdErr(QString))); } @@ -652,7 +653,6 @@ public: { GitClient *client = GitPlugin::instance()->gitClient(); if (m_commit.isEmpty()) { - GitPlugin::instance()->gitVersionControl()->emitRepositoryChanged(m_workingDirectory); if (client->checkCommandInProgress(m_workingDirectory) == GitClient::NoCommand) client->endStashScope(m_workingDirectory); } else { @@ -742,7 +742,6 @@ const char *GitClient::stashNamePrefix = "stash@{"; GitClient::GitClient(GitSettings *settings) : m_cachedGitVersion(0), m_msgWait(tr("Waiting for data...")), - m_repositoryChangedSignalMapper(0), m_settings(settings), m_disableEditor(false) { @@ -1257,7 +1256,7 @@ void GitClient::reset(const QString &workingDirectory, const QString &argument, arguments << commit; VcsBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); - connectRepositoryChanged(workingDirectory, cmd); + cmd->setExpectChanges(true); } void GitClient::addFile(const QString &workingDirectory, const QString &fileName) @@ -1563,7 +1562,8 @@ QString GitClient::synchronousCurrentLocalBranch(const QString &workingDirectory QByteArray outputTextData; QStringList arguments; arguments << QLatin1String("symbolic-ref") << QLatin1String(HEAD); - if (fullySynchronousGit(workingDirectory, arguments, &outputTextData, 0, false)) { + if (fullySynchronousGit(workingDirectory, arguments, &outputTextData, 0, + VcsBasePlugin::SuppressCommandLogging)) { QString branch = commandOutputFromLocal8Bit(outputTextData.trimmed()); const QString refsHeadsPrefix = QLatin1String("refs/heads/"); if (branch.startsWith(refsHeadsPrefix)) { @@ -1693,7 +1693,8 @@ QString GitClient::synchronousTopRevision(const QString &workingDirectory, QStri QString errorMessage; // get revision arguments << QLatin1String("rev-parse") << QLatin1String(HEAD); - if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText, false)) { + if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText, + VcsBasePlugin::SuppressCommandLogging)) { errorMessage = tr("Cannot retrieve top revision of \"%1\": %2") .arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText)); return QString(); @@ -1714,7 +1715,8 @@ void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const { QStringList arguments; arguments << QLatin1String("describe") << QLatin1String("--contains") << revision; - fullySynchronousGit(workingDirectory, arguments, &precedes, 0, false); + fullySynchronousGit(workingDirectory, arguments, &precedes, 0, + VcsBasePlugin::SuppressCommandLogging); int tilde = precedes.indexOf('~'); if (tilde != -1) precedes.truncate(tilde); @@ -1729,7 +1731,8 @@ void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const arguments.clear(); arguments << QLatin1String("describe") << QLatin1String("--tags") << QLatin1String("--abbrev=0") << p; - fullySynchronousGit(workingDirectory, arguments, &pf, 0, false); + fullySynchronousGit(workingDirectory, arguments, &pf, 0, + VcsBasePlugin::SuppressCommandLogging); pf.truncate(pf.lastIndexOf('\n')); if (!pf.isEmpty()) { if (!follows.isEmpty()) @@ -2193,12 +2196,12 @@ bool GitClient::fullySynchronousGit(const QString &workingDirectory, const QStringList &gitArguments, QByteArray* outputText, QByteArray* errorText, - bool logCommandToWindow) const + unsigned flags) const { return VcsBasePlugin::runFullySynchronous(workingDirectory, gitBinaryPath(), gitArguments, processEnvironment(), outputText, errorText, settings()->intValue(GitSettings::timeoutKey) * 1000, - logCommandToWindow); + flags); } void GitClient::submoduleUpdate(const QString &workingDirectory) @@ -2207,7 +2210,7 @@ void GitClient::submoduleUpdate(const QString &workingDirectory) arguments << QLatin1String("submodule") << QLatin1String("update"); VcsBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); - connectRepositoryChanged(workingDirectory, cmd); + cmd->setExpectChanges(true); } void GitClient::promptSubmoduleUpdate(const QString &workingDirectory) @@ -2832,7 +2835,7 @@ void GitClient::fetch(const QString &workingDirectory, const QString &remote) arguments << (remote.isEmpty() ? QLatin1String("--all") : remote); VcsBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); - connectRepositoryChanged(workingDirectory, cmd); + cmd->setExpectChanges(true); } bool GitClient::executeAndHandleConflicts(const QString &workingDirectory, @@ -2840,7 +2843,8 @@ bool GitClient::executeAndHandleConflicts(const QString &workingDirectory, const QString &abortCommand) { // Disable UNIX terminals to suppress SSH prompting. - const unsigned flags = VcsBasePlugin::SshPasswordPrompt | VcsBasePlugin::ShowStdOutInLogWindow; + const unsigned flags = VcsBasePlugin::SshPasswordPrompt | VcsBasePlugin::ShowStdOutInLogWindow + | VcsBasePlugin::ExpectRepoChanges; const Utils::SynchronousProcessResponse resp = synchronousGit(workingDirectory, arguments, flags); ConflictHandler conflictHandler(0, workingDirectory, abortCommand); // Notify about changed files or abort the rebase. @@ -2886,7 +2890,8 @@ void GitClient::synchronousAbortCommand(const QString &workingDir, const QString arguments << abortCommand << QLatin1String("--abort"); QByteArray stdOut; QByteArray stdErr; - const bool rc = fullySynchronousGit(workingDir, arguments, &stdOut, &stdErr, true); + const bool rc = fullySynchronousGit(workingDir, arguments, &stdOut, &stdErr, + VcsBasePlugin::ExpectRepoChanges); outwin->append(commandOutputFromLocal8Bit(stdOut)); if (!rc) outwin->appendError(commandOutputFromLocal8Bit(stdErr)); @@ -2977,7 +2982,7 @@ void GitClient::push(const QString &workingDirectory, const QStringList &pushArg arguments += pushArgs; VcsBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); - connectRepositoryChanged(workingDirectory, cmd); + cmd->setExpectChanges(true); } bool GitClient::synchronousMerge(const QString &workingDirectory, const QString &branch) @@ -3069,7 +3074,7 @@ void GitClient::stashPop(const QString &workingDirectory, const QString &stash) if (!stash.isEmpty()) arguments << stash; VcsBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); - connectRepositoryChanged(workingDirectory, cmd); + cmd->setExpectChanges(true); } void GitClient::stashPop(const QString &workingDirectory) @@ -3192,7 +3197,8 @@ QString GitClient::readConfig(const QString &workingDirectory, const QStringList QByteArray outputText; QByteArray errorText; - if (!fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText, false)) + if (!fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText, + VcsBasePlugin::SuppressCommandLogging)) return QString(); if (Utils::HostOsInfo::isWindowsHost()) return QString::fromUtf8(outputText).remove(QLatin1Char('\r')); @@ -3218,7 +3224,7 @@ bool GitClient::cloneRepository(const QString &directory,const QByteArray &url) QStringList arguments(QLatin1String("remote")); arguments << QLatin1String("add") << QLatin1String("origin") << QLatin1String(url); - if (!fullySynchronousGit(workingDirectory.path(), arguments, 0, 0, true)) + if (!fullySynchronousGit(workingDirectory.path(), arguments, 0)) return false; arguments.clear(); @@ -3232,14 +3238,14 @@ bool GitClient::cloneRepository(const QString &directory,const QByteArray &url) arguments << QLatin1String("config") << QLatin1String("branch.master.remote") << QLatin1String("origin"); - if (!fullySynchronousGit(workingDirectory.path(), arguments, 0, 0, true)) + if (!fullySynchronousGit(workingDirectory.path(), arguments, 0)) return false; arguments.clear(); arguments << QLatin1String("config") << QLatin1String("branch.master.merge") << QLatin1String("refs/heads/master"); - if (!fullySynchronousGit(workingDirectory.path(), arguments, 0, 0, true)) + if (!fullySynchronousGit(workingDirectory.path(), arguments, 0)) return false; return true; @@ -3262,8 +3268,10 @@ QString GitClient::vcsGetRepositoryURL(const QString &directory) arguments << QLatin1String("remote.origin.url"); - if (fullySynchronousGit(directory, arguments, &outputText, 0, false)) + if (fullySynchronousGit(directory, arguments, &outputText, 0, + VcsBasePlugin::SuppressCommandLogging)) { return commandOutputFromLocal8Bit(outputText); + } return QString(); } @@ -3272,19 +3280,6 @@ GitSettings *GitClient::settings() const return m_settings; } -void GitClient::connectRepositoryChanged(const QString & repository, VcsBase::Command *cmd) -{ - // Bind command success termination with repository to changed signal - if (!m_repositoryChangedSignalMapper) { - m_repositoryChangedSignalMapper = new QSignalMapper(this); - connect(m_repositoryChangedSignalMapper, SIGNAL(mapped(QString)), - GitPlugin::instance()->gitVersionControl(), SIGNAL(repositoryChanged(QString))); - } - m_repositoryChangedSignalMapper->setMapping(cmd, repository); - connect(cmd, SIGNAL(success(QVariant)), m_repositoryChangedSignalMapper, SLOT(map()), - Qt::QueuedConnection); -} - // determine version as '(major << 16) + (minor << 8) + patch' or 0. unsigned GitClient::gitVersion(QString *errorMessage) const { @@ -3307,7 +3302,9 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const // run git --version QByteArray outputText; QByteArray errorText; - const bool rc = fullySynchronousGit(QString(), QStringList(QLatin1String("--version")), &outputText, &errorText, false); + const bool rc = fullySynchronousGit(QString(), QStringList(QLatin1String("--version")), + &outputText, &errorText, + VcsBasePlugin::SuppressCommandLogging); if (!rc) { const QString msg = tr("Cannot determine git version: %1").arg(commandOutputFromLocal8Bit(errorText)); if (errorMessage) diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 7565ac6b33d0f07006bef5d888facfae1d9c2839..9cfc17773a8c785b87c188ff66fd098af0a40cc4 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -358,10 +358,10 @@ private: // Fully synchronous git execution (QProcess-based). bool fullySynchronousGit(const QString &workingDirectory, - const QStringList &arguments, - QByteArray* outputText, - QByteArray* errorText = 0, - bool logCommandToWindow = true) const; + const QStringList &arguments, + QByteArray* outputText, + QByteArray* errorText = 0, + unsigned flags = 0) const; // Synchronous git execution using Utils::SynchronousProcess, with // log windows updating (using VcsBasePlugin::runVcs with flags). @@ -391,7 +391,6 @@ private: mutable unsigned m_cachedGitVersion; const QString m_msgWait; - QSignalMapper *m_repositoryChangedSignalMapper; GitSettings *m_settings; QString m_gitQtcEditor; QMap<QString, StashInfo> m_stashInfo; diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp index d6edff387ad90f03d8899bbb0d5ff2a4a02c47c9..335e56ca4b25e3649cfc3880a0069988ce6696aa 100644 --- a/src/plugins/vcsbase/command.cpp +++ b/src/plugins/vcsbase/command.cpp @@ -29,8 +29,10 @@ #include "command.h" +#include <coreplugin/documentmanager.h> #include <coreplugin/icore.h> #include <coreplugin/progressmanager/progressmanager.h> +#include <coreplugin/vcsmanager.h> #include <utils/synchronousprocess.h> #include <QDebug> @@ -80,6 +82,7 @@ public: QVariant m_cookie; bool m_unixTerminalDisabled; int m_defaultTimeout; + bool m_expectChanges; QList<Job> m_jobs; Command::TerminationReportMode m_reportTerminationMode; @@ -96,6 +99,7 @@ CommandPrivate::CommandPrivate(const QString &binary, m_environment(environment), m_unixTerminalDisabled(false), m_defaultTimeout(10), + m_expectChanges(false), m_reportTerminationMode(Command::NoReport), m_lastExecSuccess(false), m_lastExecExitCode(-1) @@ -170,6 +174,16 @@ void Command::setUnixTerminalDisabled(bool e) d->m_unixTerminalDisabled = e; } +bool Command::expectChanges() const +{ + return d->m_expectChanges; +} + +void Command::setExpectChanges(bool e) +{ + d->m_expectChanges = e; +} + void Command::addJob(const QStringList &arguments) { addJob(arguments, defaultTimeout()); @@ -188,6 +202,8 @@ void Command::execute() if (d->m_jobs.empty()) return; + if (d->m_expectChanges) + Core::DocumentManager::expectDirectoryChange(d->m_workingDirectory); // For some reason QtConcurrent::run() only works on this QFuture<void> task = QtConcurrent::run(this, &Command::run); QString binary = QFileInfo(d->m_binaryPath).baseName(); @@ -284,8 +300,15 @@ void Command::run() emit errorText(error); emit finished(ok, exitCode, cookie()); - if (ok) + if (ok) { emit success(cookie()); + if (d->m_expectChanges) + Core::ICore::vcsManager()->emitRepositoryChanged(d->m_workingDirectory); + } + + if (d->m_expectChanges) + Core::DocumentManager::unexpectDirectoryChange(d->m_workingDirectory); + // As it is used asynchronously, we need to delete ourselves this->deleteLater(); } diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h index 5619d702c4434975ef4f2fccdfc3db94a1afa761..b84bf12cdf8b5be0cfecd5435e74a2db653cba0c 100644 --- a/src/plugins/vcsbase/command.h +++ b/src/plugins/vcsbase/command.h @@ -85,6 +85,9 @@ public: bool unixTerminalDisabled() const; void setUnixTerminalDisabled(bool); + bool expectChanges() const; + void setExpectChanges(bool); + static QString msgTimeout(int seconds); const QVariant &cookie() const; diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp index c572e5d542038fb8e11988902f833404ee2d2b50..73a8eb019b9430682476b1c56cf185eaed65d589 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.cpp +++ b/src/plugins/vcsbase/vcsbaseplugin.cpp @@ -34,6 +34,7 @@ #include "vcsbaseoutputwindow.h" #include "corelistener.h" +#include <coreplugin/documentmanager.h> #include <coreplugin/icore.h> #include <coreplugin/id.h> #include <coreplugin/iversioncontrol.h> @@ -920,12 +921,16 @@ SynchronousProcessResponse VcsBasePlugin::runVcs(const QString &workingDir, nsp << "c_locale"; if (flags & FullySynchronously) nsp << "fully_synchronously"; + if (flags & ExpectRepoChanges) + nsp << "expect_repo_changes"; if (outputCodec) nsp << " Codec: " << outputCodec->name(); } VcsBase::VcsBasePlugin::setProcessEnvironment(&env, (flags & ForceCLocale)); + if (flags & ExpectRepoChanges) + Core::DocumentManager::expectDirectoryChange(workingDir); if (flags & FullySynchronously) { response = runVcsFullySynchronously(workingDir, binary, arguments, timeOutMS, env, flags, outputCodec); @@ -974,6 +979,8 @@ SynchronousProcessResponse VcsBasePlugin::runVcs(const QString &workingDir, if (!(flags & SuppressFailMessageInLogWindow)) outputWindow->appendError(response.exitMessage(binary, timeOutMS)); } + if (flags & ExpectRepoChanges) + Core::DocumentManager::unexpectDirectoryChange(workingDir); return response; } @@ -985,14 +992,16 @@ bool VcsBasePlugin::runFullySynchronous(const QString &workingDirectory, QByteArray* outputText, QByteArray* errorText, int timeoutMS, - bool logCommandToWindow) + unsigned flags) { if (binary.isEmpty()) return false; - if (logCommandToWindow) + if (!(flags & SuppressCommandLogging)) VcsBase::VcsBaseOutputWindow::instance()->appendCommand(workingDirectory, binary, arguments); + if (flags & ExpectRepoChanges) + Core::DocumentManager::expectDirectoryChange(workingDirectory); QProcess process; process.setWorkingDirectory(workingDirectory); process.setProcessEnvironment(env); @@ -1014,6 +1023,8 @@ bool VcsBasePlugin::runFullySynchronous(const QString &workingDirectory, SynchronousProcess::stopProcess(process); return false; } + if (flags & ExpectRepoChanges) + Core::DocumentManager::unexpectDirectoryChange(workingDirectory); return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0; } diff --git a/src/plugins/vcsbase/vcsbaseplugin.h b/src/plugins/vcsbase/vcsbaseplugin.h index 092d4be727f1190c7927f454c353b13a6dc9dc96..2e6a87057518b63f2e8907dd75edcb0359915c1d 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.h +++ b/src/plugins/vcsbase/vcsbaseplugin.h @@ -164,8 +164,9 @@ public: SuppressCommandLogging = 0x20, // No command log entry in VCS output window. ShowSuccessMessage = 0x40, // Show message about successful completion in VCS output window. ForceCLocale = 0x80, // Force C-locale for commands whose output is parsed. - FullySynchronously = 0x100 // Suppress local event loop (in case UI actions are + FullySynchronously = 0x100, // Suppress local event loop (in case UI actions are // triggered by file watchers). + ExpectRepoChanges = 0x200 // Expect changes in repository by the command }; static Utils::SynchronousProcessResponse runVcs(const QString &workingDir, @@ -189,7 +190,9 @@ public: const QStringList &arguments, const QProcessEnvironment &env, QByteArray* outputText, - QByteArray *errorText, int timeoutMS, bool logCommandToWindow); + QByteArray *errorText, + int timeoutMS, + unsigned flags); // Utility to run the 'patch' command static bool runPatch(const QByteArray &input, const QString &workingDirectory = QString(),