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?

Jake A. Smith
la source

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}'
Neevek
la source
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.

jfeston
la source
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 :{}
Dmitriy
la source
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: {}

Naren
la source
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.

Kirby
la source
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
manquer de
la source
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
Ashish Sajwan
la source
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
andrewmart.in
la source
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.

utilisateur3416278
la source
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.

void.pointer
la source
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.

Ewin Hong
la source
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

Alex
la source
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 :{}
Atish Narlawar
la source
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.

Patrick Desjardins
la source
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

Tobias Ernst
la source
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.

Damodar Bashyal
la source
-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.

Dmytro Gorpynenko
la source
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