Supprimer plusieurs branches distantes dans git


129

J'ai un membre de l'équipe qui a par inadvertance transféré plus de 150 de ses succursales locales à notre repo central. Heureusement, ils ont tous le même préfixe. En utilisant ce préfixe, y a-t-il une commande git ou un petit script shell sympa que je peux utiliser qui supprimera tout cela à la fois?

Réponses:


151

Utilisez la commande suivante pour supprimer toutes les branches avec le PREFIXpréfixe sur le serveur distant.

git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}

Vous voudrez peut-être effectuer d'abord une analyse à sec pour voir si ce sont les branches que vous souhaitez supprimer:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'

2
J'aime ça parce que c'est une seule ligne et que je peux d'abord faire une course à sec. Malheureusement, il se trompe avec ce message: $ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH 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. error: failed to push some refs to 'GIT_URL'
Jake A. Smith

Avec git branch -r | awk -F/ '/\/APR/{print $2}', pourriez-vous voir tous les noms de succursales avec préfixe APR répertoriés?
neevek

1
OK, c'est parce que la APR-04-DPHbranche a déjà été supprimée. Jetez un œil à ces questions répondues: ceci et cela et aussi ceci . Les réponses à ces questions portent sur le même problème, vous voudrez peut-être tester les solutions vous-même.
neevek

26
si vous avez / dans vos noms de branche (si vous utilisez git-flow ou quelque chose), alors imprimez {$ 2 "/" $ 3} à la place
ajma

4
J'utilise msysgit dans Windows et la commande suivante a fonctionné pour moi (en conjonction avec le commentaire de @ ajma pour les noms de branche contenant des barres obliques:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe

96

Si vous aimez une approche plus simple, supprimez par exemple 3 ou 4 branches:

git push origin --delete <branch1> <branch2> <branch3>

Important: fonctionne uniquement sur Git v1.7.0 et supérieur.


6
J'ai fini par utilisergit branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Aram Kocharyan

36

Merci à Neevek pour une solution géniale et élégante!

Mais j'ai quelques problèmes avec les barres obliques dans les noms de branche (j'utilise Git Flow), à cause du awkséparateur de champ /( -Foption)

Ma solution est donc basée sur celle de Neevek , mais analyse correctement les noms de branche avec /. Dans ce cas, je suppose que votre télécommande a appelé origin. Commande de suppression des branches distantes dont les noms commencent par PATTERN:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}

Et n'oubliez pas de vérifier ce que vous allez supprimer:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'

CONSEIL UTILE: Si vos noms de branche (sans origin/préfixe) sont stockés dans un fichier texte (un nom de branche par ligne), lancez simplement:

cat your_file.txt | xargs -I {} git push origin :{}

2
Utilisez à la xargs -a file -Lplace de cat file | xargs. Encore plus simple xargs -a file git push --delete origin.
musiKk

15

Cela peut être une réponse en double mais ci-dessous testé et a parfaitement fonctionné pour moi.

  1. Supprimer la branche locale de force

git branch -D nom-de-branche

  1. Supprimer la branche distante

git push origin --delete nom-branche

  1. Supprimer plus d'une succursale locale

git branch -D nom-branche1 nom-branche2

  1. Supprimer plus d'une branche distante

git push origin --delete nom-branche1 nom-branche2

  1. Supprimer la branche locale avec le préfixe. Par exemple, fonctionnalité / *

git branch -D $ (git branch --list 'fonctionnalité / *')

git branch -D backticks $ (git branch - list 'feature / *' backticks )

  1. Répertoriez la branche distante avec le préfixe.

git branche -r | grep -Eo 'fonction /.*'

  1. Supprimer la branche distante avec le préfixe

git branche -r | grep -Eo 'fonction /.*' | xargs -I {} origine git push: {}


2
Je pense que vous vouliez échapper aux backticks à l'étape 5
GPL

Comment ajouter des backticks?
Naren

