Support deleting remote branches via the delete button
The delete button and context menu action now detect whether the selected branch is remote (tracked via Qt::UserRole on list items). Remote branches are deleted with `git push --delete <remote> <branch>` with an appropriate confirmation dialog warning about server-side removal. Local branches continue using `git branch -D`.
This commit is contained in:
parent
3642f8b743
commit
7dabd4b9e6
|
|
@ -836,6 +836,7 @@ void GitPlusPlusView::onBranchFinished(int exitCode, QProcess::ExitStatus)
|
|||
if (exitCode == 0) {
|
||||
QByteArray output = proc->readAllStandardOutput();
|
||||
m_allBranches.clear();
|
||||
m_remoteBranches.clear();
|
||||
QString current;
|
||||
|
||||
const auto lines = output.split('\n');
|
||||
|
|
@ -849,17 +850,25 @@ void GitPlusPlusView::onBranchFinished(int exitCode, QProcess::ExitStatus)
|
|||
// Skip HEAD pointer in remotes
|
||||
if (branch.contains(QStringLiteral(" -> "))) continue;
|
||||
// Strip "remotes/" prefix for display (show as origin/foo)
|
||||
if (branch.startsWith(QStringLiteral("remotes/")))
|
||||
bool isRemote = false;
|
||||
if (branch.startsWith(QStringLiteral("remotes/"))) {
|
||||
branch = branch.mid(8); // len("remotes/") == 8
|
||||
isRemote = true;
|
||||
}
|
||||
// Deduplicate: if local branch matches a remote, skip the remote
|
||||
if (!m_allBranches.contains(branch))
|
||||
if (!m_allBranches.contains(branch)) {
|
||||
m_allBranches.append(branch);
|
||||
if (isRemote)
|
||||
m_remoteBranches.append(branch);
|
||||
}
|
||||
}
|
||||
|
||||
// Update branch list widget
|
||||
m_branchList->clear();
|
||||
for (const auto &b : m_allBranches) {
|
||||
auto *item = new QListWidgetItem(b, m_branchList);
|
||||
// Mark remote branches (those that came from remotes/ prefix)
|
||||
item->setData(Qt::UserRole, m_remoteBranches.contains(b));
|
||||
if (b == current) {
|
||||
item->setText(QStringLiteral("* ") + b);
|
||||
QFont f = item->font();
|
||||
|
|
@ -1202,26 +1211,62 @@ void GitPlusPlusView::deleteBranch()
|
|||
return;
|
||||
}
|
||||
|
||||
if (QMessageBox::question(m_toolView, QStringLiteral("Delete Branch"),
|
||||
QStringLiteral("Delete branch '%1'?").arg(branch),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
||||
return;
|
||||
// Detect if this is a remote branch via the UserRole flag
|
||||
auto *item = m_branchList->currentItem();
|
||||
bool isRemote = item && item->data(Qt::UserRole).toBool();
|
||||
|
||||
// Use -D for force delete (handles unmerged branches)
|
||||
auto *proc = gitProcess({QStringLiteral("branch"), QStringLiteral("-D"), branch});
|
||||
if (!proc) return;
|
||||
connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
this, [this, proc, branch](int exitCode, QProcess::ExitStatus) {
|
||||
if (exitCode == 0) {
|
||||
setMessage(QStringLiteral("Deleted branch: ") + branch);
|
||||
} else {
|
||||
QString err = QString::fromUtf8(proc->readAllStandardError()).trimmed();
|
||||
setMessage(QStringLiteral("Delete failed: ") + err, true);
|
||||
if (isRemote) {
|
||||
// Remote branch: extract remote name and branch name (e.g. "origin/feature" -> "origin", "feature")
|
||||
int sep = branch.indexOf(QLatin1Char('/'));
|
||||
if (sep <= 0) {
|
||||
setMessage(QStringLiteral("Cannot determine remote for branch: ") + branch, true);
|
||||
return;
|
||||
}
|
||||
proc->deleteLater();
|
||||
refreshAll();
|
||||
});
|
||||
proc->start();
|
||||
QString remote = branch.left(sep);
|
||||
QString remoteBranch = branch.mid(sep + 1);
|
||||
|
||||
if (QMessageBox::question(m_toolView, QStringLiteral("Delete Remote Branch"),
|
||||
QStringLiteral("Delete remote branch '%1' from '%2'?\n\nThis will remove it from the remote server.").arg(remoteBranch, remote),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
auto *proc = gitProcess({QStringLiteral("push"), QStringLiteral("--delete"), remote, remoteBranch});
|
||||
if (!proc) return;
|
||||
connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
this, [this, proc, branch](int exitCode, QProcess::ExitStatus) {
|
||||
if (exitCode == 0) {
|
||||
setMessage(QStringLiteral("Deleted remote branch: ") + branch);
|
||||
} else {
|
||||
QString err = QString::fromUtf8(proc->readAllStandardError()).trimmed();
|
||||
setMessage(QStringLiteral("Delete failed: ") + err, true);
|
||||
}
|
||||
proc->deleteLater();
|
||||
refreshAll();
|
||||
});
|
||||
proc->start();
|
||||
} else {
|
||||
// Local branch
|
||||
if (QMessageBox::question(m_toolView, QStringLiteral("Delete Branch"),
|
||||
QStringLiteral("Delete local branch '%1'?").arg(branch),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
// Use -D for force delete (handles unmerged branches)
|
||||
auto *proc = gitProcess({QStringLiteral("branch"), QStringLiteral("-D"), branch});
|
||||
if (!proc) return;
|
||||
connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
this, [this, proc, branch](int exitCode, QProcess::ExitStatus) {
|
||||
if (exitCode == 0) {
|
||||
setMessage(QStringLiteral("Deleted branch: ") + branch);
|
||||
} else {
|
||||
QString err = QString::fromUtf8(proc->readAllStandardError()).trimmed();
|
||||
setMessage(QStringLiteral("Delete failed: ") + err, true);
|
||||
}
|
||||
proc->deleteLater();
|
||||
refreshAll();
|
||||
});
|
||||
proc->start();
|
||||
}
|
||||
}
|
||||
|
||||
void GitPlusPlusView::compareBranch()
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ private:
|
|||
QString m_gitDir;
|
||||
QString m_currentBranch;
|
||||
QStringList m_allBranches;
|
||||
QStringList m_remoteBranches;
|
||||
bool m_isDirty = false;
|
||||
QPointer<QProcess> m_remoteProc;
|
||||
int m_spinnerFrame = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue