added gprune --deep parameter to allow deletion of forge merge
This commit is contained in:
@@ -497,11 +497,20 @@ export -f gwip
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Delete merged local branches (except protected branches)
|
||||
# Usage: gprune [main-branch]
|
||||
# Usage: gprune [-D|--deep] [main-branch]
|
||||
#
|
||||
# Default mode: deletes branches already merged into <main-branch> locally
|
||||
# (git branch --merged).
|
||||
# Deep mode (-D/--deep): additionally deletes branches whose tracking remote
|
||||
# has disappeared (remote pruned after a merge request / pull request merge).
|
||||
# Those branches are detected via `git fetch --prune` + remote-tracking gone.
|
||||
# This is the common case when the MR was merged upstream and the remote
|
||||
# branch was deleted by the forge. Deletion uses `git branch -D` (force)
|
||||
# because the local branch has no merged ancestor that git can verify locally.
|
||||
gprune()
|
||||
{
|
||||
local PARSED
|
||||
PARSED=$(getopt -o h --long help -n 'gprune' -- "$@")
|
||||
local PARSED deep=0
|
||||
PARSED=$(getopt -o hD --long help,deep -n 'gprune' -- "$@")
|
||||
# shellcheck disable=SC2181 # getopt return code is checked immediately after
|
||||
if [[ $? -ne 0 ]]; then
|
||||
disp E "Invalid options, use \"gprune --help\" to display usage."
|
||||
@@ -512,10 +521,20 @@ gprune()
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
printf "gprune: Delete local branches already merged into main branch.\n"
|
||||
printf "Usage: gprune [main-branch]\n"
|
||||
printf "gprune: Delete local branches already merged into main branch.\n\n"
|
||||
printf "Usage: gprune [-D|--deep] [main-branch]\n\n"
|
||||
printf "Options:\n"
|
||||
printf "\t-D, --deep\tAlso delete branches whose upstream was removed\n"
|
||||
printf "\t\t\t(remote deleted after MR/PR merge). Uses 'git branch -D'.\n"
|
||||
printf "\t-h, --help\tDisplay this help screen\n\n"
|
||||
printf "Arguments:\n"
|
||||
printf "\tmain-branch\tBase branch to check merges against (default: auto-detected)\n"
|
||||
return 0
|
||||
;;
|
||||
-D|--deep)
|
||||
deep=1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@@ -532,6 +551,7 @@ gprune()
|
||||
local base="${1:-$(_git_default_branch "$GIT_DEFAULT_REMOTE")}" current deleted=0
|
||||
current=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || return 1
|
||||
|
||||
# ── Standard mode: branches locally merged into base ──────────────────────
|
||||
disp I "Pruning branches merged into $base..."
|
||||
|
||||
while IFS= read -r b; do
|
||||
@@ -540,12 +560,35 @@ gprune()
|
||||
[[ $b == "$base" ]] && continue
|
||||
[[ $b == "master" || $b == "main" || $b == "develop" || $b == "dev" ]] && continue
|
||||
git branch -d "$b" >/dev/null 2>&1 && {
|
||||
printf "Deleted: %s\n" "$b"
|
||||
printf "Deleted (merged): %s\n" "$b"
|
||||
((deleted++))
|
||||
}
|
||||
done < <(git branch --merged "$base" | sed -E 's/^\*?\s*//')
|
||||
|
||||
(( deleted == 0 )) && disp I "No merged branches to delete."
|
||||
# ── Deep mode: branches whose remote tracking ref was deleted upstream ─────
|
||||
if (( deep )); then
|
||||
disp I "Deep mode: pruning remote-tracking refs, then checking for gone branches..."
|
||||
git fetch --prune --quiet
|
||||
|
||||
while IFS= read -r b; do
|
||||
[[ -z $b ]] && continue
|
||||
[[ $b == "$current" ]] && continue
|
||||
[[ $b == "$base" ]] && continue
|
||||
[[ $b == "master" || $b == "main" || $b == "develop" || $b == "dev" ]] && continue
|
||||
# Verify the upstream is truly gone (not just unset).
|
||||
local upstream
|
||||
upstream=$(git rev-parse --abbrev-ref "${b}@{upstream}" 2>/dev/null)
|
||||
[[ -z "$upstream" ]] && continue # no tracking branch at all — skip
|
||||
# If the remote ref still exists, skip (not deleted upstream).
|
||||
git show-ref --verify --quiet "refs/remotes/$upstream" 2>/dev/null && continue
|
||||
git branch -D "$b" >/dev/null 2>&1 && {
|
||||
printf "Deleted (gone upstream): %s\n" "$b"
|
||||
((deleted++))
|
||||
}
|
||||
done < <(git branch -vv | sed -E 's/^\*?\s*//' | awk '/: gone]/ {print $1}')
|
||||
fi
|
||||
|
||||
(( deleted == 0 )) && disp I "No branches to delete."
|
||||
}
|
||||
export -f gprune
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
@@ -70,7 +70,7 @@ help()
|
||||
printf "gacp\t\tAdd, commit and push changes (auto-pull if needed)\n"
|
||||
printf "genpwd\t\tGenerate one or more random secure passwords with configurable constraints\n"
|
||||
printf "ggraph\t\tDisplay decorated git history graph\n"
|
||||
printf "gprune\t\tDelete local branches already merged into main branch\n"
|
||||
printf "gprune\t\tDelete local branches already merged, or after remote deletion (MR / PR)\n"
|
||||
printf "greset\t\tReset branch to upstream (stash local, drop local commits)\n"
|
||||
printf "groot\t\tDisplay repository root path (or cd to it with -g)\n"
|
||||
printf "gsync\t\tFetch and rebase current branch onto upstream\n"
|
||||
|
||||
Reference in New Issue
Block a user