Voici mon flux de travail Git.
Je travaille à partir de deux ordinateurs différents (A et B) et stocke une télécommande git commune dans un répertoire dropbox.
Disons que j'ai deux branches master et devel. Tous deux suivent leurs homologues distants Origin/Master et Origin/Devel.
Maintenant, alors que je suis sur l'ordinateur A, je supprime le développement de branche - local et distant - comme suit:
git Push Origin :heads/devel
git branch -d devel
Maintenant, si je fais git branch -a
sur l'ordinateur A, je reçois
master
Origin/HEAD
Origin/master
Je vais maintenant à l'ordinateur B. Do git fetch
. Je peux supprimer la branche de développement locale en
git branch -d devel
Mais je ne peux pas supprimer la branche de développement distante.
git Push Origin :heads/devel
error: unable to Push to unqualified destination: heads/proxy3d
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
fatal: The remote end hung up unexpectedly
Faire git branch -a
liste toujours Origin/Devel dans les branches distantes.
Comment puis-je nettoyer l'entrée à distance de devel à partir de la machine B?
Tout d’abord, quel est le résultat de git branch -a
sur la machine B?
Deuxièmement, vous avez déjà supprimé heads/devel
sur Origin
, c'est pourquoi vous ne pouvez pas le supprimer de la machine B.
Essayer
git branch -r -d Origin/devel
ou
git remote Prune Origin
ou
git fetch Origin --Prune
et n'hésitez pas à ajouter --dry-run
à la fin de votre instruction git
pour voir le résultat de son exécution sans l'exécuter réellement.
Pensez à courir:
git fetch --Prune
Sur une base régulière dans chaque référentiel, pour supprimer les branches locales qui suivaient une branche distante supprimée (n'existe plus dans le référentiel GIT distant).
Ceci peut être encore simplifié en
git config remote.Origin.Prune true
il s'agit d'un paramètre per-repo
qui transformera tout futur git fetch or git pull
en un processus automatique Prune .
Pour configurer cela pour votre utilisateur, vous pouvez également éditer le .gitconfig global et ajouter
[fetch]
Prune = true
Cependant, il est recommandé de le faire en utilisant la commande suivante:
git config --global fetch.Prune true
ou de l'appliquer à l'échelle du système (pas seulement pour l'utilisateur)
git config --system fetch.Prune true
Voici le script bash qui peut le faire pour vous. C'est une version modifiée de http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git script. Ma modification lui permet de prendre en charge différents emplacements distants.
#!/bin/bash
current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching merged branches...\n"
git remote update --Prune
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
echo "No existing branches have been merged into $current_branch."
else
echo "This will remove the following branches:"
if [ -n "$remote_branches" ]; then
echo "$remote_branches"
fi
if [ -n "$local_branches" ]; then
echo "$local_branches"
fi
read -p "Continue? (y/n): " -n 1 choice
echo
if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
remotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u`
# Remove remote branches
for remote in $remotes
do
branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'`
git Push $remote $branches
done
# Remove local branches
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/Origin\///g' | tr -d '\n'`
else
echo "No branches removed."
fi
fi
Cette commande va "effacer" toutes les branches fusionnées distantes (Origin
), à l'exception de master
. Vous pouvez changer cela ou ajouter d'autres branches après le maître: grep -v for-example-your-branch-here |
git branch -r --merged |
grep Origin |
grep -v '>' |
grep -v master |
xargs -L1 |
awk '{sub(/Origin\//,"");print}'|
xargs git Push Origin --delete --dry-run
Si cela vous convient, supprimez le --dry-run
. De plus, vous voudrez peut-être d'abord tester ceci sur une fourche.
Si git branch -r
indique un grand nombre de branches de suivi à distance qui ne vous intéressent pas et que vous voulez supprimer uniquement du local, utilisez la commande suivante:
git branch -r | grep -Ev 'HEAD|master|develop' | xargs -r git branch -rd
Une version plus sûre consisterait à ne supprimer que les versions fusionnées:
git branch -r --merged | grep -Ev 'HEAD|master|develop' | xargs -r git branch -rd
Cela peut être utile pour les grands projets, où vous n'avez pas besoin des branches de fonctionnalités des autres coéquipiers, mais de nombreuses branches de suivi à distance récupérées sur le clone initial.
Et cette étape seule est incomplète, car ces branches supprimées de suivi à distance réapparaîtront lors du prochain git fetch
.
Pour arrêter l'extraction de ces branches de suivi à distance, vous devez spécifier explicitement les références à extraire dans .git/config :
[remote "Origin"]
# fetch = +refs/heads/*:refs/remotes/Origin/*
fetch = +refs/heads/master:refs/remotes/Origin/master
fetch = +refs/heads/develop:refs/remotes/Origin/develop
fetch = +refs/heads/release/*:refs/remotes/Origin/release/*
Dans l'exemple ci-dessus, nous n'extrayons que master
, develop
et libérons des branches, n'hésitez pas et ajoutez les vôtres.
La suppression est toujours une tâche difficile et peut être dangereuse !!! Par conséquent, exécutez d'abord la commande suivante pour voir ce qui va se passer:
git Push --all --Prune --dry-run
En procédant comme ci-dessus, git
vous fournira une liste de ce qui se passerait si la commande ci-dessous était exécutée.
Exécutez ensuite la commande suivante pour supprimer toutes les branches du référentiel distant qui ne figurent pas dans votre référentiel local:
git Push --all --Prune
Je vais devoir ajouter une réponse ici, car les autres réponses ne couvrent pas mon cas ou sont inutilement compliquées ... J'utilise github avec d'autres développeurs et je veux juste toutes les branches locales dont les télécommandes ont été (éventuellement fusionnées et) supprimé d'un github PR à supprimer en une fois de ma machine. Non, des éléments tels que git branch -r --merged
ne couvrent pas les branches qui n'ont pas été fusionnées localement, ou celles qui ne l'ont pas été du tout (abandonnées), etc., une solution différente est donc nécessaire.
Quoi qu'il en soit, la première étape, je l'ai obtenu d'autres réponses:
git fetch --Prune
Une version d'essai de git remote Prune Origin
semblait vouloir faire la même chose dans mon cas, alors j'ai choisi la version la plus courte pour que ce soit simple.
Maintenant, un git branch -v
devrait marquer les branches dont les télécommandes sont supprimées comme étant [gone]
. Par conséquent, tout ce que je dois faire est:
git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}
Aussi simple que cela, il supprime tout ce que je veux pour le scénario ci-dessus.
La syntaxe xargs
moins commune est telle qu'elle fonctionne également sur Mac & BSD en plus de Linux . Attention, cette commande n'est pas un essai à blanc et va donc forcer la suppression de toutes les branches marquées avec [gone]
. Évidemment, étant donné que rien n’est parti pour toujours, si vous voyez des branches supprimées dont vous vous rappelez que vous souhaitez conserver, vous pouvez toujours les restaurer (la commande ci-dessus aura répertorié leur hachage lors de la suppression, donc un simple git checkout -b <branch> <hash>
.