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);