From 1888e52d7c3ccb5beee45a98b05f49ba40efb214 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 5 May 2019 23:49:08 +0300 Subject: [PATCH] Git: Show at least 5 entries in Branches even if they're old MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTCREATORBUG-22372 Change-Id: Ia4e0477a4e810c3c922cebbad1e44d295abca524 Reviewed-by: André Hartmann Reviewed-by: Tobias Hunger --- src/plugins/git/branchmodel.cpp | 74 +++++++++++++++++++++++++++------ src/plugins/git/gitconstants.h | 1 + 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index 34b19ad449f..bf74f7b32cc 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -36,6 +36,8 @@ #include #include +#include + using namespace VcsBase; namespace Git { @@ -214,7 +216,8 @@ public: } bool hasTags() const { return rootNode->children.count() > Tags; } - void parseOutputLine(const QString &line); + void parseOutputLine(const QString &line, bool force = false); + void flushOldEntries(); GitClient *client; QString workingDirectory; @@ -226,6 +229,17 @@ public: QStringList obsoleteLocalBranches; Utils::FileSystemWatcher fsWatcher; bool oldBranchesIncluded = false; + + struct OldEntry + { + QString line; + QDateTime dateTime; + bool operator<(const OldEntry &other) const { return dateTime < other.dateTime; } + }; + + BranchNode *currentRoot = nullptr; + QString currentRemote; + std::set oldEntries; }; // -------------------------------------------------------------------------- @@ -410,6 +424,7 @@ bool BranchModel::refresh(const QString &workingDirectory, QString *errorMessage const QStringList lines = output.split('\n'); for (const QString &l : lines) d->parseOutputLine(l); + d->flushOldEntries(); if (d->currentBranch) { if (d->currentBranch->isLocal()) @@ -723,7 +738,7 @@ Utils::optional BranchModel::remoteName(const QModelIndex &idx) const return Utils::nullopt; } -void BranchModel::Private::parseOutputLine(const QString &line) +void BranchModel::Private::parseOutputLine(const QString &line, bool force) { if (line.size() < 3) return; @@ -744,14 +759,10 @@ void BranchModel::Private::parseOutputLine(const QString &line) dateTime = QDateTime::fromSecsSinceEpoch(timeT); } - if (!oldBranchesIncluded && !current && dateTime.isValid()) { + bool isOld = false; + if (!oldBranchesIncluded && !force && !current && dateTime.isValid()) { const qint64 age = dateTime.daysTo(QDateTime::currentDateTime()); - if (age > Constants::OBSOLETE_COMMIT_AGE_IN_DAYS) { - const QString heads = "refs/heads/"; - if (fullName.startsWith(heads)) - obsoleteLocalBranches.append(fullName.mid(heads.size())); - return; - } + isOld = age > Constants::OBSOLETE_COMMIT_AGE_IN_DAYS; } bool showTags = client->settings().boolValue(GitSettings::showTagsKey); @@ -760,18 +771,45 @@ void BranchModel::Private::parseOutputLine(const QString &line) nameParts.removeFirst(); // remove refs... BranchNode *root = nullptr; + BranchNode *oldEntriesRoot = nullptr; + RootNodes rootType; if (nameParts.first() == "heads") { - root = rootNode->children.at(LocalBranches); + rootType = LocalBranches; + if (isOld) + obsoleteLocalBranches.append(fullName.mid(sizeof("refs/heads/")-1)); } else if (nameParts.first() == "remotes") { - root = rootNode->children.at(RemoteBranches); + rootType = RemoteBranches; + const QString remoteName = nameParts.at(1); + root = rootNode->children.at(rootType); + oldEntriesRoot = root->childOfName(remoteName); + if (!oldEntriesRoot) + oldEntriesRoot = root->append(new BranchNode(remoteName)); } else if (showTags && nameParts.first() == "tags") { if (!hasTags()) // Tags is missing, add it rootNode->append(new BranchNode(tr("Tags"), "refs/tags")); - root = rootNode->children.at(Tags); + rootType = Tags; } else { return; } + root = rootNode->children.at(rootType); + if (!oldEntriesRoot) + oldEntriesRoot = root; + if (isOld) { + if (oldEntriesRoot->children.size() > Constants::MAX_OBSOLETE_COMMITS_TO_DISPLAY) + return; + if (currentRoot != oldEntriesRoot) { + flushOldEntries(); + currentRoot = oldEntriesRoot; + } + const bool eraseOldestEntry = oldEntries.size() >= Constants::MAX_OBSOLETE_COMMITS_TO_DISPLAY; + if (!eraseOldestEntry || dateTime > oldEntries.begin()->dateTime) { + if (eraseOldestEntry) + oldEntries.erase(oldEntries.begin()); + oldEntries.insert(Private::OldEntry{line, dateTime}); + } + return; + } nameParts.removeFirst(); // limit depth of list. Git basically only ever wants one / and considers the rest as part of @@ -790,6 +828,18 @@ void BranchModel::Private::parseOutputLine(const QString &line) currentBranch = newNode; } +void BranchModel::Private::flushOldEntries() +{ + if (!currentRoot) + return; + for (int size = currentRoot->children.size(); size > 0 && !oldEntries.empty(); --size) + oldEntries.erase(oldEntries.begin()); + for (const Private::OldEntry &entry : oldEntries) + parseOutputLine(entry.line, true); + oldEntries.clear(); + currentRoot = nullptr; +} + BranchNode *BranchModel::indexToNode(const QModelIndex &index) const { if (index.column() > 1) diff --git a/src/plugins/git/gitconstants.h b/src/plugins/git/gitconstants.h index fb97b16b1d7..9cb9ddada1f 100644 --- a/src/plugins/git/gitconstants.h +++ b/src/plugins/git/gitconstants.h @@ -51,6 +51,7 @@ const char SUBMIT_MIMETYPE[] = "text/vnd.qtcreator.git.submit"; const char C_GITEDITORID[] = "Git Editor"; const int OBSOLETE_COMMIT_AGE_IN_DAYS = 90; +const int MAX_OBSOLETE_COMMITS_TO_DISPLAY = 5; const char EXPAND_BRANCHES[] = "Branches: ";