forked from qt-creator/qt-creator
VCS: VcsBaseClient::vcsFullySynchronousExec returns a SynchronousProcessResponse
Change-Id: Ic155da2ed1fd36f1f91327ac90f34a5cad3c210e Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -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)
|
||||
|
@@ -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<QString,QString> GitClient::synchronousRemotesList(const QString &workingDi
|
||||
QString *errorMessage) const
|
||||
{
|
||||
QMap<QString,QString> result;
|
||||
|
||||
QString output;
|
||||
QString error;
|
||||
if (!synchronousRemoteCmd(workingDirectory, { "-v" }, &output, &error, true)) {
|
||||
@@ -1658,7 +1640,7 @@ QMap<QString,QString> 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<QString,QString> 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<QByteArray> lines = outputText.split('\n');
|
||||
foreach (const QByteArray &line, lines)
|
||||
QList<QString> 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 "SHA1<lf>author<lf>email<lf>message".
|
||||
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<Stash> *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);
|
||||
|
@@ -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") <<revision;
|
||||
if (!file.isEmpty())
|
||||
args << file;
|
||||
QByteArray outputData;
|
||||
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
|
||||
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args);
|
||||
if (resp.result != SynchronousProcessResponse::Finished)
|
||||
return QStringList();
|
||||
const QString output = SynchronousProcess::normalizeNewlines(
|
||||
QString::fromLocal8Bit(outputData));
|
||||
/* Looks like: \code
|
||||
changeset: 0:031a48610fba
|
||||
user: ...
|
||||
\endcode */
|
||||
// Obtain first line and split by blank-delimited tokens
|
||||
const QStringList lines = output.split(QLatin1Char('\n'));
|
||||
const QStringList lines = resp.stdOut().split(QLatin1Char('\n'));
|
||||
if (lines.size() < 1) {
|
||||
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
|
||||
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(resp.stdOut())));
|
||||
return QStringList();
|
||||
}
|
||||
QStringList changeSets = lines.front().simplified().split(QLatin1Char(' '));
|
||||
if (changeSets.size() < 2) {
|
||||
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
|
||||
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(resp.stdOut())));
|
||||
return QStringList();
|
||||
}
|
||||
// Remove revision numbers
|
||||
@@ -231,18 +230,15 @@ QString MercurialClient::shortDescriptionSync(const QString &workingDirectory,
|
||||
const QString &revision,
|
||||
const QString &format)
|
||||
{
|
||||
QString description;
|
||||
QStringList args;
|
||||
args << QLatin1String("log") << QLatin1String("-r") <<revision;
|
||||
if (!format.isEmpty())
|
||||
args << QLatin1String("--template") << format;
|
||||
QByteArray outputData;
|
||||
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
|
||||
|
||||
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args);
|
||||
if (resp.result != SynchronousProcessResponse::Finished)
|
||||
return revision;
|
||||
description = commandOutputFromLocal8Bit(outputData);
|
||||
if (description.endsWith(QLatin1Char('\n')))
|
||||
description.truncate(description.size() - 1);
|
||||
return description;
|
||||
return stripLastNewline(resp.stdOut());
|
||||
}
|
||||
|
||||
// Default format: "SHA1 (author summmary)"
|
||||
@@ -258,9 +254,7 @@ bool MercurialClient::managesFile(const QString &workingDirectory, const QString
|
||||
{
|
||||
QStringList args;
|
||||
args << QLatin1String("status") << QLatin1String("--unknown") << fileName;
|
||||
QByteArray output;
|
||||
vcsFullySynchronousExec(workingDirectory, args, &output);
|
||||
return output.isEmpty();
|
||||
return vcsFullySynchronousExec(workingDirectory, args).stdOut().isEmpty();
|
||||
}
|
||||
|
||||
void MercurialClient::incoming(const QString &repositoryRoot, const QString &repository)
|
||||
|
@@ -138,14 +138,13 @@ QString SubversionClient::synchronousTopic(const QString &repository)
|
||||
QStringList args;
|
||||
args << QLatin1String("info");
|
||||
|
||||
QByteArray stdOut;
|
||||
if (!vcsFullySynchronousExec(repository, args, &stdOut))
|
||||
const SynchronousProcessResponse result = vcsFullySynchronousExec(repository, args);
|
||||
if (result.result != SynchronousProcessResponse::Finished)
|
||||
return QString();
|
||||
|
||||
const QString revisionString = QLatin1String("Revision: ");
|
||||
// stdOut is ASCII only (at least in those areas we care about).
|
||||
QString output = commandOutputFromLocal8Bit(stdOut);
|
||||
foreach (const QString &line, output.split(QLatin1Char('\n'))) {
|
||||
foreach (const QString &line, result.stdOut().split(QLatin1Char('\n'))) {
|
||||
if (line.startsWith(revisionString))
|
||||
return QString::fromLatin1("r") + line.mid(revisionString.count());
|
||||
}
|
||||
|
@@ -877,21 +877,19 @@ SubversionResponse SubversionPlugin::runSvn(const QString &workingDir,
|
||||
int timeOutS, unsigned flags,
|
||||
QTextCodec *outputCodec) const
|
||||
{
|
||||
const FileName executable = client()->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;
|
||||
|
@@ -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<VcsCommand> 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,
|
||||
|
@@ -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();
|
||||
|
Reference in New Issue
Block a user