Add branch auto-completion to create workspace dialog

Destination field offers completion from all branch names found across
repos in the source workspace. Uses MatchContains for substring matching.
Completer updates when source path changes.

Existing fan-out logic already handles checkout-vs-create per repo:
if branch exists in a repo, checks it out; otherwise creates it.
This commit is contained in:
Levi Neely 2026-07-22 16:56:16 +02:00
parent cd123422f9
commit 9b1de56e97
1 changed files with 35 additions and 0 deletions

View File

@ -21,6 +21,7 @@
#include <QCheckBox> #include <QCheckBox>
#include <QClipboard> #include <QClipboard>
#include <QComboBox> #include <QComboBox>
#include <QCompleter>
#include <QDialog> #include <QDialog>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
@ -41,6 +42,7 @@
#include <QPushButton> #include <QPushButton>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QSplitter> #include <QSplitter>
#include <QStringListModel>
#include <QStatusBar> #include <QStatusBar>
#include <QSettings> #include <QSettings>
#include <QTabBar> #include <QTabBar>
@ -2484,6 +2486,39 @@ void GitPlusPlusView::createWorkspace()
auto *destEdit = new QLineEdit(&dlg); auto *destEdit = new QLineEdit(&dlg);
destEdit->setPlaceholderText(QStringLiteral("workspace-name (also used as branch name)")); destEdit->setPlaceholderText(QStringLiteral("workspace-name (also used as branch name)"));
// Branch auto-completion from source repos
auto *completer = new QCompleter(&dlg);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setFilterMode(Qt::MatchContains);
destEdit->setCompleter(completer);
auto updateCompleter = [sourceEdit, completer]() {
QStringList branches;
QDir src(sourceEdit->text().trimmed());
if (src.exists()) {
const auto entries = src.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const auto &entry : entries) {
QString repoPath = src.absoluteFilePath(entry);
if (QFileInfo::exists(repoPath + QStringLiteral("/.git"))) {
QByteArray out = GitProcess::run(repoPath,
{QStringLiteral("for-each-ref"), QStringLiteral("--format=%(refname:short)"), QStringLiteral("refs/heads/")});
const auto lines = QString::fromUtf8(out).split(QLatin1Char('\n'), Qt::SkipEmptyParts);
for (const auto &line : lines) {
QString b = line.trimmed();
if (!b.isEmpty() && !branches.contains(b))
branches.append(b);
}
}
}
}
branches.sort();
completer->setModel(new QStringListModel(branches, completer));
};
// Populate on dialog open and when source changes
updateCompleter();
connect(sourceEdit, &QLineEdit::editingFinished, &dlg, updateCompleter);
auto *destRow = new QHBoxLayout; auto *destRow = new QHBoxLayout;
destRow->addWidget(destLabel); destRow->addWidget(destLabel);
destRow->addWidget(destEdit, 1); destRow->addWidget(destEdit, 1);