aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/git/branchmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/git/branchmodel.cpp')
-rw-r--r--src/plugins/git/branchmodel.cpp112
1 files changed, 73 insertions, 39 deletions
diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 3c4971fa734..3bf65cf5b38 100644
--- a/src/plugins/git/branchmodel.cpp
+++ b/src/plugins/git/branchmodel.cpp
@@ -11,8 +11,8 @@
#include <vcsbase/vcsoutputwindow.h>
#include <utils/environment.h>
+#include <utils/process.h>
#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
#include <utils/stringutils.h>
#include <QDateTime>
@@ -20,6 +20,7 @@
#include <set>
+using namespace Tasking;
using namespace Utils;
using namespace VcsBase;
@@ -229,6 +230,7 @@ public:
QString currentSha;
QDateTime currentDateTime;
QStringList obsoleteLocalBranches;
+ std::unique_ptr<TaskTree> refreshTask;
bool oldBranchesIncluded = false;
struct OldEntry
@@ -399,50 +401,82 @@ void BranchModel::clear()
d->obsoleteLocalBranches.clear();
}
-bool BranchModel::refresh(const FilePath &workingDirectory, QString *errorMessage)
+void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError)
{
+ if (d->refreshTask) {
+ endResetModel(); // for the running task tree.
+ d->refreshTask.reset(); // old running tree is reset, no handlers are being called
+ }
beginResetModel();
clear();
if (workingDirectory.isEmpty()) {
endResetModel();
- return true;
+ return;
}
- d->currentSha = d->client->synchronousTopRevision(workingDirectory, &d->currentDateTime);
- QStringList args = {"--format=%(objectname)\t%(refname)\t%(upstream:short)\t"
- "%(*objectname)\t%(committerdate:raw)\t%(*committerdate:raw)",
- "refs/heads/**",
- "refs/remotes/**"};
- if (d->client->settings().showTags.value())
- args << "refs/tags/**";
- QString output;
- if (!d->client->synchronousForEachRefCmd(workingDirectory, args, &output, errorMessage)) {
- endResetModel();
- return false;
- }
+ const ProcessTask topRevisionProc =
+ d->client->topRevision(workingDirectory,
+ [=](const QString &ref, const QDateTime &dateTime) {
+ d->currentSha = ref;
+ d->currentDateTime = dateTime;
+ });
+
+ const auto setupForEachRef = [=](Process &process) {
+ d->workingDirectory = workingDirectory;
+ QStringList args = {"for-each-ref",
+ "--format=%(objectname)\t%(refname)\t%(upstream:short)\t"
+ "%(*objectname)\t%(committerdate:raw)\t%(*committerdate:raw)",
+ "refs/heads/**",
+ "refs/remotes/**"};
+ if (settings().showTags())
+ args << "refs/tags/**";
+ d->client->setupCommand(process, workingDirectory, args);
+ };
- d->workingDirectory = workingDirectory;
- const QStringList lines = output.split('\n');
- for (const QString &l : lines)
- d->parseOutputLine(l);
- d->flushOldEntries();
+ const auto forEachRefDone = [=](const Process &process) {
+ const QString output = process.stdOut();
+ const QStringList lines = output.split('\n');
+ for (const QString &l : lines)
+ d->parseOutputLine(l);
+ d->flushOldEntries();
+
+ d->updateAllUpstreamStatus(d->rootNode->children.at(LocalBranches));
+ if (d->currentBranch) {
+ if (d->currentBranch->isLocal())
+ d->currentBranch = nullptr;
+ setCurrentBranch();
+ }
+ if (!d->currentBranch) {
+ BranchNode *local = d->rootNode->children.at(LocalBranches);
+ d->currentBranch = d->headNode = new BranchNode(
+ Tr::tr("Detached HEAD"), "HEAD", {}, d->currentDateTime);
+ local->prepend(d->headNode);
+ }
+ };
- d->updateAllUpstreamStatus(d->rootNode->children.at(LocalBranches));
- if (d->currentBranch) {
- if (d->currentBranch->isLocal())
- d->currentBranch = nullptr;
- setCurrentBranch();
- }
- if (!d->currentBranch) {
- BranchNode *local = d->rootNode->children.at(LocalBranches);
- d->currentBranch = d->headNode = new BranchNode(Tr::tr("Detached HEAD"), "HEAD", QString(),
- d->currentDateTime);
- local->prepend(d->headNode);
- }
+ const auto forEachRefError = [=](const Process &process) {
+ if (showError == ShowError::No)
+ return;
+ const QString message = Tr::tr("Cannot run \"%1\" in \"%2\": %3")
+ .arg("git for-each-ref")
+ .arg(workingDirectory.toUserOutput())
+ .arg(process.cleanedStdErr());
+ VcsBase::VcsOutputWindow::appendError(message);
+ };
- endResetModel();
+ const auto finalize = [this] {
+ endResetModel();
+ d->refreshTask.release()->deleteLater();
+ };
- return true;
+ const Group root {
+ topRevisionProc,
+ ProcessTask(setupForEachRef, forEachRefDone, forEachRefError),
+ onGroupDone(finalize),
+ onGroupError(finalize)
+ };
+ d->refreshTask.reset(new TaskTree(root));
+ d->refreshTask->start();
}
void BranchModel::setCurrentBranch()
@@ -469,7 +503,7 @@ void BranchModel::renameBranch(const QString &oldName, const QString &newName)
&output, &errorMessage))
VcsOutputWindow::appendError(errorMessage);
else
- refresh(d->workingDirectory, &errorMessage);
+ refresh(d->workingDirectory);
}
void BranchModel::renameTag(const QString &oldName, const QString &newName)
@@ -482,7 +516,7 @@ void BranchModel::renameTag(const QString &oldName, const QString &newName)
&output, &errorMessage)) {
VcsOutputWindow::appendError(errorMessage);
} else {
- refresh(d->workingDirectory, &errorMessage);
+ refresh(d->workingDirectory);
}
}
@@ -771,7 +805,7 @@ void BranchModel::Private::parseOutputLine(const QString &line, bool force)
const qint64 age = dateTime.daysTo(QDateTime::currentDateTime());
isOld = age > Constants::OBSOLETE_COMMIT_AGE_IN_DAYS;
}
- const bool showTags = client->settings().showTags.value();
+ const bool showTags = settings().showTags();
// insert node into tree:
QStringList nameParts = fullName.split('/');
@@ -885,12 +919,12 @@ void BranchModel::updateUpstreamStatus(BranchNode *node)
if (node->tracking.isEmpty())
return;
- QtcProcess *process = new QtcProcess(node);
+ Process *process = new Process(node);
process->setEnvironment(d->client->processEnvironment());
process->setCommand({d->client->vcsBinary(), {"rev-list", "--no-color", "--left-right",
"--count", node->fullRef() + "..." + node->tracking}});
process->setWorkingDirectory(d->workingDirectory);
- connect(process, &QtcProcess::done, this, [this, process, node] {
+ connect(process, &Process::done, this, [this, process, node] {
process->deleteLater();
if (process->result() != ProcessResult::FinishedWithSuccess)
return;