1
@Naren: le problème est que le formatage de démarque transforme vos backticks en une commande de style. Je les ai remplacés par une méthode de substitution de commande différente (par exemple, «$ (commande)» équivaut à «commande» mais ne se traduit pas par markdown en quelque chose de bizarre.) L'autre chose que vous pouvez faire est d'échapper aux contre-indications avec «\»
Stabledog

13

La même chose avec grep: git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -rspectacles origin/prefix/branchname. Il faudra donc prefix/branchname.


Je pense que tu voulais xargs -I {} git push origin :{}dire non -i.
jojo

1
@jojo, AFAIK, car -iil utilise le remplacement par défaut pour {}mais avec -Ivous pouvez déclarer le vôtre. ... juste trouvé dans le manuel:-i ... the same as -I{}
Kirby

10

La solution de Neevek est élégante, mais elle peut être meilleure: la solution proposée appelle «git push» une fois par branche, ce qui signifie un aller-retour réseau supplémentaire par branche à supprimer. Puisque vous utilisez de toute façon awk, pourquoi ne pas l'utiliser pour préfixer le ':' et ensuite xargs peut appeler 'git push' exactement une fois et supprimer toutes les branches à la fois:

Exécuter à sec pour lister les branches qui seraient supprimées:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'

Solution finale pour réellement pousser les suppressions:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin

2
Cela fonctionne parfaitement dans le cas où vous ne pouvez pas utiliser l'option "-I" pour xargs lorsque vous avez une version inférieure bash ou que vous utilisez une version Windows git bash.
zchholmes

J'avais une xargs: replstr may not be emptysolution avec Neevek, peut-être la version git .. git version 1.9.5Mais cela a très bien fonctionné pour moi. Merci à vous deux
IamFace

8

ressource https://coderwall.com/p/eis0ba

    1 - List all your remote branches:

    $ git branch -r

    2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:

    $ git branch -r | awk -F/ '/\/feature-/{print $2}'
    3 - Pipe the last command to git push to delete them:
    # **Edit** - Removed extra colon, which is not needed
    $ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
    4 - Grab a beer.

    5 - Remove any local reference to those branches:

    $ git remote prune origin

Merci, cela a fonctionné pour moi. Dans ce cas, je pourrais supprimer plusieurs branches locales. Merci!
Prashant Kabade

5

Grâce à Steve et Neevek, j'ai trouvé une solution qui fonctionnait plutôt bien pour moi et qui valait la peine d'être partagée:

La solution de Steve a fonctionné pour moi avec un ajustement mineur. Mes télécommandes ont été nommées origin/feature/some-feature-namealors j'ai coupé votre awk:

git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}

Il fait maintenant un joli petit flux de suppression:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
To github.com:project/project-name.git
- [deleted]         feature/search-placeholder
To github.com:project/project-name.git
- [deleted]         feature/server-error-message
To github.com:project/project-name.git
- [deleted]         feature/six-point-asterisk

Je me demandais si quelqu'un avait des idées pour une solution plus élégante, cependant, qui pourrait produire quelque chose comme ceci (mon script CLI est assez pauvre, donc il me faudrait un certain temps pour comprendre cela):

git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk

Cela entraînerait une belle sortie unique avec une requête réseau:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
- [deleted]         feature/search-placeholder
- [deleted]         feature/server-error-message
- [deleted]         feature/six-point-asterisk

4

Merci à Neevek. Cela a bien fonctionné après l'avoir reconfiguré pour mon objectif:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}

J'avais également besoin de prendre en compte la structure des dossiers. Mes branches de fonctionnalités sont dans une structure de dossiers comme origin / feature / PREFIX-FEATURENUMBER. J'ai donc dû créer mon modèle à partir de $ 2 = dossier + $ 3 = branchname.


4

Tout le monde utilise awk, je ne sais pas pourquoi. J'ai l'impression que c'est plus complexe. Voici ce que j'utilise pour supprimer toutes les branches distantes de ma forktélécommande:

$ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork

Lancez un grepentre le xargset sedsi vous avez besoin de filtrer la liste vers un sous-ensemble de branches distantes uniquement.


