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")
|
args << QLatin1String("whoami")
|
||||||
<< (settings().stringValue(BazaarSettings::userNameKey) + QLatin1String(" <")
|
<< (settings().stringValue(BazaarSettings::userNameKey) + QLatin1String(" <")
|
||||||
+ settings().stringValue(BazaarSettings::userEmailKey) + QLatin1Char('>'));
|
+ settings().stringValue(BazaarSettings::userEmailKey) + QLatin1Char('>'));
|
||||||
QByteArray stdOut;
|
return vcsFullySynchronousExec(QDir::currentPath(), args).result
|
||||||
return vcsFullySynchronousExec(QDir::currentPath(), args, &stdOut);
|
== SynchronousProcessResponse::Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
BranchInfo BazaarClient::synchronousBranchQuery(const QString &repositoryRoot) const
|
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
|
<< QLatin1String("--verbose") // Will print out what is being removed
|
||||||
<< revisionSpec(revision)
|
<< revisionSpec(revision)
|
||||||
<< extraOptions;
|
<< extraOptions;
|
||||||
QByteArray stdOut;
|
|
||||||
const bool success = vcsFullySynchronousExec(workingDir, args, &stdOut);
|
const SynchronousProcessResponse result = vcsFullySynchronousExec(workingDir, args);
|
||||||
if (!stdOut.isEmpty())
|
VcsOutputWindow::append(result.stdOut());
|
||||||
VcsOutputWindow::append(QString::fromUtf8(stdOut));
|
return result.result == SynchronousProcessResponse::Finished;
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BazaarClient::commit(const QString &repositoryRoot, const QStringList &files,
|
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"));
|
QStringList args(QLatin1String("status"));
|
||||||
args << fileName;
|
args << fileName;
|
||||||
QByteArray stdOut;
|
|
||||||
if (!vcsFullySynchronousExec(workingDirectory, args, &stdOut))
|
const SynchronousProcessResponse result = vcsFullySynchronousExec(workingDirectory, args);
|
||||||
|
if (result.result != SynchronousProcessResponse::Finished)
|
||||||
return false;
|
return false;
|
||||||
return !stdOut.startsWith("unknown");
|
return result.rawStdOut.startsWith("unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BazaarClient::view(const QString &source, const QString &id, const QStringList &extraOptions)
|
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
|
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,
|
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")
|
const QString message = GitClient::tr("Cannot run \"%1\" in \"%2\": %3")
|
||||||
.arg("git " + args.join(' '),
|
.arg("git " + args.join(' '),
|
||||||
QDir::toNativeSeparators(workingDirectory),
|
QDir::toNativeSeparators(workingDirectory),
|
||||||
GitClient::commandOutputFromLocal8Bit(error));
|
error);
|
||||||
|
|
||||||
msgCannotRun(message, errorMessage);
|
msgCannotRun(message, errorMessage);
|
||||||
}
|
}
|
||||||
@@ -625,9 +626,8 @@ QString GitClient::findGitDirForRepository(const QString &repositoryDir) const
|
|||||||
|
|
||||||
bool GitClient::managesFile(const QString &workingDirectory, const QString &fileName) const
|
bool GitClient::managesFile(const QString &workingDirectory, const QString &fileName) const
|
||||||
{
|
{
|
||||||
QByteArray output;
|
return vcsFullySynchronousExec(workingDirectory, { "ls-files", "--error-unmatch", fileName }).result
|
||||||
const QStringList arguments = { "ls-files", "--error-unmatch", fileName };
|
== SynchronousProcessResponse::Finished;
|
||||||
return vcsFullySynchronousExec(workingDirectory, arguments, &output, 0, silentFlags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextCodec *GitClient::codecFor(GitClient::CodecType codecType, const QString &source) const
|
QTextCodec *GitClient::codecFor(GitClient::CodecType codecType, const QString &source) const
|
||||||
@@ -938,17 +938,17 @@ bool GitClient::synchronousCheckout(const QString &workingDirectory,
|
|||||||
const QString &ref,
|
const QString &ref,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
|
||||||
QStringList arguments = setupCheckoutArguments(workingDirectory, ref);
|
QStringList arguments = setupCheckoutArguments(workingDirectory, ref);
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, 0,
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
VcsCommand::ExpectRepoChanges);
|
workingDirectory, arguments, VcsCommand::ExpectRepoChanges);
|
||||||
VcsOutputWindow::append(commandOutputFromLocal8Bit(outputText));
|
VcsOutputWindow::append(resp.stdOut());
|
||||||
if (rc)
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
updateSubmodulesIfNeeded(workingDirectory, true);
|
updateSubmodulesIfNeeded(workingDirectory, true);
|
||||||
else
|
return true;
|
||||||
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
|
} else {
|
||||||
return rc;
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* method used to setup arguments for checkout, in case user wants to create local branch */
|
/* 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,
|
bool GitClient::synchronousLog(const QString &workingDirectory, const QStringList &arguments,
|
||||||
QString *output, QString *errorMessageIn, unsigned flags)
|
QString *output, QString *errorMessageIn, unsigned flags)
|
||||||
{
|
{
|
||||||
QByteArray outputData;
|
|
||||||
QByteArray errorData;
|
|
||||||
QStringList allArguments = { "log", noColorOption };
|
QStringList allArguments = { "log", noColorOption };
|
||||||
|
|
||||||
allArguments.append(arguments);
|
allArguments.append(arguments);
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, allArguments, &outputData, &errorData, flags);
|
|
||||||
if (rc) {
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
if (QTextCodec *codec = encoding(workingDirectory, "i18n.logOutputEncoding"))
|
workingDirectory, allArguments, flags, vcsTimeoutS(),
|
||||||
*output = codec->toUnicode(outputData);
|
encoding(workingDirectory, "i18n.logOutputEncoding"));
|
||||||
else
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
*output = commandOutputFromLocal8Bit(outputData);
|
*output = resp.stdOut();
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
msgCannotRun(tr("Cannot obtain log of \"%1\": %2")
|
msgCannotRun(tr("Cannot obtain log of \"%1\": %2")
|
||||||
.arg(QDir::toNativeSeparators(workingDirectory),
|
.arg(QDir::toNativeSeparators(workingDirectory), resp.stdErr()), errorMessageIn);
|
||||||
commandOutputFromLocal8Bit(errorData)), errorMessageIn);
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringList &files)
|
bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringList &files)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
return vcsFullySynchronousExec(workingDirectory, QStringList({ "add" }) + files).result
|
||||||
return vcsFullySynchronousExec(workingDirectory, QStringList({ "add" }) + files, &outputText);
|
== SynchronousProcessResponse::Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::synchronousDelete(const QString &workingDirectory,
|
bool GitClient::synchronousDelete(const QString &workingDirectory,
|
||||||
bool force,
|
bool force,
|
||||||
const QStringList &files)
|
const QStringList &files)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
|
||||||
QStringList arguments = { "rm" };
|
QStringList arguments = { "rm" };
|
||||||
if (force)
|
if (force)
|
||||||
arguments << "--force";
|
arguments << "--force";
|
||||||
arguments.append(files);
|
arguments.append(files);
|
||||||
return vcsFullySynchronousExec(workingDirectory, arguments, &outputText);
|
return vcsFullySynchronousExec(workingDirectory, arguments).result
|
||||||
|
== SynchronousProcessResponse::Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::synchronousMove(const QString &workingDirectory,
|
bool GitClient::synchronousMove(const QString &workingDirectory,
|
||||||
const QString &from,
|
const QString &from,
|
||||||
const QString &to)
|
const QString &to)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
return vcsFullySynchronousExec(workingDirectory, { "mv", from, to }).result
|
||||||
return vcsFullySynchronousExec(workingDirectory, { "mv", from, to }, &outputText);
|
== SynchronousProcessResponse::Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::synchronousReset(const QString &workingDirectory,
|
bool GitClient::synchronousReset(const QString &workingDirectory,
|
||||||
const QStringList &files,
|
const QStringList &files,
|
||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
|
||||||
QStringList arguments = { "reset" };
|
QStringList arguments = { "reset" };
|
||||||
if (files.isEmpty())
|
if (files.isEmpty())
|
||||||
arguments << "--hard";
|
arguments << "--hard";
|
||||||
else
|
else
|
||||||
arguments << HEAD << "--" << files;
|
arguments << HEAD << "--" << files;
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText);
|
|
||||||
const QString output = commandOutputFromLocal8Bit(outputText);
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments);
|
||||||
VcsOutputWindow::append(output);
|
const QString stdOut = resp.stdOut();
|
||||||
|
VcsOutputWindow::append(stdOut);
|
||||||
// Note that git exits with 1 even if the operation is successful
|
// Note that git exits with 1 even if the operation is successful
|
||||||
// Assume real failure if the output does not contain "foo.cpp modified"
|
// Assume real failure if the output does not contain "foo.cpp modified"
|
||||||
// or "Unstaged changes after reset" (git 1.7.0).
|
// 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()) {
|
if (files.isEmpty()) {
|
||||||
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
} else {
|
} else {
|
||||||
msgCannotRun(tr("Cannot reset %n file(s) in \"%1\": %2", 0, files.size())
|
msgCannotRun(tr("Cannot reset %n file(s) in \"%1\": %2", 0, files.size())
|
||||||
.arg(QDir::toNativeSeparators(workingDirectory),
|
.arg(QDir::toNativeSeparators(workingDirectory), resp.stdErr()),
|
||||||
commandOutputFromLocal8Bit(errorText)),
|
|
||||||
errorMessage);
|
errorMessage);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1124,13 +1120,15 @@ bool GitClient::synchronousReset(const QString &workingDirectory,
|
|||||||
// Initialize repository
|
// Initialize repository
|
||||||
bool GitClient::synchronousInit(const QString &workingDirectory)
|
bool GitClient::synchronousInit(const QString &workingDirectory)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, { "init" });
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, { "init" }, &outputText);
|
|
||||||
// '[Re]Initialized...'
|
// '[Re]Initialized...'
|
||||||
VcsOutputWindow::append(commandOutputFromLocal8Bit(outputText));
|
VcsOutputWindow::append(resp.stdOut());
|
||||||
if (rc)
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
resetCachedVcsInfo(workingDirectory);
|
resetCachedVcsInfo(workingDirectory);
|
||||||
return rc;
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checkout, supports:
|
/* Checkout, supports:
|
||||||
@@ -1145,21 +1143,18 @@ bool GitClient::synchronousCheckoutFiles(const QString &workingDirectory, QStrin
|
|||||||
revision = HEAD;
|
revision = HEAD;
|
||||||
if (files.isEmpty())
|
if (files.isEmpty())
|
||||||
files = QStringList(".");
|
files = QStringList(".");
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
|
||||||
QStringList arguments = { "checkout" };
|
QStringList arguments = { "checkout" };
|
||||||
if (revertStaging)
|
if (revertStaging)
|
||||||
arguments << revision;
|
arguments << revision;
|
||||||
arguments << "--" << files;
|
arguments << "--" << files;
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText,
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
VcsCommand::ExpectRepoChanges);
|
workingDirectory, arguments, VcsCommand::ExpectRepoChanges);
|
||||||
if (!rc) {
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
const QString fileArg = files.join(", ");
|
const QString fileArg = files.join(", ");
|
||||||
//: Meaning of the arguments: %1: revision, %2: files, %3: repository,
|
//: Meaning of the arguments: %1: revision, %2: files, %3: repository,
|
||||||
//: %4: Error message
|
//: %4: Error message
|
||||||
msgCannotRun(tr("Cannot checkout \"%1\" of %2 in \"%3\": %4")
|
msgCannotRun(tr("Cannot checkout \"%1\" of %2 in \"%3\": %4")
|
||||||
.arg(revision, fileArg, workingDirectory,
|
.arg(revision, fileArg, workingDirectory, resp.stdErr()),
|
||||||
commandOutputFromLocal8Bit(errorText)),
|
|
||||||
errorMessage);
|
errorMessage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1212,16 +1207,14 @@ static inline bool splitCommitParents(const QString &line,
|
|||||||
bool GitClient::synchronousRevListCmd(const QString &workingDirectory, const QStringList &extraArguments,
|
bool GitClient::synchronousRevListCmd(const QString &workingDirectory, const QStringList &extraArguments,
|
||||||
QString *output, QString *errorMessage) const
|
QString *output, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
QByteArray outputTextData;
|
|
||||||
QByteArray errorText;
|
|
||||||
const QStringList arguments = QStringList({ "rev-list", noColorOption }) + extraArguments;
|
const QStringList arguments = QStringList({ "rev-list", noColorOption }) + extraArguments;
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData,
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
&errorText, silentFlags);
|
workingDirectory, arguments, silentFlags);
|
||||||
if (!rc) {
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*output = commandOutputFromLocal8Bit(outputTextData);
|
*output = resp.stdOut();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1273,11 +1266,11 @@ QString GitClient::synchronousShortDescription(const QString &workingDirectory,
|
|||||||
|
|
||||||
QString GitClient::synchronousCurrentLocalBranch(const QString &workingDirectory) const
|
QString GitClient::synchronousCurrentLocalBranch(const QString &workingDirectory) const
|
||||||
{
|
{
|
||||||
QByteArray outputTextData;
|
|
||||||
QString branch;
|
QString branch;
|
||||||
if (vcsFullySynchronousExec(workingDirectory, { "symbolic-ref", HEAD }, &outputTextData, 0,
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
silentFlags)) {
|
workingDirectory, { "symbolic-ref", HEAD }, silentFlags);
|
||||||
branch = commandOutputFromLocal8Bit(outputTextData.trimmed());
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
|
branch = resp.stdOut().trimmed();
|
||||||
} else {
|
} else {
|
||||||
const QString gitDir = findGitDirForRepository(workingDirectory);
|
const QString gitDir = findGitDirForRepository(workingDirectory);
|
||||||
const QString rebaseHead = gitDir + "/rebase-merge/head-name";
|
const QString rebaseHead = gitDir + "/rebase-merge/head-name";
|
||||||
@@ -1299,27 +1292,25 @@ bool GitClient::synchronousHeadRefs(const QString &workingDirectory, QStringList
|
|||||||
QString *errorMessage) const
|
QString *errorMessage) const
|
||||||
{
|
{
|
||||||
const QStringList arguments = { "show-ref", "--head", "--abbrev=10", "--dereference" };
|
const QStringList arguments = { "show-ref", "--head", "--abbrev=10", "--dereference" };
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
QByteArray errorText;
|
workingDirectory, arguments, silentFlags);
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText,
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
silentFlags);
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
if (!rc) {
|
|
||||||
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray headSha = outputText.left(10);
|
const QString stdOut = resp.stdOut();
|
||||||
QByteArray newLine("\n");
|
const QString headSha = stdOut.left(10);
|
||||||
|
const QChar newLine('\n');
|
||||||
|
|
||||||
int currentIndex = 15;
|
int currentIndex = 15;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
currentIndex = outputText.indexOf(headSha, currentIndex);
|
currentIndex = stdOut.indexOf(headSha, currentIndex);
|
||||||
if (currentIndex < 0)
|
if (currentIndex < 0)
|
||||||
break;
|
break;
|
||||||
currentIndex += 11;
|
currentIndex += 11;
|
||||||
output->append(QString::fromLocal8Bit(outputText.mid(currentIndex,
|
output->append(stdOut.mid(currentIndex, stdOut.indexOf(newLine, currentIndex) - currentIndex));
|
||||||
outputText.indexOf(newLine, currentIndex) - currentIndex)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1356,11 +1347,12 @@ QString GitClient::synchronousTopic(const QString &workingDirectory) const
|
|||||||
return remoteBranch;
|
return remoteBranch;
|
||||||
|
|
||||||
// No tag or remote branch - try git describe
|
// No tag or remote branch - try git describe
|
||||||
QByteArray output;
|
const SynchronousProcessResponse resp =
|
||||||
if (vcsFullySynchronousExec(workingDirectory, { "describe" }, &output, 0, VcsCommand::NoOutput)) {
|
vcsFullySynchronousExec(workingDirectory, { "describe" }, VcsCommand::NoOutput);
|
||||||
const QString describeOutput = commandOutputFromLocal8Bit(output.trimmed());
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
if (!describeOutput.isEmpty())
|
const QString stdOut = resp.stdOut().trimmed();
|
||||||
return describeOutput;
|
if (!stdOut.isEmpty())
|
||||||
|
return stdOut;
|
||||||
}
|
}
|
||||||
return tr("Detached HEAD");
|
return tr("Detached HEAD");
|
||||||
}
|
}
|
||||||
@@ -1369,15 +1361,15 @@ bool GitClient::synchronousRevParseCmd(const QString &workingDirectory, const QS
|
|||||||
QString *output, QString *errorMessage) const
|
QString *output, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
const QStringList arguments = { "rev-parse", ref };
|
const QStringList arguments = { "rev-parse", ref };
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
QByteArray errorText;
|
workingDirectory, arguments, silentFlags);
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText,
|
*output = resp.stdOut().trimmed();
|
||||||
silentFlags);
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
*output = commandOutputFromLocal8Bit(outputText.trimmed());
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
if (!rc)
|
return false;
|
||||||
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
|
}
|
||||||
|
|
||||||
return rc;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve head revision
|
// Retrieve head revision
|
||||||
@@ -1393,28 +1385,27 @@ QString GitClient::synchronousTopRevision(const QString &workingDirectory, QStri
|
|||||||
void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const QString &revision,
|
void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const QString &revision,
|
||||||
QString &precedes, QString &follows) const
|
QString &precedes, QString &follows) const
|
||||||
{
|
{
|
||||||
QByteArray pr;
|
const SynchronousProcessResponse resp1 = vcsFullySynchronousExec(
|
||||||
vcsFullySynchronousExec(workingDirectory, { "describe", "--contains", revision },
|
workingDirectory, { "describe", "--contains", revision }, silentFlags);
|
||||||
&pr, 0, silentFlags);
|
precedes = resp1.stdOut();
|
||||||
int tilde = pr.indexOf('~');
|
int tilde = precedes.indexOf('~');
|
||||||
if (tilde != -1)
|
if (tilde != -1)
|
||||||
pr.truncate(tilde);
|
precedes.truncate(tilde);
|
||||||
else
|
else
|
||||||
pr = pr.trimmed();
|
precedes = precedes.trimmed();
|
||||||
precedes = QString::fromLocal8Bit(pr);
|
|
||||||
|
|
||||||
QStringList parents;
|
QStringList parents;
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
synchronousParentRevisions(workingDirectory, revision, &parents, &errorMessage);
|
synchronousParentRevisions(workingDirectory, revision, &parents, &errorMessage);
|
||||||
foreach (const QString &p, parents) {
|
foreach (const QString &p, parents) {
|
||||||
QByteArray pf;
|
const SynchronousProcessResponse resp2 = vcsFullySynchronousExec(
|
||||||
vcsFullySynchronousExec(workingDirectory, { "describe", "--tags", "--abbrev=0", p },
|
workingDirectory, { "describe", "--tags", "--abbrev=0", p }, silentFlags);
|
||||||
&pf, 0, silentFlags);
|
QString pf = resp2.stdOut();
|
||||||
pf.truncate(pf.lastIndexOf('\n'));
|
pf.truncate(pf.lastIndexOf('\n'));
|
||||||
if (!pf.isEmpty()) {
|
if (!pf.isEmpty()) {
|
||||||
if (!follows.isEmpty())
|
if (!follows.isEmpty())
|
||||||
follows += ", ";
|
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)
|
bool GitClient::isRemoteCommit(const QString &workingDirectory, const QString &commit)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
return !vcsFullySynchronousExec(
|
||||||
vcsFullySynchronousExec(workingDirectory, { "branch", "-r", "--contains", commit },
|
workingDirectory, { "branch", "-r", "--contains", commit }, silentFlags).rawStdOut.isEmpty();
|
||||||
&outputText, 0, silentFlags);
|
|
||||||
return !outputText.isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::isFastForwardMerge(const QString &workingDirectory, const QString &branch)
|
bool GitClient::isFastForwardMerge(const QString &workingDirectory, const QString &branch)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
vcsFullySynchronousExec(workingDirectory, { "merge-base", HEAD, branch },
|
workingDirectory, { "merge-base", HEAD, branch }, silentFlags);
|
||||||
&outputText, 0, silentFlags);
|
return resp.stdOut().trimmed() == synchronousTopRevision(workingDirectory);
|
||||||
return commandOutputFromLocal8Bit(outputText).trimmed()
|
|
||||||
== synchronousTopRevision(workingDirectory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format an entry in a one-liner for selection list using git log.
|
// Format an entry in a one-liner for selection list using git log.
|
||||||
QString GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision,
|
QString GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision,
|
||||||
const QString &format) const
|
const QString &format) const
|
||||||
{
|
{
|
||||||
QString description;
|
|
||||||
QByteArray outputTextData;
|
|
||||||
QByteArray errorText;
|
|
||||||
const QStringList arguments = { "log", noColorOption, ("--pretty=format:" + format),
|
const QStringList arguments = { "log", noColorOption, ("--pretty=format:" + format),
|
||||||
"--max-count=1", revision };
|
"--max-count=1", revision };
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData, &errorText,
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
silentFlags);
|
workingDirectory, arguments, silentFlags);
|
||||||
if (!rc) {
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
VcsOutputWindow::appendSilently(tr("Cannot describe revision \"%1\" in \"%2\": %3")
|
VcsOutputWindow::appendSilently(tr("Cannot describe revision \"%1\" in \"%2\": %3")
|
||||||
.arg(revision, workingDirectory, commandOutputFromLocal8Bit(errorText)));
|
.arg(revision, workingDirectory, resp.stdErr()));
|
||||||
return revision;
|
return revision;
|
||||||
}
|
}
|
||||||
description = commandOutputFromLocal8Bit(outputTextData);
|
return stripLastNewline(resp.stdOut());
|
||||||
if (description.endsWith('\n'))
|
|
||||||
description.truncate(description.size() - 1);
|
|
||||||
return description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a default message to be used for describing stashes
|
// 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
|
const unsigned flags = VcsCommand::ShowStdOut
|
||||||
| VcsCommand::ExpectRepoChanges
|
| VcsCommand::ExpectRepoChanges
|
||||||
| VcsCommand::ShowSuccessMessage;
|
| VcsCommand::ShowSuccessMessage;
|
||||||
const SynchronousProcessResponse response = vcsSynchronousExec(workingDirectory, arguments, flags);
|
const SynchronousProcessResponse resp = vcsSynchronousExec(workingDirectory, arguments, flags);
|
||||||
const bool rc = response.result == SynchronousProcessResponse::Finished;
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
if (!rc)
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
msgCannotRun(arguments, workingDirectory, response.rawStdErr, errorMessage);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve a stash name from message
|
// Resolve a stash name from message
|
||||||
@@ -1578,43 +1560,40 @@ bool GitClient::synchronousBranchCmd(const QString &workingDirectory, QStringLis
|
|||||||
QString *output, QString *errorMessage) const
|
QString *output, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
branchArgs.push_front("branch");
|
branchArgs.push_front("branch");
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, branchArgs);
|
||||||
QByteArray errorText;
|
*output = resp.stdOut();
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, branchArgs, &outputText, &errorText);
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
*output = commandOutputFromLocal8Bit(outputText);
|
msgCannotRun(branchArgs, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
if (!rc)
|
return false;
|
||||||
msgCannotRun(branchArgs, workingDirectory, errorText, errorMessage);
|
}
|
||||||
|
return true;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::synchronousTagCmd(const QString &workingDirectory, QStringList tagArgs,
|
bool GitClient::synchronousTagCmd(const QString &workingDirectory, QStringList tagArgs,
|
||||||
QString *output, QString *errorMessage) const
|
QString *output, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
tagArgs.push_front("tag");
|
tagArgs.push_front("tag");
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, tagArgs);
|
||||||
QByteArray errorText;
|
*output = resp.stdOut();
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, tagArgs, &outputText, &errorText);
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
*output = commandOutputFromLocal8Bit(outputText);
|
msgCannotRun(tagArgs, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
if (!rc)
|
return false;
|
||||||
msgCannotRun(tagArgs, workingDirectory, errorText, errorMessage);
|
}
|
||||||
|
return true;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::synchronousForEachRefCmd(const QString &workingDirectory, QStringList args,
|
bool GitClient::synchronousForEachRefCmd(const QString &workingDirectory, QStringList args,
|
||||||
QString *output, QString *errorMessage) const
|
QString *output, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
args.push_front("for-each-ref");
|
args.push_front("for-each-ref");
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args,
|
||||||
QByteArray errorText;
|
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, args, &outputText, &errorText,
|
|
||||||
silentFlags);
|
silentFlags);
|
||||||
*output = SynchronousProcess::normalizeNewlines(QString::fromUtf8(outputText));
|
*output = resp.stdOut();
|
||||||
if (!rc)
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
msgCannotRun(args, workingDirectory, errorText, errorMessage);
|
msgCannotRun(args, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
|
return false;
|
||||||
return rc;
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VcsCommand *GitClient::asyncForEachRefCmd(const QString &workingDirectory, QStringList args) const
|
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
|
QString *output, QString *errorMessage, bool silent) const
|
||||||
{
|
{
|
||||||
remoteArgs.push_front("remote");
|
remoteArgs.push_front("remote");
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, remoteArgs,
|
||||||
QByteArray errorText;
|
silent ? silentFlags : 0);
|
||||||
if (!vcsFullySynchronousExec(workingDirectory, remoteArgs, &outputText, &errorText,
|
|
||||||
silent ? silentFlags : 0)) {
|
const QString stdErr = resp.stdErr();
|
||||||
msgCannotRun(remoteArgs, workingDirectory, errorText, errorMessage);
|
*errorMessage = stdErr;
|
||||||
|
*output = resp.stdOut();
|
||||||
|
|
||||||
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
|
msgCannotRun(remoteArgs, workingDirectory, stdErr, errorMessage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (output)
|
|
||||||
*output = commandOutputFromLocal8Bit(outputText);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1643,6 +1624,7 @@ QMap<QString,QString> GitClient::synchronousRemotesList(const QString &workingDi
|
|||||||
QString *errorMessage) const
|
QString *errorMessage) const
|
||||||
{
|
{
|
||||||
QMap<QString,QString> result;
|
QMap<QString,QString> result;
|
||||||
|
|
||||||
QString output;
|
QString output;
|
||||||
QString error;
|
QString error;
|
||||||
if (!synchronousRemoteCmd(workingDirectory, { "-v" }, &output, &error, true)) {
|
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');
|
const int tabIndex = remote.indexOf('\t');
|
||||||
if (tabIndex == -1)
|
if (tabIndex == -1)
|
||||||
continue;
|
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);
|
result.insert(remote.left(tabIndex), url);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -1667,17 +1649,16 @@ QMap<QString,QString> GitClient::synchronousRemotesList(const QString &workingDi
|
|||||||
QStringList GitClient::synchronousSubmoduleStatus(const QString &workingDirectory,
|
QStringList GitClient::synchronousSubmoduleStatus(const QString &workingDirectory,
|
||||||
QString *errorMessage) const
|
QString *errorMessage) const
|
||||||
{
|
{
|
||||||
QByteArray outputTextData;
|
|
||||||
QByteArray errorText;
|
|
||||||
// get submodule status
|
// get submodule status
|
||||||
if (!vcsFullySynchronousExec(workingDirectory, { "submodule", "status" },
|
const SynchronousProcessResponse resp =
|
||||||
&outputTextData, &errorText, silentFlags)) {
|
vcsFullySynchronousExec(workingDirectory, { "submodule", "status" }, silentFlags);
|
||||||
|
|
||||||
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
msgCannotRun(tr("Cannot retrieve submodule status of \"%1\": %2")
|
msgCannotRun(tr("Cannot retrieve submodule status of \"%1\": %2")
|
||||||
.arg(QDir::toNativeSeparators(workingDirectory),
|
.arg(QDir::toNativeSeparators(workingDirectory), resp.stdErr()), errorMessage);
|
||||||
commandOutputFromLocal8Bit(errorText)), errorMessage);
|
|
||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
return commandOutputLinesFromLocal8Bit(outputTextData);
|
return splitLines(resp.stdOut());
|
||||||
}
|
}
|
||||||
|
|
||||||
SubmoduleDataMap GitClient::submoduleList(const QString &workingDirectory) const
|
SubmoduleDataMap GitClient::submoduleList(const QString &workingDirectory) const
|
||||||
@@ -1750,11 +1731,13 @@ bool GitClient::synchronousShow(const QString &workingDirectory, const QString &
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const QStringList arguments = { "show", decorateOption, noColorOption, id };
|
const QStringList arguments = { "show", decorateOption, noColorOption, id };
|
||||||
QByteArray errorText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments);
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, output, &errorText);
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
if (!rc)
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
|
return false;
|
||||||
return rc;
|
}
|
||||||
|
*output = resp.rawStdOut;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve list of files to be cleaned
|
// 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 QString directory = workingDirectory + '/' + modulePath;
|
||||||
const QStringList arguments = { "clean", "--dry-run", flag };
|
const QStringList arguments = { "clean", "--dry-run", flag };
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(directory, arguments);
|
||||||
const bool rc = vcsFullySynchronousExec(directory, arguments, &outputText, &errorText);
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
if (!rc) {
|
msgCannotRun(arguments, directory, resp.stdErr(), errorMessage);
|
||||||
msgCannotRun(arguments, directory, errorText, errorMessage);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter files that git would remove
|
// Filter files that git would remove
|
||||||
const QString relativeBase = modulePath.isEmpty() ? QString() : modulePath + '/';
|
const QString relativeBase = modulePath.isEmpty() ? QString() : modulePath + '/';
|
||||||
const QString prefix = "Would remove ";
|
const QString prefix = "Would remove ";
|
||||||
foreach (const QString &line, commandOutputLinesFromLocal8Bit(outputText)) {
|
foreach (const QString &line, resp.stdOut()) {
|
||||||
if (line.startsWith(prefix))
|
if (line.startsWith(prefix))
|
||||||
files->push_back(relativeBase + line.mid(prefix.size()));
|
files->push_back(relativeBase + line.mid(prefix.size()));
|
||||||
}
|
}
|
||||||
@@ -1806,19 +1789,19 @@ bool GitClient::synchronousApplyPatch(const QString &workingDirectory,
|
|||||||
{
|
{
|
||||||
QStringList arguments = { "apply", "--whitespace=fix" };
|
QStringList arguments = { "apply", "--whitespace=fix" };
|
||||||
arguments << extraArguments << file;
|
arguments << extraArguments << file;
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments);
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText);
|
const QString stdErr = resp.stdErr();
|
||||||
if (rc) {
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
if (!errorText.isEmpty())
|
if (!stdErr.isEmpty())
|
||||||
*errorMessage = tr("There were warnings while applying \"%1\" to \"%2\":\n%3")
|
*errorMessage = tr("There were warnings while applying \"%1\" to \"%2\":\n%3")
|
||||||
.arg(file, workingDirectory, commandOutputFromLocal8Bit(errorText));
|
.arg(file, workingDirectory, stdErr);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
*errorMessage = tr("Cannot apply patch \"%1\" to \"%2\": %3")
|
*errorMessage = tr("Cannot apply patch \"%1\" to \"%2\": %3")
|
||||||
.arg(file, workingDirectory, commandOutputFromLocal8Bit(errorText));
|
.arg(QDir::toNativeSeparators(file), workingDirectory, stdErr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QProcessEnvironment GitClient::processEnvironment() const
|
QProcessEnvironment GitClient::processEnvironment() const
|
||||||
@@ -1932,8 +1915,6 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, St
|
|||||||
QString *output, QString *errorMessage) const
|
QString *output, QString *errorMessage) const
|
||||||
{
|
{
|
||||||
// Run 'status'. Note that git returns exitcode 1 if there are no added files.
|
// Run 'status'. Note that git returns exitcode 1 if there are no added files.
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
|
||||||
QStringList arguments = { "status" };
|
QStringList arguments = { "status" };
|
||||||
if (mode & NoUntracked)
|
if (mode & NoUntracked)
|
||||||
arguments << "--untracked-files=no";
|
arguments << "--untracked-files=no";
|
||||||
@@ -1943,27 +1924,28 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, St
|
|||||||
arguments << "--ignore-submodules=all";
|
arguments << "--ignore-submodules=all";
|
||||||
arguments << "--porcelain" << "-b";
|
arguments << "--porcelain" << "-b";
|
||||||
|
|
||||||
const bool statusRc = vcsFullySynchronousExec(workingDirectory, arguments,
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
&outputText, &errorText, silentFlags);
|
workingDirectory, arguments, silentFlags);
|
||||||
|
const QString stdOut = resp.stdOut();
|
||||||
|
|
||||||
if (output)
|
if (output)
|
||||||
*output = commandOutputFromLocal8Bit(outputText);
|
*output = stdOut;
|
||||||
|
|
||||||
static const char * NO_BRANCH = "## HEAD (no branch)\n";
|
const bool statusRc = resp.result == SynchronousProcessResponse::Finished;
|
||||||
|
const bool branchKnown = !stdOut.startsWith("## HEAD (no branch)\n");
|
||||||
const bool branchKnown = !outputText.startsWith(NO_BRANCH);
|
|
||||||
// Is it something really fatal?
|
// Is it something really fatal?
|
||||||
if (!statusRc && !branchKnown) {
|
if (!statusRc && !branchKnown) {
|
||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
const QString error = commandOutputFromLocal8Bit(errorText);
|
*errorMessage = tr("Cannot obtain status: %1").arg(resp.stdErr());
|
||||||
*errorMessage = tr("Cannot obtain status: %1").arg(error);
|
|
||||||
}
|
}
|
||||||
return StatusFailed;
|
return StatusFailed;
|
||||||
}
|
}
|
||||||
// Unchanged (output text depending on whether -u was passed)
|
// Unchanged (output text depending on whether -u was passed)
|
||||||
QList<QByteArray> lines = outputText.split('\n');
|
QList<QString> lines = resp.stdOut().split('\n');
|
||||||
foreach (const QByteArray &line, lines)
|
foreach (const QString &line, lines) {
|
||||||
if (!line.isEmpty() && !line.startsWith('#'))
|
if (!line.isEmpty() && !line.startsWith('#'))
|
||||||
return StatusChanged;
|
return StatusChanged;
|
||||||
|
}
|
||||||
return StatusUnchanged;
|
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".
|
// 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 };
|
const QStringList arguments = { "log", "--max-count=1", "--pretty=format:%h\n%an\n%ae\n%B", commit };
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(repoDirectory, arguments, silentFlags);
|
||||||
if (!vcsFullySynchronousExec(repoDirectory, arguments, &outputText, 0, silentFlags)) {
|
|
||||||
if (errorMessage)
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
*errorMessage = tr("Cannot retrieve last commit data of repository \"%1\".").arg(repoDirectory);
|
if (errorMessage) {
|
||||||
|
*errorMessage = tr("Cannot retrieve last commit data of repository \"%1\".")
|
||||||
|
.arg(QDir::toNativeSeparators(repoDirectory));
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextCodec *authorCodec = HostOsInfo::isWindowsHost()
|
QTextCodec *authorCodec = HostOsInfo::isWindowsHost()
|
||||||
? QTextCodec::codecForName("UTF-8")
|
? QTextCodec::codecForName("UTF-8")
|
||||||
: commitData.commitEncoding;
|
: commitData.commitEncoding;
|
||||||
commitData.amendSHA1 = QLatin1String(shiftLogLine(outputText));
|
QByteArray stdOut = resp.rawStdOut;
|
||||||
commitData.panelData.author = authorCodec->toUnicode(shiftLogLine(outputText));
|
commitData.amendSHA1 = QLatin1String(shiftLogLine(stdOut));
|
||||||
commitData.panelData.email = authorCodec->toUnicode(shiftLogLine(outputText));
|
commitData.panelData.author = authorCodec->toUnicode(shiftLogLine(stdOut));
|
||||||
|
commitData.panelData.email = authorCodec->toUnicode(shiftLogLine(stdOut));
|
||||||
if (commitTemplate)
|
if (commitTemplate)
|
||||||
*commitTemplate = commitData.commitEncoding->toUnicode(outputText);
|
*commitTemplate = commitData.commitEncoding->toUnicode(stdOut);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2539,19 +2526,16 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
|
|||||||
arguments << "--no-verify";
|
arguments << "--no-verify";
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(repositoryDirectory, arguments);
|
||||||
QByteArray errorText;
|
const QString stdErr = resp.stdErr();
|
||||||
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
const bool rc = vcsFullySynchronousExec(repositoryDirectory, arguments, &outputText, &errorText);
|
|
||||||
const QString stdErr = commandOutputFromLocal8Bit(errorText);
|
|
||||||
if (rc) {
|
|
||||||
VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount));
|
VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount));
|
||||||
VcsOutputWindow::appendError(stdErr);
|
VcsOutputWindow::appendError(stdErr);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
VcsOutputWindow::appendError(tr("Cannot commit %n file(s): %1\n", 0, commitCount).arg(stdErr));
|
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
|
/* 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);
|
QStringList(), QString(), nullptr, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QByteArray stdOut;
|
|
||||||
vcsFullySynchronousExec(workingDir, { abortCommand, "--abort" }, &stdOut, nullptr,
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
VcsCommand::ExpectRepoChanges);
|
workingDir, { abortCommand, "--abort" }, VcsCommand::ExpectRepoChanges);
|
||||||
VcsOutputWindow::append(commandOutputFromLocal8Bit(stdOut));
|
VcsOutputWindow::append(resp.stdOut());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GitClient::synchronousTrackingBranch(const QString &workingDirectory, const QString &branch)
|
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,
|
bool GitClient::synchronousSetTrackingBranch(const QString &workingDirectory,
|
||||||
const QString &branch, const QString &tracking)
|
const QString &branch, const QString &tracking)
|
||||||
{
|
{
|
||||||
QByteArray outputText;
|
|
||||||
return vcsFullySynchronousExec(
|
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,
|
void GitClient::handleMergeConflicts(const QString &workingDir, const QString &commit,
|
||||||
@@ -2962,35 +2946,35 @@ bool GitClient::synchronousStashRemove(const QString &workingDirectory, const QS
|
|||||||
arguments << "clear";
|
arguments << "clear";
|
||||||
else
|
else
|
||||||
arguments << "drop" << stash;
|
arguments << "drop" << stash;
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments);
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText);
|
if (resp.result == SynchronousProcessResponse::Finished) {
|
||||||
if (rc) {
|
const QString output = resp.stdOut();
|
||||||
const QString output = commandOutputFromLocal8Bit(outputText);
|
|
||||||
if (!output.isEmpty())
|
if (!output.isEmpty())
|
||||||
VcsOutputWindow::append(output);
|
VcsOutputWindow::append(output);
|
||||||
|
return true;
|
||||||
} else {
|
} 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,
|
bool GitClient::synchronousStashList(const QString &workingDirectory, QList<Stash> *stashes,
|
||||||
QString *errorMessage) const
|
QString *errorMessage) const
|
||||||
{
|
{
|
||||||
stashes->clear();
|
stashes->clear();
|
||||||
QByteArray outputText;
|
|
||||||
QByteArray errorText;
|
|
||||||
const QStringList arguments = { "stash", "list", noColorOption };
|
const QStringList arguments = { "stash", "list", noColorOption };
|
||||||
const bool rc = vcsFullySynchronousExec(workingDirectory, arguments, &outputText, &errorText);
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, arguments);
|
||||||
if (!rc) {
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
|
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Stash stash;
|
Stash stash;
|
||||||
foreach (const QString &line, commandOutputLinesFromLocal8Bit(outputText))
|
foreach (const QString &line, splitLines(resp.stdOut())) {
|
||||||
if (stash.parseStashLine(line))
|
if (stash.parseStashLine(line))
|
||||||
stashes->push_back(stash);
|
stashes->push_back(stash);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3013,13 +2997,11 @@ QString GitClient::readOneLine(const QString &workingDirectory, const QStringLis
|
|||||||
? QTextCodec::codecForName("UTF-8")
|
? QTextCodec::codecForName("UTF-8")
|
||||||
: QTextCodec::codecForLocale();
|
: QTextCodec::codecForLocale();
|
||||||
|
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
if (!vcsFullySynchronousExec(workingDirectory, arguments, &outputText, 0, silentFlags))
|
workingDirectory, arguments, silentFlags, vcsTimeoutS(), codec);
|
||||||
|
if (resp.result != SynchronousProcessResponse::Finished)
|
||||||
return QString();
|
return QString();
|
||||||
if (HostOsInfo::isWindowsHost())
|
return resp.stdOut().trimmed();
|
||||||
outputText.replace("\r\n", "\n");
|
|
||||||
|
|
||||||
return SynchronousProcess::normalizeNewlines(codec->toUnicode(outputText.trimmed()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::cloneRepository(const QString &directory,const QByteArray &url)
|
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()))
|
if (!synchronousInit(workingDirectory.path()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!vcsFullySynchronousExec(workingDirectory.path(),
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
|
||||||
{ "remote", "add", "origin", QString::fromUtf8(url) }, nullptr)) {
|
workingDirectory.path(), { "remote", "add", "origin", QString::fromUtf8(url) });
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SynchronousProcessResponse resp
|
|
||||||
= vcsSynchronousExec(workingDirectory.path(), { "fetch" }, flags);
|
|
||||||
if (resp.result != SynchronousProcessResponse::Finished)
|
if (resp.result != SynchronousProcessResponse::Finished)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!vcsFullySynchronousExec(workingDirectory.path(),
|
const SynchronousProcessResponse resp1 = vcsSynchronousExec(
|
||||||
{ "config", "branch.master.remote", "origin" }, nullptr)) {
|
workingDirectory.path(), { "fetch" }, flags);
|
||||||
|
if (resp1.result != SynchronousProcessResponse::Finished)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!vcsFullySynchronousExec(workingDirectory.path(),
|
const SynchronousProcessResponse resp2 = vcsSynchronousExec(
|
||||||
{ "config", "branch.master.merge", "refs/heads/master" }, nullptr)) {
|
workingDirectory.path(), { "config", "branch.master.remote", "origin" }, flags);
|
||||||
|
if (resp2.result != SynchronousProcessResponse::Finished)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
const SynchronousProcessResponse resp3 = vcsSynchronousExec(
|
||||||
|
workingDirectory.path(),
|
||||||
|
{ "config", "branch.master.merge", "refs/heads/master" }, flags);
|
||||||
|
return resp3.result == SynchronousProcessResponse::Finished;
|
||||||
} else {
|
} else {
|
||||||
workingDirectory.cdUp();
|
workingDirectory.cdUp();
|
||||||
const SynchronousProcessResponse resp = vcsSynchronousExec(
|
const SynchronousProcessResponse resp = vcsSynchronousExec(
|
||||||
@@ -3083,19 +3063,16 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// run git --version
|
// run git --version
|
||||||
QByteArray outputText;
|
const SynchronousProcessResponse resp = vcsSynchronousExec(
|
||||||
QByteArray errorText;
|
QString(), { "--version" }, silentFlags);
|
||||||
const bool rc = vcsFullySynchronousExec(QString(), { "--version" },
|
if (resp.result != SynchronousProcessResponse::Finished) {
|
||||||
&outputText, &errorText, silentFlags);
|
msgCannotRun(tr("Cannot determine Git version: %1").arg(resp.stdErr()), errorMessage);
|
||||||
if (!rc) {
|
|
||||||
msgCannotRun(tr("Cannot determine Git version: %1")
|
|
||||||
.arg(commandOutputFromLocal8Bit(errorText)),
|
|
||||||
errorMessage);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cut 'git version 1.6.5.1.sha'
|
// cut 'git version 1.6.5.1.sha'
|
||||||
// another form: 'git version 1.9.rc1'
|
// another form: 'git version 1.9.rc1'
|
||||||
const QString output = commandOutputFromLocal8Bit(outputText);
|
const QString output = resp.stdOut();
|
||||||
QRegExp versionPattern("^[^\\d]+(\\d+)\\.(\\d+)\\.(\\d+|rc\\d).*$");
|
QRegExp versionPattern("^[^\\d]+(\\d+)\\.(\\d+)\\.(\\d+|rc\\d).*$");
|
||||||
QTC_ASSERT(versionPattern.isValid(), return 0);
|
QTC_ASSERT(versionPattern.isValid(), return 0);
|
||||||
QTC_ASSERT(versionPattern.exactMatch(output), 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.
|
// This only works when called from the repo and outputs paths relative to it.
|
||||||
const QStringList args(QLatin1String("manifest"));
|
const QStringList args(QLatin1String("manifest"));
|
||||||
|
|
||||||
QByteArray output;
|
const SynchronousProcessResponse result = vcsFullySynchronousExec(repository, args);
|
||||||
vcsFullySynchronousExec(repository, args, &output);
|
|
||||||
const QDir repositoryDir(repository);
|
const QDir repositoryDir(repository);
|
||||||
const QFileInfo needle = QFileInfo(repositoryDir, relativeFilename);
|
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) {
|
foreach (const QString &fileName, files) {
|
||||||
const QFileInfo managedFile(repositoryDir, fileName);
|
const QFileInfo managedFile(repositoryDir, fileName);
|
||||||
if (needle == managedFile)
|
if (needle == managedFile)
|
||||||
@@ -96,7 +96,6 @@ bool MercurialClient::synchronousClone(const QString &workingDir,
|
|||||||
Q_UNUSED(workingDir);
|
Q_UNUSED(workingDir);
|
||||||
Q_UNUSED(extraOptions);
|
Q_UNUSED(extraOptions);
|
||||||
QDir workingDirectory(srcLocation);
|
QDir workingDirectory(srcLocation);
|
||||||
QByteArray output;
|
|
||||||
const unsigned flags = VcsCommand::SshPasswordPrompt |
|
const unsigned flags = VcsCommand::SshPasswordPrompt |
|
||||||
VcsCommand::ShowStdOut |
|
VcsCommand::ShowStdOut |
|
||||||
VcsCommand::ShowSuccessMessage;
|
VcsCommand::ShowSuccessMessage;
|
||||||
@@ -104,14 +103,16 @@ bool MercurialClient::synchronousClone(const QString &workingDir,
|
|||||||
if (workingDirectory.exists()) {
|
if (workingDirectory.exists()) {
|
||||||
// Let's make first init
|
// Let's make first init
|
||||||
QStringList arguments(QLatin1String("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;
|
return false;
|
||||||
|
|
||||||
// Then pull remote repository
|
// Then pull remote repository
|
||||||
arguments.clear();
|
arguments.clear();
|
||||||
arguments << QLatin1String("pull") << dstLocation;
|
arguments << QLatin1String("pull") << dstLocation;
|
||||||
const SynchronousProcessResponse resp1 =
|
const SynchronousProcessResponse resp1 = vcsSynchronousExec(
|
||||||
vcsSynchronousExec(workingDirectory.path(), arguments, flags);
|
workingDirectory.path(), arguments, flags);
|
||||||
if (resp1.result != SynchronousProcessResponse::Finished)
|
if (resp1.result != SynchronousProcessResponse::Finished)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -127,15 +128,15 @@ bool MercurialClient::synchronousClone(const QString &workingDir,
|
|||||||
// And last update repository
|
// And last update repository
|
||||||
arguments.clear();
|
arguments.clear();
|
||||||
arguments << QLatin1String("update");
|
arguments << QLatin1String("update");
|
||||||
const SynchronousProcessResponse resp2 =
|
const SynchronousProcessResponse resp2 = vcsSynchronousExec(
|
||||||
vcsSynchronousExec(workingDirectory.path(), arguments, flags);
|
workingDirectory.path(), arguments, flags);
|
||||||
return resp2.result == SynchronousProcessResponse::Finished;
|
return resp2.result == SynchronousProcessResponse::Finished;
|
||||||
} else {
|
} else {
|
||||||
QStringList arguments(QLatin1String("clone"));
|
QStringList arguments(QLatin1String("clone"));
|
||||||
arguments << dstLocation << workingDirectory.dirName();
|
arguments << dstLocation << workingDirectory.dirName();
|
||||||
workingDirectory.cdUp();
|
workingDirectory.cdUp();
|
||||||
const SynchronousProcessResponse resp =
|
const SynchronousProcessResponse resp = vcsSynchronousExec(
|
||||||
vcsSynchronousExec(workingDirectory.path(), arguments, flags);
|
workingDirectory.path(), arguments, flags);
|
||||||
return resp.result == SynchronousProcessResponse::Finished;
|
return resp.result == SynchronousProcessResponse::Finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,24 +195,22 @@ QStringList MercurialClient::parentRevisionsSync(const QString &workingDirectory
|
|||||||
args << QLatin1String("parents") << QLatin1String("-r") <<revision;
|
args << QLatin1String("parents") << QLatin1String("-r") <<revision;
|
||||||
if (!file.isEmpty())
|
if (!file.isEmpty())
|
||||||
args << file;
|
args << file;
|
||||||
QByteArray outputData;
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args);
|
||||||
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
|
if (resp.result != SynchronousProcessResponse::Finished)
|
||||||
return QStringList();
|
return QStringList();
|
||||||
const QString output = SynchronousProcess::normalizeNewlines(
|
|
||||||
QString::fromLocal8Bit(outputData));
|
|
||||||
/* Looks like: \code
|
/* Looks like: \code
|
||||||
changeset: 0:031a48610fba
|
changeset: 0:031a48610fba
|
||||||
user: ...
|
user: ...
|
||||||
\endcode */
|
\endcode */
|
||||||
// Obtain first line and split by blank-delimited tokens
|
// 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) {
|
if (lines.size() < 1) {
|
||||||
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
|
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(resp.stdOut())));
|
||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
QStringList changeSets = lines.front().simplified().split(QLatin1Char(' '));
|
QStringList changeSets = lines.front().simplified().split(QLatin1Char(' '));
|
||||||
if (changeSets.size() < 2) {
|
if (changeSets.size() < 2) {
|
||||||
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
|
VcsOutputWindow::appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(resp.stdOut())));
|
||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
// Remove revision numbers
|
// Remove revision numbers
|
||||||
@@ -231,18 +230,15 @@ QString MercurialClient::shortDescriptionSync(const QString &workingDirectory,
|
|||||||
const QString &revision,
|
const QString &revision,
|
||||||
const QString &format)
|
const QString &format)
|
||||||
{
|
{
|
||||||
QString description;
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << QLatin1String("log") << QLatin1String("-r") <<revision;
|
args << QLatin1String("log") << QLatin1String("-r") <<revision;
|
||||||
if (!format.isEmpty())
|
if (!format.isEmpty())
|
||||||
args << QLatin1String("--template") << format;
|
args << QLatin1String("--template") << format;
|
||||||
QByteArray outputData;
|
|
||||||
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
|
const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, args);
|
||||||
|
if (resp.result != SynchronousProcessResponse::Finished)
|
||||||
return revision;
|
return revision;
|
||||||
description = commandOutputFromLocal8Bit(outputData);
|
return stripLastNewline(resp.stdOut());
|
||||||
if (description.endsWith(QLatin1Char('\n')))
|
|
||||||
description.truncate(description.size() - 1);
|
|
||||||
return description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default format: "SHA1 (author summmary)"
|
// Default format: "SHA1 (author summmary)"
|
||||||
@@ -258,9 +254,7 @@ bool MercurialClient::managesFile(const QString &workingDirectory, const QString
|
|||||||
{
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << QLatin1String("status") << QLatin1String("--unknown") << fileName;
|
args << QLatin1String("status") << QLatin1String("--unknown") << fileName;
|
||||||
QByteArray output;
|
return vcsFullySynchronousExec(workingDirectory, args).stdOut().isEmpty();
|
||||||
vcsFullySynchronousExec(workingDirectory, args, &output);
|
|
||||||
return output.isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MercurialClient::incoming(const QString &repositoryRoot, const QString &repository)
|
void MercurialClient::incoming(const QString &repositoryRoot, const QString &repository)
|
||||||
|
@@ -138,14 +138,13 @@ QString SubversionClient::synchronousTopic(const QString &repository)
|
|||||||
QStringList args;
|
QStringList args;
|
||||||
args << QLatin1String("info");
|
args << QLatin1String("info");
|
||||||
|
|
||||||
QByteArray stdOut;
|
const SynchronousProcessResponse result = vcsFullySynchronousExec(repository, args);
|
||||||
if (!vcsFullySynchronousExec(repository, args, &stdOut))
|
if (result.result != SynchronousProcessResponse::Finished)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
const QString revisionString = QLatin1String("Revision: ");
|
const QString revisionString = QLatin1String("Revision: ");
|
||||||
// stdOut is ASCII only (at least in those areas we care about).
|
// stdOut is ASCII only (at least in those areas we care about).
|
||||||
QString output = commandOutputFromLocal8Bit(stdOut);
|
foreach (const QString &line, result.stdOut().split(QLatin1Char('\n'))) {
|
||||||
foreach (const QString &line, output.split(QLatin1Char('\n'))) {
|
|
||||||
if (line.startsWith(revisionString))
|
if (line.startsWith(revisionString))
|
||||||
return QString::fromLatin1("r") + line.mid(revisionString.count());
|
return QString::fromLatin1("r") + line.mid(revisionString.count());
|
||||||
}
|
}
|
||||||
|
@@ -877,21 +877,19 @@ SubversionResponse SubversionPlugin::runSvn(const QString &workingDir,
|
|||||||
int timeOutS, unsigned flags,
|
int timeOutS, unsigned flags,
|
||||||
QTextCodec *outputCodec) const
|
QTextCodec *outputCodec) const
|
||||||
{
|
{
|
||||||
const FileName executable = client()->vcsBinary();
|
|
||||||
SubversionResponse response;
|
SubversionResponse response;
|
||||||
if (executable.isEmpty()) {
|
if (client()->vcsBinary().isEmpty()) {
|
||||||
response.error = true;
|
response.error = true;
|
||||||
response.message =tr("No subversion executable specified.");
|
response.message =tr("No subversion executable specified.");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SynchronousProcessResponse sp_resp =
|
const SynchronousProcessResponse sp_resp
|
||||||
VcsBasePlugin::runVcs(workingDir, executable, arguments, timeOutS,
|
= client()->vcsFullySynchronousExec(workingDir, arguments, flags, timeOutS, outputCodec);
|
||||||
flags, outputCodec);
|
|
||||||
|
|
||||||
response.error = sp_resp.result != SynchronousProcessResponse::Finished;
|
response.error = sp_resp.result != SynchronousProcessResponse::Finished;
|
||||||
if (response.error)
|
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.stdErr = sp_resp.stdErr();
|
||||||
response.stdOut = sp_resp.stdOut();
|
response.stdOut = sp_resp.stdOut();
|
||||||
return response;
|
return response;
|
||||||
|
@@ -155,8 +155,13 @@ QString VcsBaseClientImpl::commandOutputFromLocal8Bit(const QByteArray &a)
|
|||||||
|
|
||||||
QStringList VcsBaseClientImpl::commandOutputLinesFromLocal8Bit(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');
|
const QChar newLine = QLatin1Char('\n');
|
||||||
|
QString output = s;
|
||||||
if (output.endsWith(newLine))
|
if (output.endsWith(newLine))
|
||||||
output.truncate(output.size() - 1);
|
output.truncate(output.size() - 1);
|
||||||
if (output.isEmpty())
|
if (output.isEmpty())
|
||||||
@@ -164,6 +169,13 @@ QStringList VcsBaseClientImpl::commandOutputLinesFromLocal8Bit(const QByteArray
|
|||||||
return output.split(newLine);
|
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)
|
void VcsBaseClientImpl::resetCachedVcsInfo(const QString &workingDir)
|
||||||
{
|
{
|
||||||
Core::VcsManager::resetVersionControlForDirectory(workingDir);
|
Core::VcsManager::resetVersionControlForDirectory(workingDir);
|
||||||
@@ -182,18 +194,15 @@ void VcsBaseClientImpl::annotateRevisionRequested(const QString &workingDirector
|
|||||||
annotate(workingDirectory, file, changeCopy, line);
|
annotate(workingDirectory, file, changeCopy, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
|
Utils::SynchronousProcessResponse
|
||||||
QByteArray *outputData, QByteArray *errorData,
|
VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
|
||||||
unsigned flags) const
|
unsigned flags, int timeoutS, QTextCodec *codec) const
|
||||||
{
|
{
|
||||||
QByteArray internalErrorData;
|
VcsCommand command(workingDir, processEnvironment());
|
||||||
QScopedPointer<VcsCommand> command(createCommand(workingDir));
|
command.addFlags(flags);
|
||||||
command->addFlags(flags);
|
if (codec)
|
||||||
bool result = command->runFullySynchronous(vcsBinary(), args, vcsTimeoutS(), outputData,
|
command.setCodec(codec);
|
||||||
errorData ? errorData : &internalErrorData);
|
return command.runCommand(vcsBinary(), args, (timeoutS > 0) ? timeoutS : vcsTimeoutS());
|
||||||
if (!internalErrorData.isEmpty() && !(flags & VcsCommand::SuppressStdErr))
|
|
||||||
VcsOutputWindow::appendError(commandOutputFromLocal8Bit(internalErrorData));
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VcsCommand *VcsBaseClientImpl::vcsExec(const QString &workingDirectory, const QStringList &arguments,
|
VcsCommand *VcsBaseClientImpl::vcsExec(const QString &workingDirectory, const QStringList &arguments,
|
||||||
@@ -300,10 +309,10 @@ bool VcsBaseClient::synchronousCreateRepository(const QString &workingDirectory,
|
|||||||
{
|
{
|
||||||
QStringList args(vcsCommandString(CreateRepositoryCommand));
|
QStringList args(vcsCommandString(CreateRepositoryCommand));
|
||||||
args << extraOptions;
|
args << extraOptions;
|
||||||
QByteArray outputData;
|
Utils::SynchronousProcessResponse result = vcsFullySynchronousExec(workingDirectory, args);
|
||||||
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
|
if (result.result != Utils::SynchronousProcessResponse::Finished)
|
||||||
return false;
|
return false;
|
||||||
VcsOutputWindow::append(commandOutputFromLocal8Bit(outputData));
|
VcsOutputWindow::append(result.stdOut());
|
||||||
|
|
||||||
resetCachedVcsInfo(workingDirectory);
|
resetCachedVcsInfo(workingDirectory);
|
||||||
|
|
||||||
@@ -318,10 +327,10 @@ bool VcsBaseClient::synchronousClone(const QString &workingDir,
|
|||||||
QStringList args;
|
QStringList args;
|
||||||
args << vcsCommandString(CloneCommand)
|
args << vcsCommandString(CloneCommand)
|
||||||
<< extraOptions << srcLocation << dstLocation;
|
<< extraOptions << srcLocation << dstLocation;
|
||||||
QByteArray stdOut;
|
|
||||||
const bool cloneOk = vcsFullySynchronousExec(workingDir, args, &stdOut);
|
Utils::SynchronousProcessResponse result = vcsFullySynchronousExec(workingDir, args);
|
||||||
resetCachedVcsInfo(workingDir);
|
resetCachedVcsInfo(workingDir);
|
||||||
return cloneOk;
|
return result.result == Utils::SynchronousProcessResponse::Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VcsBaseClient::synchronousAdd(const QString &workingDir, const QString &filename,
|
bool VcsBaseClient::synchronousAdd(const QString &workingDir, const QString &filename,
|
||||||
@@ -329,8 +338,7 @@ bool VcsBaseClient::synchronousAdd(const QString &workingDir, const QString &fil
|
|||||||
{
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << vcsCommandString(AddCommand) << extraOptions << filename;
|
args << vcsCommandString(AddCommand) << extraOptions << filename;
|
||||||
QByteArray stdOut;
|
return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished;
|
||||||
return vcsFullySynchronousExec(workingDir, args, &stdOut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VcsBaseClient::synchronousRemove(const QString &workingDir, const QString &filename,
|
bool VcsBaseClient::synchronousRemove(const QString &workingDir, const QString &filename,
|
||||||
@@ -338,8 +346,7 @@ bool VcsBaseClient::synchronousRemove(const QString &workingDir, const QString &
|
|||||||
{
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << vcsCommandString(RemoveCommand) << extraOptions << filename;
|
args << vcsCommandString(RemoveCommand) << extraOptions << filename;
|
||||||
QByteArray stdOut;
|
return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished;
|
||||||
return vcsFullySynchronousExec(workingDir, args, &stdOut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VcsBaseClient::synchronousMove(const QString &workingDir,
|
bool VcsBaseClient::synchronousMove(const QString &workingDir,
|
||||||
@@ -348,8 +355,7 @@ bool VcsBaseClient::synchronousMove(const QString &workingDir,
|
|||||||
{
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << vcsCommandString(MoveCommand) << extraOptions << from << to;
|
args << vcsCommandString(MoveCommand) << extraOptions << from << to;
|
||||||
QByteArray stdOut;
|
return vcsFullySynchronousExec(workingDir, args).result == Utils::SynchronousProcessResponse::Finished;
|
||||||
return vcsFullySynchronousExec(workingDir, args, &stdOut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VcsBaseClient::synchronousPull(const QString &workingDir,
|
bool VcsBaseClient::synchronousPull(const QString &workingDir,
|
||||||
|
@@ -95,28 +95,31 @@ public:
|
|||||||
static QString commandOutputFromLocal8Bit(const QByteArray &a);
|
static QString commandOutputFromLocal8Bit(const QByteArray &a);
|
||||||
// Return converted command output split into lines
|
// Return converted command output split into lines
|
||||||
static QStringList commandOutputLinesFromLocal8Bit(const QByteArray &a);
|
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:
|
protected:
|
||||||
void resetCachedVcsInfo(const QString &workingDir);
|
void resetCachedVcsInfo(const QString &workingDir);
|
||||||
virtual void annotateRevisionRequested(const QString &workingDirectory, const QString &file,
|
virtual void annotateRevisionRequested(const QString &workingDirectory, const QString &file,
|
||||||
const QString &change, int line);
|
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
|
// Synchronous VCS execution using Utils::SynchronousProcess, with
|
||||||
// log windows updating (using VcsBasePlugin::runVcs with flags)
|
// log windows updating (using VcsBasePlugin::runVcs with flags)
|
||||||
Utils::SynchronousProcessResponse vcsSynchronousExec(const QString &workingDir,
|
Utils::SynchronousProcessResponse vcsSynchronousExec(const QString &workingDir,
|
||||||
const QStringList &args,
|
const QStringList &args,
|
||||||
unsigned flags = 0,
|
unsigned flags = 0,
|
||||||
QTextCodec *outputCodec = 0) const;
|
QTextCodec *outputCodec = nullptr) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
Reference in New Issue
Block a user