Git: Improve branch listing in Show

* Separate local and remote branches
* List branches for each remote in a separate line
* List up to 12 branches per group
* Elide in the middle, list first and last branches in each group

Task-number: QTCREATORBUG-16949
Change-Id: If293cbd2536921261d9f420c71c2b68c8cb5bfe2
Reviewed-by: André Hartmann <aha_1980@gmx.de>
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Orgad Shaneh
2017-05-19 00:16:10 +03:00
committed by Orgad Shaneh
parent 60eb763979
commit 2584c4e180

View File

@@ -81,6 +81,7 @@ const char GIT_DIRECTORY[] = ".git";
const char graphLogFormatC[] = "%h %d %an %s %ci";
const char HEAD[] = "HEAD";
const char CHERRY_PICK_HEAD[] = "CHERRY_PICK_HEAD";
const char BRANCHES_PREFIX[] = "Branches: ";
const char stashNamePrefix[] = "stash@{";
const char noColorOption[] = "--no-color";
const char decorateOption[] = "--decorate";
@@ -1418,6 +1419,32 @@ void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const
}
}
static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first)
{
const int limit = 12;
const int count = branches->count();
int more = 0;
QString output;
if (*first)
*first = false;
else
output += QString(sizeof(BRANCHES_PREFIX) - 1, ' '); // Align
output += prefix + ": ";
// If there are more than 'limit' branches, list limit/2 (first limit/4 and last limit/4)
if (count > limit) {
const int leave = limit / 2;
more = count - leave;
branches->erase(branches->begin() + leave / 2 + 1, branches->begin() + count - leave / 2);
(*branches)[leave / 2] = "...";
}
output += branches->join(", ");
//: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'"
// in git show.
if (more > 0)
output += ' ' + GitClient::tr("and %n more", 0, more);
return output;
}
void GitClient::branchesForCommit(const QString &revision)
{
auto controller = qobject_cast<DiffEditorController *>(sender());
@@ -1426,29 +1453,40 @@ void GitClient::branchesForCommit(const QString &revision)
workingDirectory, {"branch", noColorOption, "-a", "--contains", revision}, nullptr,
false, 0, workingDirectory);
connect(command, &VcsCommand::stdOutText, controller, [controller](const QString &text) {
QString moreBranches;
QStringList res;
QHash<QString, QStringList> remotes;
const QString remotePrefix = "remotes/";
const QString localPrefix = "<Local>";
const int prefixLength = remotePrefix.length();
QString output = BRANCHES_PREFIX;
QStringList branches;
QString previousRemote = localPrefix;
bool first = true;
for (const QString &branch : text.split('\n')) {
const QString b = branch.mid(2).trimmed();
if (!b.isEmpty())
res << b;
if (b.isEmpty())
continue;
if (b.startsWith(remotePrefix)) {
const int nextSlash = b.indexOf('/', prefixLength);
if (nextSlash < 0)
continue;
const QString remote = b.mid(prefixLength, nextSlash - prefixLength);
if (remote != previousRemote) {
output += branchesDisplay(previousRemote, &branches, &first) + '\n';
branches.clear();
previousRemote = remote;
}
branches << b.mid(nextSlash + 1);
} else {
branches << b;
}
}
const int branchCount = res.count();
// If there are more than 20 branches, list first 10 followed by a hint
if (branchCount > 20) {
const int leave = 10;
//: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'"
// in git show.
moreBranches = ' ' + tr("and %n more", 0, branchCount - leave);
res.erase(res.begin() + leave, res.end());
if (branches.isEmpty()) {
if (previousRemote == localPrefix)
output += tr("<None>");
} else {
output += branchesDisplay(previousRemote, &branches, &first);
}
QString branches = "Branches: ";
if (res.isEmpty())
branches += tr("<None>");
else
branches += res.join(", ") + moreBranches;
controller->branchesReceived(branches);
controller->branchesReceived(output.trimmed());
});
}