diff options
Diffstat (limited to 'src/plugins/git/branchmodel.cpp')
-rw-r--r-- | src/plugins/git/branchmodel.cpp | 112 |
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; |