1
Merci beaucoup. Celui-ci a fonctionné pour moi parmi toutes les solutions .. grep retournait la branche complète avec le nom distant ainsi que origin/blaprefix_anotherbla. Mais en utilisant bien sedgéré. Un autre avantage de cette approche est que j'utilise bitbucket et que je n'ai pas besoin de saisir manuellement le mot de passe d'authentification pour chaque suppression de branche. Celui-ci supprime toutes les branches en un seul lot.
Madhur Bhaiya

Pour supprimer toutes les branches de greenkeepergit branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
abhisekp

4

Je me rends compte que c'est pour la commande git, mais si vous cherchez une solution alternative pour faire le même ou le même résultat:

Vous pouvez le faire à partir d'ici (Git Remove Remote Branches):

Sélectionnez ensuite les branches souhaitées:

Assurez-vous que vous disposez des autorisations nécessaires pour supprimer les branches distantes.


Cela devrait être une bonne réponse, elle est indépendante de la plate-forme.
karmington

Quel est le logiciel et est-il disponible pour Linux?
abhisekp

1

Github a également une belle interface utilisateur et un mécanisme pour supprimer rapidement les branches, c'est si vous préférez utiliser une interface utilisateur


1
Oui, c'est documenté ici , mais vous devez toujours cliquer une fois pour chaque branche individuelle. La solution la plus votée ici est la meilleure façon de créer de nombreuses branches auxquelles vous pouvez écrire une expression régulière.
thewoolleyman

0

J'ai essayé de supprimer toutes les branches distantes d'origine / release / r1-1 *, donc la ligne de commande suivante fonctionnait bien.

git branch -r | awk -Forigin/ '/\/*r1-1/ {print $2}' |  xargs -I {} git push origin :{}

0

Je n'ai pas pu utiliser awk car nous utilisons une structure slash pour le nom de nos branches.

git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

Cela récupère toutes les branches distantes, n'obtient que celle pour un seul utilisateur, distante la chaîne "origin /" et exécute une suppression sur chacune d'elles.


0

Course à sec:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}

Supprimer les branches distantes:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Supprimer uniquement les branches distantes entièrement fusionnées:

git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Explication:

sed "s/origin\///"supprimera origin/du nom de la branche. Sans enlever ça, j'ai:remote ref does not exist


0

Les réponses précédentes m'ont aidé à supprimer toutes les branches de version de 2018. J'ai exécuté cela sur mon invite de commande Windows 10. J'ai installé clink , donc les commandes de type Linux fonctionnent pour moi.

Exécution à sec:

git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}

Si la marche à sec montre des branches qui ne sont pas à distance / d'origine. Exécutez ci-dessous la commande git prune pour corriger et vérifier à nouveau.

git remote prune origin

Supprimez une fois que vous êtes satisfait du résultat ci-dessus:

git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}

Si vous voyez: error: unable to delete 'release-...2018': remote ref does not exist. Exécutez ensuite la commande d'élagage précédente et réessayez.


-4

Attention: cela supprimera toutes les branches distantes. Utiliser avec précaution.

Je pense que ma façon de supprimer les branches distantes est la meilleure.

git branch -r | grep -v master | sed 's/origin\//:/'| xargs git push

Attention: cela supprimera toutes les branches distantes. Utiliser avec précaution.


4
Évalué à la baisse comme un troll évident. Supprimerait si j'avais les droits.
Jake A. Smith

où avez-vous trouvé la pêche à la traîne?
Dmytro Gorpynenko

2
ce n'est pas correct, il vous manque des arguments vitaux pour xargs et cela ne répond pas à la question.
Rob

@ JakeA.Smith Jake, je suppose que vous pensiez que ce code supprimera le maître distant - ce qui n'est pas le cas car grep -v master trouve tout sauf master.
Vadim Samokhin

@Rob qu'est-ce qui ne va pas ici? L'instruction finale exécutée sera smth comme git push: some_branch: another_branch, ce qui est absolument correct.
Vadim Samokhin
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.