From 9b1de56e97a770715716e90577c944e56b7b7d74 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Wed, 22 Jul 2026 16:56:16 +0200 Subject: [PATCH] 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. --- gitplusplus.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/gitplusplus.cpp b/gitplusplus.cpp index fab4594..df44a69 100644 --- a/gitplusplus.cpp +++ b/gitplusplus.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -2484,6 +2486,39 @@ void GitPlusPlusView::createWorkspace() auto *destEdit = new QLineEdit(&dlg); 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; destRow->addWidget(destLabel); destRow->addWidget(destEdit, 1);