web-dev-qa-db-fra.com

nettoyer les vieilles branches distantes

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?

564
Jayesh

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. 

1069
Jakub Narębski

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
67
Arif

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
14
Alex Amiryan

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.

7
weston

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.

3
ryenus

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
3

Voici comment faire avec SourceTree (v2.3.1):
1. Cliquez sur chercher
2. Cochez "Prune branches de suivi ..."
3. Appuyez sur OK
4. ???? 

 enter image description here

2
coco

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>.

1
Ecuador