From ca7a924a068b23815e3915b1f2887eed0e38ef7f Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 5 Jul 2016 10:34:41 +0200 Subject: [PATCH] VCS: VcsBaseClient::vcsFullySynchronousExec returns a SynchronousProcessResponse Change-Id: Ic155da2ed1fd36f1f91327ac90f34a5cad3c210e Reviewed-by: Tobias Hunger --- src/plugins/bazaar/bazaarclient.cpp | 20 +- src/plugins/git/gitclient.cpp | 497 ++++++++++---------- src/plugins/mercurial/mercurialclient.cpp | 50 +- src/plugins/subversion/subversionclient.cpp | 7 +- src/plugins/subversion/subversionplugin.cpp | 10 +- src/plugins/vcsbase/vcsbaseclient.cpp | 54 ++- src/plugins/vcsbase/vcsbaseclient.h | 25 +- 7 files changed, 320 insertions(+), 343 deletions(-) diff --git a/src/plugins/bazaar/bazaarclient.cpp b/src/plugins/bazaar/bazaarclient.cpp index 3fc8293e17c..991f9947419 100644 --- a/src/plugins/bazaar/bazaarclient.cpp +++ b/src/plugins/bazaar/bazaarclient.cpp @@ -110,8 +110,8 @@ bool BazaarClient::synchronousSetUserId() args << QLatin1String("whoami") << (settings().stringValue(BazaarSettings::userNameKey) + QLatin1String(" <") + settings().stringValue(BazaarSettings::userEmailKey) + QLatin1Char('>')); - QByteArray stdOut; - return vcsFullySynchronousExec(QDir::currentPath(), args, &stdOut); + return vcsFullySynchronousExec(QDir::currentPath(), args).result + == SynchronousProcessResponse::Finished; } BranchInfo BazaarClient::synchronousBranchQuery(const QString &repositoryRoot) const @@ -150,11 +150,10 @@ bool BazaarClient::synchronousUncommit(const QString &workingDir, << QLatin1String("--verbose") // Will print out what is being removed << revisionSpec(revision) << extraOptions; - QByteArray stdOut; - const bool success = vcsFullySynchronousExec(workingDir, args, &stdOut); - if (!stdOut.isEmpty()) - VcsOutputWindow::append(QString::fromUtf8(stdOut)); - return success; + + const SynchronousProcessResponse result = vcsFullySynchronousExec(workingDir, args); + VcsOutputWindow::append(result.stdOut()); + return result.result == SynchronousProcessResponse::Finished; } void BazaarClient::commit(const QString &repositoryRoot, const QStringList &files, @@ -187,10 +186,11 @@ bool BazaarClient::managesFile(const QString &workingDirectory, const QString &f { QStringList args(QLatin1String("status")); args << fileName; - QByteArray stdOut; - if (!vcsFullySynchronousExec(workingDirectory, args, &stdOut)) + + const SynchronousProcessResponse result = vcsFullySynchronousExec(workingDirectory, args); + if (result.result != SynchronousProcessResponse::Finished) return false; - return !stdOut.startsWith("unknown"); + return result.rawStdOut.startsWith("unknown"); } void BazaarClient::view(const QString &source, const QString &id, const QStringList &extraOptions) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index b526fb980e4..c6fd273706f 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -103,7 +103,8 @@ static unsigned diffExecutionFlags() } const unsigned silentFlags = unsigned(VcsCommand::SuppressCommandLogging - | VcsCommand::SuppressStdErr); + | VcsCommand::SuppressStdErr + | VcsCommand::SuppressFailMessage); ///////////////////////////////////// @@ -567,12 +568,12 @@ static inline void msgCannotRun(const QString &message, QString *errorMessage) } static inline void msgCannotRun(const QStringList &args, const QString &workingDirectory, - const QByteArray &error, QString *errorMessage) + const QString &error, QString *errorMessage) { const QString message = GitClient::tr("Cannot run \"%1\" in \"%2\": %3") .arg("git " + args.join(' '), QDir::toNativeSeparators(workingDirectory), - GitClient::commandOutputFromLocal8Bit(error)); + error); msgCannotRun(message, errorMessage); } @@ -625,9 +626,8 @@ QString GitClient::findGitDirForRepository(const QString &repositoryDir) const bool GitClient::managesFile(const QString &workingDirectory, const QString &fileName) const { - QByteArray output; - const QStringList arguments = { "ls-files", "--error-unmatch", fileName }; - return vcsFullySynchronousExec(workingDirectory, arguments, &output, 0, silentFlags); + return vcsFullySynchronousExec(workingDirectory, { "ls-files", "--error-unmatch", fileName }).result + == SynchronousProcessResponse::Finished; } QTextCodec *GitClient::codecFor(GitClient::CodecType codecType, const QString &source) const @@ -938,17 +938,17 @@ bool GitClient::synchronousCheckout(const QString &workingDirectory, const QString &ref, QString *errorMessage) { - QByteArray outputText; - QByteArray errorText; QStringList arguments = setupCheckoutArguments(workingDirectory, ref); - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, 0, - VcsCommand::ExpectRepoChanges); - VcsOutputWindow::append(commandOutputFromLocal8Bit(outputText)); - if (rc) + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, VcsCommand::ExpectRepoChanges); + VcsOutputWindow::append(resp.stdOut()); + if (resp.result == SynchronousProcessResponse::Finished) { updateSubmodulesIfNeeded(workingDirectory, true); - else - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); - return rc; + return true; + } else { + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); + return false; + } } /* method used to setup arguments for checkout, in case user wants to create local branch */ @@ -1044,76 +1044,72 @@ void GitClient::addFile(const QString &workingDirectory, const QString &fileName bool GitClient::synchronousLog(const QString &workingDirectory, const QStringList &arguments, QString *output, QString *errorMessageIn, unsigned flags) { - QByteArray outputData; - QByteArray errorData; QStringList allArguments = { "log", noColorOption }; allArguments.append(arguments); - const bool rc = vcsFullySynchronousExec(workingDirectory, allArguments, &outputData, &errorData, flags); - if (rc) { - if (QTextCodec *codec = encoding(workingDirectory, "i18n.logOutputEncoding")) - *output = codec->toUnicode(outputData); - else - *output = commandOutputFromLocal8Bit(outputData); + + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, allArguments, flags, vcsTimeoutS(), + encoding(workingDirectory, "i18n.logOutputEncoding")); + if (resp.result == SynchronousProcessResponse::Finished) { + *output = resp.stdOut(); + return true; } else { msgCannotRun(tr("Cannot obtain log of \"%1\": %2") - .arg(QDir::toNativeSeparators(workingDirectory), - commandOutputFromLocal8Bit(errorData)), errorMessageIn); - + .arg(QDir::toNativeSeparators(workingDirectory), resp.stdErr()), errorMessageIn); + return false; } - return rc; } bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringList &files) { - QByteArray outputText; - return vcsFullySynchronousExec(workingDirectory, QStringList({ "add" }) + files, &outputText); + return vcsFullySynchronousExec(workingDirectory, QStringList({ "add" }) + files).result + == SynchronousProcessResponse::Finished; } bool GitClient::synchronousDelete(const QString &workingDirectory, bool force, const QStringList &files) { - QByteArray outputText; QStringList arguments = { "rm" }; if (force) arguments << "--force"; arguments.append(files); - return vcsFullySynchronousExec(workingDirectory, arguments, &outputText); + return vcsFullySynchronousExec(workingDirectory, arguments).result + == SynchronousProcessResponse::Finished; } bool GitClient::synchronousMove(const QString &workingDirectory, const QString &from, const QString &to) { - QByteArray outputText; - return vcsFullySynchronousExec(workingDirectory, { "mv", from, to }, &outputText); + return vcsFullySynchronousExec(workingDirectory, { "mv", from, to }).result + == SynchronousProcessResponse::Finished; } bool GitClient::synchronousReset(const QString &workingDirectory, const QStringList &files, QString *errorMessage) { - QByteArray outputText; - QByteArray errorText; QStringList arguments = { "reset" }; if (files.isEmpty()) arguments << "--hard"; else arguments << HEAD << "--" << files; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText); - const QString output = commandOutputFromLocal8Bit(outputText); - VcsOutputWindow::append(output); + + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments); + const QString stdOut = resp.stdOut(); + VcsOutputWindow::append(stdOut); // Note that git exits with 1 even if the operation is successful // Assume real failure if the output does not contain "foo.cpp modified" // or "Unstaged changes after reset" (git 1.7.0). - if (!rc && (!output.contains("modified") && !output.contains("Unstaged changes after reset"))) { + if (resp.result == SynchronousProcessResponse::Finished + && (!stdOut.contains("modified") && !stdOut.contains("Unstaged changes after reset"))) { if (files.isEmpty()) { - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); } else { msgCannotRun(tr("Cannot reset %n file(s) in \"%1\": %2", 0, files.size()) - .arg(QDir::toNativeSeparators(workingDirectory), - commandOutputFromLocal8Bit(errorText)), + .arg(QDir::toNativeSeparators(workingDirectory), resp.stdErr()), errorMessage); } return false; @@ -1124,13 +1120,15 @@ bool GitClient::synchronousReset(const QString &workingDirectory, // Initialize repository bool GitClient::synchronousInit(const QString &workingDirectory) { - QByteArray outputText; - const bool rc = vcsFullySynchronousExec(workingDirectory, { "init" }, &outputText); + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, { "init" }); // '[Re]Initialized...' - VcsOutputWindow::append(commandOutputFromLocal8Bit(outputText)); - if (rc) + VcsOutputWindow::append(resp.stdOut()); + if (resp.result == SynchronousProcessResponse::Finished) { resetCachedVcsInfo(workingDirectory); - return rc; + return true; + } else { + return false; + } } /* Checkout, supports: @@ -1145,21 +1143,18 @@ bool GitClient::synchronousCheckoutFiles(const QString &workingDirectory, QStrin revision = HEAD; if (files.isEmpty()) files = QStringList("."); - QByteArray outputText; - QByteArray errorText; QStringList arguments = { "checkout" }; if (revertStaging) arguments << revision; arguments << "--" << files; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText, - VcsCommand::ExpectRepoChanges); - if (!rc) { + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, VcsCommand::ExpectRepoChanges); + if (resp.result != SynchronousProcessResponse::Finished) { const QString fileArg = files.join(", "); //: Meaning of the arguments: %1: revision, %2: files, %3: repository, //: %4: Error message msgCannotRun(tr("Cannot checkout \"%1\" of %2 in \"%3\": %4") - .arg(revision, fileArg, workingDirectory, - commandOutputFromLocal8Bit(errorText)), + .arg(revision, fileArg, workingDirectory, resp.stdErr()), errorMessage); return false; } @@ -1212,16 +1207,14 @@ static inline bool splitCommitParents(const QString &line, bool GitClient::synchronousRevListCmd(const QString &workingDirectory, const QStringList &extraArguments, QString *output, QString *errorMessage) const { - QByteArray outputTextData; - QByteArray errorText; const QStringList arguments = QStringList({ "rev-list", noColorOption }) + extraArguments; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData, - &errorText, silentFlags); - if (!rc) { - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, silentFlags); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); return false; } - *output = commandOutputFromLocal8Bit(outputTextData); + *output = resp.stdOut(); return true; } @@ -1273,11 +1266,11 @@ QString GitClient::synchronousShortDescription(const QString &workingDirectory, QString GitClient::synchronousCurrentLocalBranch(const QString &workingDirectory) const { - QByteArray outputTextData; QString branch; - if (vcsFullySynchronousExec(workingDirectory, { "symbolic-ref", HEAD }, &outputTextData, 0, - silentFlags)) { - branch = commandOutputFromLocal8Bit(outputTextData.trimmed()); + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, { "symbolic-ref", HEAD }, silentFlags); + if (resp.result == SynchronousProcessResponse::Finished) { + branch = resp.stdOut().trimmed(); } else { const QString gitDir = findGitDirForRepository(workingDirectory); const QString rebaseHead = gitDir + "/rebase-merge/head-name"; @@ -1299,27 +1292,25 @@ bool GitClient::synchronousHeadRefs(const QString &workingDirectory, QStringList QString *errorMessage) const { const QStringList arguments = { "show-ref", "--head", "--abbrev=10", "--dereference" }; - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText, - silentFlags); - if (!rc) { - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, silentFlags); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); return false; } - QByteArray headSha = outputText.left(10); - QByteArray newLine("\n"); + const QString stdOut = resp.stdOut(); + const QString headSha = stdOut.left(10); + const QChar newLine('\n'); int currentIndex = 15; while (true) { - currentIndex = outputText.indexOf(headSha, currentIndex); + currentIndex = stdOut.indexOf(headSha, currentIndex); if (currentIndex < 0) break; currentIndex += 11; - output->append(QString::fromLocal8Bit(outputText.mid(currentIndex, - outputText.indexOf(newLine, currentIndex) - currentIndex))); + output->append(stdOut.mid(currentIndex, stdOut.indexOf(newLine, currentIndex) - currentIndex)); } return true; @@ -1356,11 +1347,12 @@ QString GitClient::synchronousTopic(const QString &workingDirectory) const return remoteBranch; // No tag or remote branch - try git describe - QByteArray output; - if (vcsFullySynchronousExec(workingDirectory, { "describe" }, &output, 0, VcsCommand::NoOutput)) { - const QString describeOutput = commandOutputFromLocal8Bit(output.trimmed()); - if (!describeOutput.isEmpty()) - return describeOutput; + const SynchronousProcessResponse resp = + vcsFullySynchronousExec(workingDirectory, { "describe" }, VcsCommand::NoOutput); + if (resp.result == SynchronousProcessResponse::Finished) { + const QString stdOut = resp.stdOut().trimmed(); + if (!stdOut.isEmpty()) + return stdOut; } return tr("Detached HEAD"); } @@ -1369,15 +1361,15 @@ bool GitClient::synchronousRevParseCmd(const QString &workingDirectory, const QS QString *output, QString *errorMessage) const { const QStringList arguments = { "rev-parse", ref }; - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText, - silentFlags); - *output = commandOutputFromLocal8Bit(outputText.trimmed()); - if (!rc) - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, silentFlags); + *output = resp.stdOut().trimmed(); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); + return false; + } - return rc; + return true; } // Retrieve head revision @@ -1393,28 +1385,27 @@ QString GitClient::synchronousTopRevision(const QString &workingDirectory, QStri void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const QString &revision, QString &precedes, QString &follows) const { - QByteArray pr; - vcsFullySynchronousExec(workingDirectory, { "describe", "--contains", revision }, - &pr, 0, silentFlags); - int tilde = pr.indexOf('~'); + const SynchronousProcessResponse resp1 = vcsFullySynchronousExec( + workingDirectory, { "describe", "--contains", revision }, silentFlags); + precedes = resp1.stdOut(); + int tilde = precedes.indexOf('~'); if (tilde != -1) - pr.truncate(tilde); + precedes.truncate(tilde); else - pr = pr.trimmed(); - precedes = QString::fromLocal8Bit(pr); + precedes = precedes.trimmed(); QStringList parents; QString errorMessage; synchronousParentRevisions(workingDirectory, revision, &parents, &errorMessage); foreach (const QString &p, parents) { - QByteArray pf; - vcsFullySynchronousExec(workingDirectory, { "describe", "--tags", "--abbrev=0", p }, - &pf, 0, silentFlags); + const SynchronousProcessResponse resp2 = vcsFullySynchronousExec( + workingDirectory, { "describe", "--tags", "--abbrev=0", p }, silentFlags); + QString pf = resp2.stdOut(); pf.truncate(pf.lastIndexOf('\n')); if (!pf.isEmpty()) { if (!follows.isEmpty()) follows += ", "; - follows += QString::fromLocal8Bit(pf); + follows += pf; } } } @@ -1432,41 +1423,31 @@ void GitClient::branchesForCommit(const QString &revision) bool GitClient::isRemoteCommit(const QString &workingDirectory, const QString &commit) { - QByteArray outputText; - vcsFullySynchronousExec(workingDirectory, { "branch", "-r", "--contains", commit }, - &outputText, 0, silentFlags); - return !outputText.isEmpty(); + return !vcsFullySynchronousExec( + workingDirectory, { "branch", "-r", "--contains", commit }, silentFlags).rawStdOut.isEmpty(); } bool GitClient::isFastForwardMerge(const QString &workingDirectory, const QString &branch) { - QByteArray outputText; - vcsFullySynchronousExec(workingDirectory, { "merge-base", HEAD, branch }, - &outputText, 0, silentFlags); - return commandOutputFromLocal8Bit(outputText).trimmed() - == synchronousTopRevision(workingDirectory); + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, { "merge-base", HEAD, branch }, silentFlags); + return resp.stdOut().trimmed() == synchronousTopRevision(workingDirectory); } // Format an entry in a one-liner for selection list using git log. QString GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision, const QString &format) const { - QString description; - QByteArray outputTextData; - QByteArray errorText; const QStringList arguments = { "log", noColorOption, ("--pretty=format:" + format), "--max-count=1", revision }; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData, &errorText, - silentFlags); - if (!rc) { + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, silentFlags); + if (resp.result != SynchronousProcessResponse::Finished) { VcsOutputWindow::appendSilently(tr("Cannot describe revision \"%1\" in \"%2\": %3") - .arg(revision, workingDirectory, commandOutputFromLocal8Bit(errorText))); + .arg(revision, workingDirectory, resp.stdErr())); return revision; } - description = commandOutputFromLocal8Bit(outputTextData); - if (description.endsWith('\n')) - description.truncate(description.size() - 1); - return description; + return stripLastNewline(resp.stdOut()); } // Create a default message to be used for describing stashes @@ -1540,12 +1521,13 @@ bool GitClient::executeSynchronousStash(const QString &workingDirectory, const unsigned flags = VcsCommand::ShowStdOut | VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage; - const SynchronousProcessResponse response = vcsSynchronousExec(workingDirectory, arguments, flags); - const bool rc = response.result == SynchronousProcessResponse::Finished; - if (!rc) - msgCannotRun(arguments, workingDirectory, response.rawStdErr, errorMessage); + const SynchronousProcessResponse resp = vcsSynchronousExec(workingDirectory, arguments, flags); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); + return false; + } - return rc; + return true; } // Resolve a stash name from message @@ -1578,43 +1560,40 @@ bool GitClient::synchronousBranchCmd(const QString &workingDirectory, QStringLis QString *output, QString *errorMessage) const { branchArgs.push_front("branch"); - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, branchArgs, &outputText, &errorText); - *output = commandOutputFromLocal8Bit(outputText); - if (!rc) - msgCannotRun(branchArgs, workingDirectory, errorText, errorMessage); - - return rc; + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, branchArgs); + *output = resp.stdOut(); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(branchArgs, workingDirectory, resp.stdErr(), errorMessage); + return false; + } + return true; } bool GitClient::synchronousTagCmd(const QString &workingDirectory, QStringList tagArgs, QString *output, QString *errorMessage) const { tagArgs.push_front("tag"); - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, tagArgs, &outputText, &errorText); - *output = commandOutputFromLocal8Bit(outputText); - if (!rc) - msgCannotRun(tagArgs, workingDirectory, errorText, errorMessage); - - return rc; + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, tagArgs); + *output = resp.stdOut(); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(tagArgs, workingDirectory, resp.stdErr(), errorMessage); + return false; + } + return true; } bool GitClient::synchronousForEachRefCmd(const QString &workingDirectory, QStringList args, QString *output, QString *errorMessage) const { args.push_front("for-each-ref"); - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, args, &outputText, &errorText, - silentFlags); - *output = SynchronousProcess::normalizeNewlines(QString::fromUtf8(outputText)); - if (!rc) - msgCannotRun(args, workingDirectory, errorText, errorMessage); - - return rc; + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args, + silentFlags); + *output = resp.stdOut(); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(args, workingDirectory, resp.stdErr(), errorMessage); + return false; + } + return true; } VcsCommand *GitClient::asyncForEachRefCmd(const QString &workingDirectory, QStringList args) const @@ -1627,15 +1606,17 @@ bool GitClient::synchronousRemoteCmd(const QString &workingDirectory, QStringLis QString *output, QString *errorMessage, bool silent) const { remoteArgs.push_front("remote"); - QByteArray outputText; - QByteArray errorText; - if (!vcsFullySynchronousExec(workingDirectory, remoteArgs, &outputText, &errorText, - silent ? silentFlags : 0)) { - msgCannotRun(remoteArgs, workingDirectory, errorText, errorMessage); + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, remoteArgs, + silent ? silentFlags : 0); + + const QString stdErr = resp.stdErr(); + *errorMessage = stdErr; + *output = resp.stdOut(); + + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(remoteArgs, workingDirectory, stdErr, errorMessage); return false; } - if (output) - *output = commandOutputFromLocal8Bit(outputText); return true; } @@ -1643,6 +1624,7 @@ QMap GitClient::synchronousRemotesList(const QString &workingDi QString *errorMessage) const { QMap result; + QString output; QString error; if (!synchronousRemoteCmd(workingDirectory, { "-v" }, &output, &error, true)) { @@ -1658,7 +1640,7 @@ QMap GitClient::synchronousRemotesList(const QString &workingDi const int tabIndex = remote.indexOf('\t'); if (tabIndex == -1) continue; - QString url = remote.mid(tabIndex + 1, remote.length() - tabIndex - 8); + const QString url = remote.mid(tabIndex + 1, remote.length() - tabIndex - 8); result.insert(remote.left(tabIndex), url); } return result; @@ -1667,17 +1649,16 @@ QMap GitClient::synchronousRemotesList(const QString &workingDi QStringList GitClient::synchronousSubmoduleStatus(const QString &workingDirectory, QString *errorMessage) const { - QByteArray outputTextData; - QByteArray errorText; // get submodule status - if (!vcsFullySynchronousExec(workingDirectory, { "submodule", "status" }, - &outputTextData, &errorText, silentFlags)) { + const SynchronousProcessResponse resp = + vcsFullySynchronousExec(workingDirectory, { "submodule", "status" }, silentFlags); + + if (resp.result != SynchronousProcessResponse::Finished) { msgCannotRun(tr("Cannot retrieve submodule status of \"%1\": %2") - .arg(QDir::toNativeSeparators(workingDirectory), - commandOutputFromLocal8Bit(errorText)), errorMessage); + .arg(QDir::toNativeSeparators(workingDirectory), resp.stdErr()), errorMessage); return QStringList(); } - return commandOutputLinesFromLocal8Bit(outputTextData); + return splitLines(resp.stdOut()); } SubmoduleDataMap GitClient::submoduleList(const QString &workingDirectory) const @@ -1750,11 +1731,13 @@ bool GitClient::synchronousShow(const QString &workingDirectory, const QString & return false; } const QStringList arguments = { "show", decorateOption, noColorOption, id }; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, output, &errorText); - if (!rc) - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); - return rc; + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); + return false; + } + *output = resp.rawStdOut; + return true; } // Retrieve list of files to be cleaned @@ -1763,17 +1746,17 @@ bool GitClient::cleanList(const QString &workingDirectory, const QString &module { const QString directory = workingDirectory + '/' + modulePath; const QStringList arguments = { "clean", "--dry-run", flag }; - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(directory, arguments, &outputText, &errorText); - if (!rc) { - msgCannotRun(arguments, directory, errorText, errorMessage); + + const SynchronousProcessResponse resp = vcsFullySynchronousExec(directory, arguments); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(arguments, directory, resp.stdErr(), errorMessage); return false; } + // Filter files that git would remove const QString relativeBase = modulePath.isEmpty() ? QString() : modulePath + '/'; const QString prefix = "Would remove "; - foreach (const QString &line, commandOutputLinesFromLocal8Bit(outputText)) { + foreach (const QString &line, resp.stdOut()) { if (line.startsWith(prefix)) files->push_back(relativeBase + line.mid(prefix.size())); } @@ -1806,19 +1789,19 @@ bool GitClient::synchronousApplyPatch(const QString &workingDirectory, { QStringList arguments = { "apply", "--whitespace=fix" }; arguments << extraArguments << file; - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText); - if (rc) { - if (!errorText.isEmpty()) + + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments); + const QString stdErr = resp.stdErr(); + if (resp.result == SynchronousProcessResponse::Finished) { + if (!stdErr.isEmpty()) *errorMessage = tr("There were warnings while applying \"%1\" to \"%2\":\n%3") - .arg(file, workingDirectory, commandOutputFromLocal8Bit(errorText)); + .arg(file, workingDirectory, stdErr); + return true; } else { *errorMessage = tr("Cannot apply patch \"%1\" to \"%2\": %3") - .arg(file, workingDirectory, commandOutputFromLocal8Bit(errorText)); + .arg(QDir::toNativeSeparators(file), workingDirectory, stdErr); return false; } - return true; } QProcessEnvironment GitClient::processEnvironment() const @@ -1932,8 +1915,6 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, St QString *output, QString *errorMessage) const { // Run 'status'. Note that git returns exitcode 1 if there are no added files. - QByteArray outputText; - QByteArray errorText; QStringList arguments = { "status" }; if (mode & NoUntracked) arguments << "--untracked-files=no"; @@ -1943,27 +1924,28 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, St arguments << "--ignore-submodules=all"; arguments << "--porcelain" << "-b"; - const bool statusRc = vcsFullySynchronousExec(workingDirectory, arguments, - &outputText, &errorText, silentFlags); + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, silentFlags); + const QString stdOut = resp.stdOut(); + if (output) - *output = commandOutputFromLocal8Bit(outputText); + *output = stdOut; - static const char * NO_BRANCH = "## HEAD (no branch)\n"; - - const bool branchKnown = !outputText.startsWith(NO_BRANCH); + const bool statusRc = resp.result == SynchronousProcessResponse::Finished; + const bool branchKnown = !stdOut.startsWith("## HEAD (no branch)\n"); // Is it something really fatal? if (!statusRc && !branchKnown) { if (errorMessage) { - const QString error = commandOutputFromLocal8Bit(errorText); - *errorMessage = tr("Cannot obtain status: %1").arg(error); + *errorMessage = tr("Cannot obtain status: %1").arg(resp.stdErr()); } return StatusFailed; } // Unchanged (output text depending on whether -u was passed) - QList lines = outputText.split('\n'); - foreach (const QByteArray &line, lines) + QList lines = resp.stdOut().split('\n'); + foreach (const QString &line, lines) { if (!line.isEmpty() && !line.startsWith('#')) return StatusChanged; + } return StatusUnchanged; } @@ -2291,20 +2273,25 @@ bool GitClient::readDataFromCommit(const QString &repoDirectory, const QString & { // Get commit data as "SHA1authoremailmessage". const QStringList arguments = { "log", "--max-count=1", "--pretty=format:%h\n%an\n%ae\n%B", commit }; - QByteArray outputText; - if (!vcsFullySynchronousExec(repoDirectory, arguments, &outputText, 0, silentFlags)) { - if (errorMessage) - *errorMessage = tr("Cannot retrieve last commit data of repository \"%1\".").arg(repoDirectory); + const SynchronousProcessResponse resp = vcsFullySynchronousExec(repoDirectory, arguments, silentFlags); + + if (resp.result != SynchronousProcessResponse::Finished) { + if (errorMessage) { + *errorMessage = tr("Cannot retrieve last commit data of repository \"%1\".") + .arg(QDir::toNativeSeparators(repoDirectory)); + } return false; } + QTextCodec *authorCodec = HostOsInfo::isWindowsHost() ? QTextCodec::codecForName("UTF-8") : commitData.commitEncoding; - commitData.amendSHA1 = QLatin1String(shiftLogLine(outputText)); - commitData.panelData.author = authorCodec->toUnicode(shiftLogLine(outputText)); - commitData.panelData.email = authorCodec->toUnicode(shiftLogLine(outputText)); + QByteArray stdOut = resp.rawStdOut; + commitData.amendSHA1 = QLatin1String(shiftLogLine(stdOut)); + commitData.panelData.author = authorCodec->toUnicode(shiftLogLine(stdOut)); + commitData.panelData.email = authorCodec->toUnicode(shiftLogLine(stdOut)); if (commitTemplate) - *commitTemplate = commitData.commitEncoding->toUnicode(outputText); + *commitTemplate = commitData.commitEncoding->toUnicode(stdOut); return true; } @@ -2539,19 +2526,16 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory, arguments << "--no-verify"; } - QByteArray outputText; - QByteArray errorText; - - const bool rc = vcsFullySynchronousExec(repositoryDirectory, arguments, &outputText, &errorText); - const QString stdErr = commandOutputFromLocal8Bit(errorText); - if (rc) { + const SynchronousProcessResponse resp = vcsFullySynchronousExec(repositoryDirectory, arguments); + const QString stdErr = resp.stdErr(); + if (resp.result == SynchronousProcessResponse::Finished) { VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount)); VcsOutputWindow::appendError(stdErr); + return true; } else { VcsOutputWindow::appendError(tr("Cannot commit %n file(s): %1\n", 0, commitCount).arg(stdErr)); + return false; } - - return rc; } /* Revert: This function can be called with a file list (to revert single @@ -2715,10 +2699,10 @@ void GitClient::synchronousAbortCommand(const QString &workingDir, const QString QStringList(), QString(), nullptr, false); return; } - QByteArray stdOut; - vcsFullySynchronousExec(workingDir, { abortCommand, "--abort" }, &stdOut, nullptr, - VcsCommand::ExpectRepoChanges); - VcsOutputWindow::append(commandOutputFromLocal8Bit(stdOut)); + + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDir, { abortCommand, "--abort" }, VcsCommand::ExpectRepoChanges); + VcsOutputWindow::append(resp.stdOut()); } QString GitClient::synchronousTrackingBranch(const QString &workingDirectory, const QString &branch) @@ -2741,9 +2725,9 @@ QString GitClient::synchronousTrackingBranch(const QString &workingDirectory, co bool GitClient::synchronousSetTrackingBranch(const QString &workingDirectory, const QString &branch, const QString &tracking) { - QByteArray outputText; return vcsFullySynchronousExec( - workingDirectory, { "branch", "--set-upstream-to=" + tracking, branch }, &outputText); + workingDirectory, { "branch", "--set-upstream-to=" + tracking, branch }).result + == SynchronousProcessResponse::Finished; } void GitClient::handleMergeConflicts(const QString &workingDir, const QString &commit, @@ -2962,35 +2946,35 @@ bool GitClient::synchronousStashRemove(const QString &workingDirectory, const QS arguments << "clear"; else arguments << "drop" << stash; - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText); - if (rc) { - const QString output = commandOutputFromLocal8Bit(outputText); + + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments); + if (resp.result == SynchronousProcessResponse::Finished) { + const QString output = resp.stdOut(); if (!output.isEmpty()) VcsOutputWindow::append(output); + return true; } else { - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); + return false; } - return rc; } bool GitClient::synchronousStashList(const QString &workingDirectory, QList *stashes, QString *errorMessage) const { stashes->clear(); - QByteArray outputText; - QByteArray errorText; + const QStringList arguments = { "stash", "list", noColorOption }; - const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText); - if (!rc) { - msgCannotRun(arguments, workingDirectory, errorText, errorMessage); + const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage); return false; } Stash stash; - foreach (const QString &line, commandOutputLinesFromLocal8Bit(outputText)) + foreach (const QString &line, splitLines(resp.stdOut())) { if (stash.parseStashLine(line)) stashes->push_back(stash); + } return true; } @@ -3013,13 +2997,11 @@ QString GitClient::readOneLine(const QString &workingDirectory, const QStringLis ? QTextCodec::codecForName("UTF-8") : QTextCodec::codecForLocale(); - QByteArray outputText; - if (!vcsFullySynchronousExec(workingDirectory, arguments, &outputText, 0, silentFlags)) + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory, arguments, silentFlags, vcsTimeoutS(), codec); + if (resp.result != SynchronousProcessResponse::Finished) return QString(); - if (HostOsInfo::isWindowsHost()) - outputText.replace("\r\n", "\n"); - - return SynchronousProcess::normalizeNewlines(codec->toUnicode(outputText.trimmed())); + return resp.stdOut().trimmed(); } bool GitClient::cloneRepository(const QString &directory,const QByteArray &url) @@ -3032,27 +3014,25 @@ bool GitClient::cloneRepository(const QString &directory,const QByteArray &url) if (!synchronousInit(workingDirectory.path())) return false; - if (!vcsFullySynchronousExec(workingDirectory.path(), - { "remote", "add", "origin", QString::fromUtf8(url) }, nullptr)) { - return false; - } - - const SynchronousProcessResponse resp - = vcsSynchronousExec(workingDirectory.path(), { "fetch" }, flags); + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory.path(), { "remote", "add", "origin", QString::fromUtf8(url) }); if (resp.result != SynchronousProcessResponse::Finished) return false; - if (!vcsFullySynchronousExec(workingDirectory.path(), - { "config", "branch.master.remote", "origin" }, nullptr)) { + const SynchronousProcessResponse resp1 = vcsSynchronousExec( + workingDirectory.path(), { "fetch" }, flags); + if (resp1.result != SynchronousProcessResponse::Finished) return false; - } - if (!vcsFullySynchronousExec(workingDirectory.path(), - { "config", "branch.master.merge", "refs/heads/master" }, nullptr)) { + const SynchronousProcessResponse resp2 = vcsSynchronousExec( + workingDirectory.path(), { "config", "branch.master.remote", "origin" }, flags); + if (resp2.result != SynchronousProcessResponse::Finished) return false; - } - return true; + const SynchronousProcessResponse resp3 = vcsSynchronousExec( + workingDirectory.path(), + { "config", "branch.master.merge", "refs/heads/master" }, flags); + return resp3.result == SynchronousProcessResponse::Finished; } else { workingDirectory.cdUp(); const SynchronousProcessResponse resp = vcsSynchronousExec( @@ -3083,19 +3063,16 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const return 0; // run git --version - QByteArray outputText; - QByteArray errorText; - const bool rc = vcsFullySynchronousExec(QString(), { "--version" }, - &outputText, &errorText, silentFlags); - if (!rc) { - msgCannotRun(tr("Cannot determine Git version: %1") - .arg(commandOutputFromLocal8Bit(errorText)), - errorMessage); + const SynchronousProcessResponse resp = vcsSynchronousExec( + QString(), { "--version" }, silentFlags); + if (resp.result != SynchronousProcessResponse::Finished) { + msgCannotRun(tr("Cannot determine Git version: %1").arg(resp.stdErr()), errorMessage); return 0; } + // cut 'git version 1.6.5.1.sha' // another form: 'git version 1.9.rc1' - const QString output = commandOutputFromLocal8Bit(outputText); + const QString output = resp.stdOut(); QRegExp versionPattern("^[^\\d]+(\\d+)\\.(\\d+)\\.(\\d+|rc\\d).*$"); QTC_ASSERT(versionPattern.isValid(), return 0); QTC_ASSERT(versionPattern.exactMatch(output), return 0); diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index abc4835ed89..21149bce989 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -73,12 +73,12 @@ bool MercurialClient::manifestSync(const QString &repository, const QString &rel // This only works when called from the repo and outputs paths relative to it. const QStringList args(QLatin1String("manifest")); - QByteArray output; - vcsFullySynchronousExec(repository, args, &output); + const SynchronousProcessResponse result = vcsFullySynchronousExec(repository, args); + const QDir repositoryDir(repository); const QFileInfo needle = QFileInfo(repositoryDir, relativeFilename); - const QStringList files = QString::fromLocal8Bit(output).split(QLatin1Char('\n')); + const QStringList files = result.stdOut().split(QLatin1Char('\n')); foreach (const QString &fileName, files) { const QFileInfo managedFile(repositoryDir, fileName); if (needle == managedFile) @@ -96,7 +96,6 @@ bool MercurialClient::synchronousClone(const QString &workingDir, Q_UNUSED(workingDir); Q_UNUSED(extraOptions); QDir workingDirectory(srcLocation); - QByteArray output; const unsigned flags = VcsCommand::SshPasswordPrompt | VcsCommand::ShowStdOut | VcsCommand::ShowSuccessMessage; @@ -104,14 +103,16 @@ bool MercurialClient::synchronousClone(const QString &workingDir, if (workingDirectory.exists()) { // Let's make first init QStringList arguments(QLatin1String("init")); - if (!vcsFullySynchronousExec(workingDirectory.path(), arguments, &output)) + const SynchronousProcessResponse resp = vcsFullySynchronousExec( + workingDirectory.path(), arguments); + if (resp.result != SynchronousProcessResponse::Finished) return false; // Then pull remote repository arguments.clear(); arguments << QLatin1String("pull") << dstLocation; - const SynchronousProcessResponse resp1 = - vcsSynchronousExec(workingDirectory.path(), arguments, flags); + const SynchronousProcessResponse resp1 = vcsSynchronousExec( + workingDirectory.path(), arguments, flags); if (resp1.result != SynchronousProcessResponse::Finished) return false; @@ -127,15 +128,15 @@ bool MercurialClient::synchronousClone(const QString &workingDir, // And last update repository arguments.clear(); arguments << QLatin1String("update"); - const SynchronousProcessResponse resp2 = - vcsSynchronousExec(workingDirectory.path(), arguments, flags); + const SynchronousProcessResponse resp2 = vcsSynchronousExec( + workingDirectory.path(), arguments, flags); return resp2.result == SynchronousProcessResponse::Finished; } else { QStringList arguments(QLatin1String("clone")); arguments << dstLocation << workingDirectory.dirName(); workingDirectory.cdUp(); - const SynchronousProcessResponse resp = - vcsSynchronousExec(workingDirectory.path(), arguments, flags); + const SynchronousProcessResponse resp = vcsSynchronousExec( + workingDirectory.path(), arguments, flags); return resp.result == SynchronousProcessResponse::Finished; } } @@ -194,24 +195,22 @@ QStringList MercurialClient::parentRevisionsSync(const QString &workingDirectory args << QLatin1String("parents") << QLatin1String("-r") <vcsBinary(); SubversionResponse response; - if (executable.isEmpty()) { + if (client()->vcsBinary().isEmpty()) { response.error = true; response.message =tr("No subversion executable specified."); return response; } - const SynchronousProcessResponse sp_resp = - VcsBasePlugin::runVcs(workingDir, executable, arguments, timeOutS, - flags, outputCodec); + const SynchronousProcessResponse sp_resp + = client()->vcsFullySynchronousExec(workingDir, arguments, flags, timeOutS, outputCodec); response.error = sp_resp.result != SynchronousProcessResponse::Finished; if (response.error) - response.message = sp_resp.exitMessage(executable.toString(), timeOutS); + response.message = sp_resp.exitMessage(client()->vcsBinary().toString(), timeOutS); response.stdErr = sp_resp.stdErr(); response.stdOut = sp_resp.stdOut(); return response; diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 2a0b8f87f1c..e33c854464c 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -155,8 +155,13 @@ QString VcsBaseClientImpl::commandOutputFromLocal8Bit(const QByteArray &a) QStringList VcsBaseClientImpl::commandOutputLinesFromLocal8Bit(const QByteArray &a) { - QString output = commandOutputFromLocal8Bit(a); + return splitLines(commandOutputFromLocal8Bit(a)); +} + +QStringList VcsBaseClientImpl::splitLines(const QString &s) +{ const QChar newLine = QLatin1Char('\n'); + QString output = s; if (output.endsWith(newLine)) output.truncate(output.size() - 1); if (output.isEmpty()) @@ -164,6 +169,13 @@ QStringList VcsBaseClientImpl::commandOutputLinesFromLocal8Bit(const QByteArray return output.split(newLine); } +QString VcsBaseClientImpl::stripLastNewline(const QString &in) +{ + if (in.endsWith('\n')) + return in.left(in.count() - 1); + return in; +} + void VcsBaseClientImpl::resetCachedVcsInfo(const QString &workingDir) { Core::VcsManager::resetVersionControlForDirectory(workingDir); @@ -182,18 +194,15 @@ void VcsBaseClientImpl::annotateRevisionRequested(const QString &workingDirector annotate(workingDirectory, file, changeCopy, line); } -bool VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const QStringList &args, - QByteArray *outputData, QByteArray *errorData, - unsigned flags) const +Utils::SynchronousProcessResponse +VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const QStringList &args, + unsigned flags, int timeoutS, QTextCodec *codec) const { - QByteArray internalErrorData; - QScopedPointer command(createCommand(workingDir)); - command->addFlags(flags); - bool result = command->runFullySynchronous(vcsBinary(), args, vcsTimeoutS(), outputData, - errorData ? errorData : &internalErrorData); - if (!internalErrorData.isEmpty() && !(flags & VcsCommand::SuppressStdErr)) - VcsOutputWindow::appendError(commandOutputFromLocal8Bit(internalErrorData)); - return result; + VcsCommand command(workingDir, processEnvironment()); + command.addFlags(flags); + if (codec) + command.setCodec(codec); + return command.runCommand(vcsBinary(), args, (timeoutS > 0) ? timeoutS : vcsTimeoutS()); } VcsCommand *VcsBaseClientImpl::vcsExec(const QString &workingDirectory, const QStringList &arguments, @@ -300,10 +309,10 @@ bool VcsBaseClient::synchronousCreateRepository(const QString &workingDirectory, { QStringList args(vcsCommandString(CreateRepositoryCommand)); args << extraOptions; - QByteArray outputData; - if (!vcsFullySynchronousExec(workingDirectory, args, &outputData)) + Utils::SynchronousProcessResponse result = vcsFullySynchronousExec(workingDirectory, args); + if (result.result != Utils::SynchronousProcessResponse::Finished) return false; - VcsOutputWindow::append(commandOutputFromLocal8Bit(outputData)); + VcsOutputWindow::append(result.stdOut()); resetCachedVcsInfo(workingDirectory); @@ -318,10 +327,10 @@ bool VcsBaseClient::synchronousClone(const QString &workingDir, QStringList args; args << vcsCommandString(CloneCommand) << extraOptions << srcLocation << dstLocation; - QByteArray stdOut; - const bool cloneOk = vcsFullySynchronousExec(workingDir, args, &stdOut); + + Utils::SynchronousProcessResponse result = vcsFullySynchronousExec(workingDir, args); resetCachedVcsInfo(workingDir); - return cloneOk; + return result.result == Utils::SynchronousProcessResponse::Finished; } bool VcsBaseClient::synchronousAdd(const QString &workingDir, const QString &filename, @@ -329,8 +338,7 @@ bool VcsBaseClient::synchronousAdd(const QString &workingDir, const QString &fil { QStringList args; args << vcsCommandString(AddCommand) << extraOptions << filename; - QByteArray stdOut; - return vcsFullySynchronousExec(workingDir, args, &stdOut); + return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished; } bool VcsBaseClient::synchronousRemove(const QString &workingDir, const QString &filename, @@ -338,8 +346,7 @@ bool VcsBaseClient::synchronousRemove(const QString &workingDir, const QString & { QStringList args; args << vcsCommandString(RemoveCommand) << extraOptions << filename; - QByteArray stdOut; - return vcsFullySynchronousExec(workingDir, args, &stdOut); + return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished; } bool VcsBaseClient::synchronousMove(const QString &workingDir, @@ -348,8 +355,7 @@ bool VcsBaseClient::synchronousMove(const QString &workingDir, { QStringList args; args << vcsCommandString(MoveCommand) << extraOptions << from << to; - QByteArray stdOut; - return vcsFullySynchronousExec(workingDir, args, &stdOut); + return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished; } bool VcsBaseClient::synchronousPull(const QString &workingDir, diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index 63ad0c52a56..62a7bde3a33 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -95,28 +95,31 @@ public: static QString commandOutputFromLocal8Bit(const QByteArray &a); // Return converted command output split into lines static QStringList commandOutputLinesFromLocal8Bit(const QByteArray &a); + static QStringList splitLines(const QString &s); + + static QString stripLastNewline(const QString &in); + + // Fully synchronous VCS execution (QProcess-based) + Utils::SynchronousProcessResponse + vcsFullySynchronousExec(const QString &workingDir, const QStringList &args, + unsigned flags = 0, int timeoutS = -1, QTextCodec *codec = nullptr) const; + + // Simple helper to execute a single command using createCommand and enqueueJob. + VcsCommand *vcsExec(const QString &workingDirectory, const QStringList &arguments, + VcsBaseEditorWidget *editor = nullptr, bool useOutputToWindow = false, + unsigned additionalFlags = 0, const QVariant &cookie = QVariant()) const; protected: void resetCachedVcsInfo(const QString &workingDir); virtual void annotateRevisionRequested(const QString &workingDirectory, const QString &file, const QString &change, int line); - // Fully synchronous VCS execution (QProcess-based) - bool vcsFullySynchronousExec(const QString &workingDir, const QStringList &args, - QByteArray *outputData, QByteArray *errorData = 0, - unsigned flags = 0) const; - - // Simple helper to execute a single command using createCommand and enqueueJob. - VcsCommand *vcsExec(const QString &workingDirectory, const QStringList &arguments, - VcsBaseEditorWidget *editor = 0, bool useOutputToWindow = false, - unsigned additionalFlags = 0, const QVariant &cookie = QVariant()) const; - // Synchronous VCS execution using Utils::SynchronousProcess, with // log windows updating (using VcsBasePlugin::runVcs with flags) Utils::SynchronousProcessResponse vcsSynchronousExec(const QString &workingDir, const QStringList &args, unsigned flags = 0, - QTextCodec *outputCodec = 0) const; + QTextCodec *outputCodec = nullptr) const; private: void saveSettings();