Question nettoyer les vieilles branches git distantes


Voici mon workflow git.

Je travaille à partir de deux ordinateurs différents (A et B) et stocke un répertoire commun de git distant dans dropbox.

Disons que j'ai deux branches master et devel. Les deux suivent leurs homologues distants origin / master et origin / devel.

Maintenant, sur l'ordinateur A, je supprime le développement de la branche - à la fois local et distant - comme suit:

git push origin :heads/devel

git branch -d devel

Maintenant si je le fais git branch -a sur l'ordinateur A, je reçois

master
origin/HEAD
origin/master

Je vais maintenant à l'ordinateur B. git fetch. Je peux supprimer la branche locale devel par

git branch -d devel

Mais je ne peux pas enlever la branche devel 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 l'origine / devel dans les branches distantes.

Comment puis-je nettoyer l'entrée à distance de devel de la machine B?


506


origine


Réponses:


Premièrement, 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 git instruction pour voir le résultat de l'exécuter sans l'exécuter réellement.


942



Envisagez de courir:

git fetch --prune

Sur une base régulière dans chaque repo pour supprimer les branches locales qui ont suivi une branche distante qui est supprimée (n'existe plus dans repo GIT à distance).

Cela peut être encore simplifié par

git config remote.origin.prune true

c'est un per-repo réglage qui fera tout avenir git fetch or git pull pour automatiquement prune.

Pour configurer cela pour votre utilisateur, vous pouvez également modifier le fichier .gitconfig global et ajouter

[fetch]
    prune = true

Cependant, il est recommandé d'utiliser la commande suivante:

git config --global fetch.prune true

ou pour l'appliquer à l'échelle du système (pas seulement pour l'utilisateur)

git config --system fetch.prune true

45



Voici un script bash qui peut le faire pour vous. C'est la version modifiée de http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git scénario. 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

13



Cette commande va "exécuter à sec" supprimer toutes les télécommandes (origin) les succursales fusionnées, à master. Vous pouvez changer cela, ou ajouter des branches supplémentaires après master: 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 semble bon, retirez le --dry-run. En outre, vous pouvez tester cela sur une fourchette en premier.


6



Voici comment faire avec SourceTree (v2.3.1):
 1. Cliquez sur Récupérer
 2. Cochez "Pruner les branches de suivi ..."
 3. Appuyez sur OK
 4.

enter image description here


3



La suppression est toujours une tâche difficile et peut être dangereuse!!! Par conséquent, commencez par exécuter la commande suivante pour voir ce qui va se passer:

git push --all --prune --dry-run

En faisant comme ci-dessus, git vous fournira une liste de ce qui se passerait si la commande ci-dessous est exécutée.

Ensuite, exécutez la commande suivante pour supprimer toutes les branches du repo distant qui ne sont pas dans votre repo local:

git push --all --prune

3



Si git branch -r affiche un grand nombre de branches de suivi à distance qui ne vous intéressent pas et que vous souhaitez supprimer uniquement de locales, utilisez la commande suivante:

git branch -r | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

Une version plus sûre serait de ne supprimer que les fusionnées:

git branch -r --merged | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

Cela peut être utile pour les projets de grande envergure, où vous n'avez pas besoin des branches techniques des autres membres de l'équipe, mais de nombreuses branches de suivi à distance récupérées sur le clone initial.

Et cette étape à elle seule est incomplète car ces branches de suivi à distance supprimées apparaîtraient à nouveau git fetch.

Pour arrêter l'extraction de ces branches de suivi à distance, vous devez spécifier explicitement les références à récupérer 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 ne récupérons que master, develop et libérez des branches, n'hésitez pas et ajoutez les vôtres.


2