objectif
Éviter l’accumulation de branches locales obsolètes: détecter celles déjà mergées dans la branche de base, les supprimer en sécurité (dry-run puis exécution), et nettoyer les références distantes périmées pour vos dépôts.
code minimal
# dry-run: lister les branches locales mergées dans la branche de base
git fetch --prune
BASE="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@' || echo main)"
git branch --merged "origin/$BASE" \
| egrep -v "^\*|^${BASE}\$|^main$|^master$|^develop$"
# suppression (après vérification)
git branch --merged "origin/$BASE" \
| egrep -v "^\*|^${BASE}\$|^main$|^master$|^develop$" \
| xargs -r -n1 git branch -d
utilisation
# 1) dépôt data.pm: liste puis suppression
cd ~/code/data.pm
git fetch --prune
BASE="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@' || echo main)"
git branch --merged "origin/$BASE" \
| egrep -v "^\*|^${BASE}\$|^main$|^master$|^develop$"
git branch --merged "origin/$BASE" \
| egrep -v "^\*|^${BASE}\$|^main$|^master$|^develop$" \
| xargs -r -n1 git branch -d
# 2) dépôt api.data.pm: purger les suivis distants obsolètes
cd ~/code/api.data.pm
git fetch --prune
git branch -vv | awk '/: gone]/{print $1}' | xargs -r -n1 git branch -D
# 3) sécurité avant suppression manuelle d'une branche non listée comme mergée
BASE="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@' || echo main)"
curr="$(git rev-parse --abbrev-ref HEAD)"
git log --oneline --graph --decorate --boundary "origin/$BASE..$curr"
variante(s) utile(s)
# A) supprimer aussi des branches distantes mergées (avec droits)
git fetch --prune
git branch -r --merged "origin/$BASE" \
| sed 's@^\s*origin/@@' \
| egrep -v "^${BASE}$|^main$|^master$|^develop$" \
| xargs -r -n1 -I{} git push origin --delete {}
# B) nettoyage rapide multi-dépôts
for repo in ~/code/data.pm ~/code/api.data.pm; do
( cd "$repo"
git fetch --prune
BASE="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@' || echo main)"
git branch --merged "origin/$BASE" \
| egrep -v "^\*|^${BASE}\$|^main$|^master$|^develop$" \
| xargs -r -n1 git branch -d
)
done
# C) script utilitaire (~/bin/git-clean-merged)
cat > ~/bin/git-clean-merged <<'SH'
#!/usr/bin/env bash
set -Eeuo pipefail
git fetch --prune
BASE="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@' || echo main)"
list="$(git branch --merged "origin/$BASE" | egrep -v "^\*|^${BASE}\$|^main$|^master$|^develop$" || true)"
[ -z "$list" ] && exit 0
echo "$list" | xargs -r -n1 git branch -d
SH
chmod +x ~/bin/git-clean-merged
# D) localiser les branches en avance (à NE PAS supprimer)
BASE="${BASE:-main}"
for b in $(git for-each-ref --format='%(refname:short)' refs/heads/); do
ahead=$(git rev-list --left-right --count "origin/$BASE...$b" 2>/dev/null | awk '{print $2}')
[ "${ahead:-0}" -gt 0 ] && printf "%s ahead=%s\n" "$b" "$ahead"
done
notes
- Travaillez à jour (
git fetch --prune) et basez-vous surorigin/HEADpour détecter automatiquementmainoumaster. - Protégez les branches pivots (
main,master,develop) et la branche de base détectée. git branch -déchoue si la branche n’est pas mergée; utilisez-Duniquement en connaissance de cause.- Pour la suppression distante, validez la politique d’équipe avant d’exécuter le push
--delete.