Comment puis-je supprimer toutes les branches Git qui ont été fusionnées?

j'ai beaucoup de branches Git. Comment supprimer des branches qui ont déjà été fusionnées? Est-il un moyen facile de supprimer tous au lieu de les supprimer un par un?

1374
demandé sur Peter Mortensen 2011-05-25 19:54:36

30 réponses

mise à jour:

vous pouvez ajouter d'autres branches pour exclure comme maître et dev si votre flux de travail a ceux comme un ancêtre possible. En général, je me sépare d'une étiquette "sprint-start" et master, dev et qa ne sont pas des ancêtres.

pour supprimer toutes les succursales locales qui sont déjà fusionnées dans la succursale actuellement cochée:

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

vous pouvez voir que maître et dev sont exclus dans le cas où ils sont un ancêtre.


vous pouvez supprimer une branche locale fusionnée avec:

git branch -d branchname

si elle n'est pas fusionnée, utiliser:

git branch -D branchname

pour le supprimer de la télécommande dans les anciennes versions de Git use:

git push origin :branchname

Dans les versions plus récentes de Git:

git push --delete origin branchname

une fois que vous supprimez la branche de la télécommande, vous pouvez prendre pour se débarrasser des branches de suivi à distance avec:

git remote prune origin

ou prune individuelle de suivi à distance des branches, comme l'autre réponse suggère, avec:

git branch -dr branchname

Espérons que cette aide.

2324
répondu Adam Dymitruk 2016-08-18 07:43:59

pour supprimer toutes les branches sur la télécommande qui sont déjà fusionnées:

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

dans les versions plus récentes de Git

git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin
332
répondu kuboon 2013-08-09 08:45:25

Juste s'étendant Adam répondre un peu:

ajoutez ceci à votre configuration Git en exécutant git config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\*\|master\|develop' | xargs -n 1 git branch -d"

et ensuite vous pouvez supprimer toutes les branches locales fusionnées en faisant un simple git cleanup .

138
répondu real_ate 2018-03-29 08:08:52

cela fonctionne aussi pour supprimer toutes les branches fusionnées sauf master.

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d
73
répondu Ismael Abreu 2016-05-18 20:21:05

vous voudrez exclure les branches master et develop de ces commandes.

git Local clair:

git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d

Distant git clair:

git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin

Sync registre local des branches distantes:

git fetch -p
58
répondu Guido Bouman 2015-12-20 04:48:06

pour ceux d'entre vous qui sont sur Windows et préfèrent les scripts PowerShell, en voici un qui supprime les branches locales fusionnées:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object {$_ -NotMatch "^\*"} |
    Where-Object {-not ( $_ -Like "*master" )} |
    ForEach-Object { git branch -d $_ }
}
33
répondu Klas Mellbourn 2015-09-07 17:41:24

Git Sweep fait un excellent travail de ceci.

19
répondu paul 2017-08-31 23:54:51

vous pouvez ajouter le commit à l'option --merged. De cette façon, vous pouvez vous assurer seulement pour enlever les branches qui sont fusionnées dans i.e. l'origine/maître

la commande suivante supprimera les branches fusionnées de votre origine.

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

vous pouvez tester quelles branches seront enlevées en remplaçant l'origine git push --supprimer par echo

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
13
répondu Jörn Reimerdes 2014-07-08 08:42:42

utilisant la version 2.5.0 de Git:

git branch -d `git branch --merged`
12
répondu drautb 2017-08-31 23:59:22

j'utilise le script Ruby suivant pour supprimer mes branches locales et distantes déjà fusionnées. Si je le fais pour un dépôt avec plusieurs télécommandes et que je ne veux supprimer qu'une seule, je n'ai qu'à ajouter une instruction select à la liste des télécommandes pour obtenir seulement les télécommandes que je veux.

#!/usr/bin/env ruby

current_branch = `git symbolic-ref --short HEAD`.chomp
if current_branch != "master"
  if $?.exitstatus == 0
    puts "WARNING: You are on branch #{current_branch}, NOT master."
  else
    puts "WARNING: You are not on a branch"
  end
  puts
end

puts "Fetching merged branches..."
remote_branches= `git branch -r --merged`.
  split("\n").
  map(&:strip).
  reject {|b| b =~ /\/(#{current_branch}|master)/}

local_branches= `git branch --merged`.
  gsub(/^\* /, '').
  split("\n").
  map(&:strip).
  reject {|b| b =~ /(#{current_branch}|master)/}

if remote_branches.empty? && local_branches.empty?
  puts "No existing branches have been merged into #{current_branch}."
else
  puts "This will remove the following branches:"
  puts remote_branches.join("\n")
  puts local_branches.join("\n")
  puts "Proceed?"
  if gets =~ /^y/i
    remote_branches.each do |b|
      remote, branch = b.split(/\//)
      `git push #{remote} :#{branch}`
    end

    # Remove local branches
    `git branch -d #{local_branches.join(' ')}`
  else
    puts "No branches removed."
  end
end
11
répondu mmrobins 2017-08-31 23:53:58

kuboon la réponse de manquer de supprimer les branches qui ont le mot de maître dans le nom de la branche. Ce qui suit améliore sa réponse:

git branch -r --merged | grep -v "origin/master$" | sed 's/\s*origin\///' | xargs -n 1 git push --delete origin

bien sûr, il ne supprime pas la branche" master "elle-même:)

8
répondu Paras 2013-10-04 06:05:34

comment supprimer les branches fusionnées dans la console PowerShell

git branch --merged | %{git branch -d $_.Trim()}

voir GitHub for Windows

8
répondu Konstantin Tarkus 2015-01-27 14:31:36

il n'y a aucune commande dans Git qui fera cela pour vous automatiquement. Mais vous pouvez écrire un script qui utilise des commandes Git pour vous donner ce dont vous avez besoin. Cela peut être fait de plusieurs façons selon ce ramification modèle que vous utilisez.

si vous avez besoin de savoir si une branche a été fusionnée dans master la commande suivante ne donnera aucun résultat si myTopicBranch a été fusionné (i.e. vous pouvez le supprimer)

$ git rev-list master | grep $(git rev-parse myTopicBranch)

vous pouvez utiliser le Git commandement de la branche et analyse Toutes les branches à Bash et faire une boucle for sur toutes les branches. Dans cette boucle, vous vérifiez avec la commande ci-dessus, si vous pouvez supprimer la branche ou pas.

7
répondu ralphtheninja 2017-08-31 23:51:24

git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d supprimera toutes les branches locales sauf la branche courante cochée et/ou master .

Voici un article utile pour ceux qui cherchent à comprendre ces commandes: Git Clean: Supprime Déjà Fusionné les Branches, par Steven Harman .

6
répondu styger 2014-10-23 21:06:52

J'utilise la réponse D'Adam depuis des années. Cela dit, il y a des cas où elle ne se comportait pas comme je l'espérais:

  1. branches que contenait le mot "master" a été ignoré, par exemple "notmaster" ou "masterful", plutôt que seulement la branche master
  2. branches que contenait le mot "dev" a été ignoré, par exemple "dev-test", plutôt que seulement la branche dev
  3. supprimer les branches qui sont accessibles à partir de la tête de la branche courante (c'est-à-dire, pas nécessairement maître)
  4. dans l'état de tête détaché, en supprimant chaque branche accessible à partir de la commit actuelle

1 & 2 étaient simples à traiter, avec juste un changement à la regex. 3 dépend du contexte de ce que vous voulez (c.-à-d. supprimer seulement les branches qui n'ont pas été fusionnées dans maître ou contre votre branche actuelle). 4 a le potentiel d'être désastreux (bien que récupérable avec git reflog ), si vous avez involontairement couru ce dans l'état de tête détaché.

enfin, je voulais que tout cela soit dans un seul liner qui ne nécessite pas de script séparé (Bash|Ruby|Python).

TL; DR

créer un git alias "sweep" qui accepte un drapeau optionnel -f :

git config --global alias.sweep '!f(){ git branch --merged $([[  != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d; }; f'

et invoquez-le avec:

git sweep

ou:

git sweep -f

la réponse longue et détaillée

il était plus facile pour moi de créer un exemple git repo avec quelques branches et commits pour tester le comportement correct:

Créer un nouveau repo git avec un seul commit

mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"

Créer de nouvelles branches

git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
  bar
  develop
  foo
* master
  masterful
  notmaster

comportement souhaité: sélectionner toutes les branches fusionnées sauf: master, develop ou current

le regex original manque les branches "masterful" et "notmaster":

git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
  bar

avec le regex mis à jour (qui exclut maintenant "développer" plutôt que" dev"):

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster

passer à la branche foo, faire un nouveau commit, puis commander une nouvelle branche, foobar, basé sur foo:

echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"

ma branche actuelle est foobar, et si je relance la commande ci-dessus pour lister les branches que je veux supprimer, la branche "foo" est incluse même si elle n'a pas été fusionnée dans master:

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  masterful
  notmaster

cependant, si je exécute la même commande sur le capitaine, la branche "foo" n'est pas incluse:

git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

et c'est simplement parce que git branch --merged est par défaut à la tête de la branche courante, sauf indication contraire. Au moins pour mon workflow, Je ne veux pas supprimer les branches locales à moins qu'elles n'aient été fusionnées à master, donc je préfère la variante suivante:

git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

, Séparé de la TÊTE de l'état

S'appuyant sur le comportement par défaut de git branch --merged

git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  foobar
  masterful
  notmaster

Cela aurait supprimé la branche, j'étais juste sur, "foobar" avec "toto", qui est presque certainement pas le résultat souhaité. Avec notre commande révisée, cependant:

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

une ligne, y compris la ligne supprimer

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d

tous enveloppé dans un alias git "sweep":

git config --global alias.sweep '!f(){ git branch --merged $([[  != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d; }; f'

l'alias accepte un drapeau optionnel -f . Le comportement par défaut est de supprimer uniquement les branches qui ont été fusionnées dans master, mais le drapeau -f supprimera les branches qui ont été fusionnées dans la branche courante.

git sweep
Deleted branch bar (was 9a56952).
Deleted branch masterful (was 9a56952).
Deleted branch notmaster (was 9a56952).
git sweep -f
Deleted branch foo (was 2cea1ab).
6
répondu eddies 2018-08-08 16:22:54

vous pouvez utiliser git-del-br outil .

git-del-br -a

vous pouvez l'installer via pip en utilisant

pip install git-del-br

P. S: je suis l'auteur de l'outil. Toute suggestion ou rétroaction est la bienvenue.

5
répondu tusharmakkar08 2016-07-19 18:50:15

Alias version de Adam de la mise à jour de réponse :

[alias]
    branch-cleanup = "!git branch --merged | egrep -v \"(^\*|master|dev)\" | xargs git branch -d #"

voir Aussi cette réponse pour des conseils pratiques sur la fuite des complexes alias.

5
répondu Eliot 2017-05-23 12:10:47

si vous souhaitez supprimer toutes les branches locales qui sont déjà fusionnées dans la branche sur laquelle vous êtes actuellement, alors j'ai trouvé une commande sûre pour le faire, basée sur les réponses précédentes:

git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d

cette commande n'affectera pas votre branche courante ni votre branche principale. Il vous dira aussi ce qu'il fait avant qu'il le fasse, en utilisant le drapeau-t de xargs.

4
répondu chrismendis 2014-01-23 16:24:57

essayez la commande suivante:

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

en utilisant git rev-parse obtiendra le nom actuel de la branche afin de l'exclure. Si vous avez l'erreur, ce qui signifie qu'il n'y a pas de branches à supprimer.

pour faire la même chose avec les branches distantes (changer origin avec votre nom distant), essayez:

git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)

dans le cas où vous avez plusieurs télécommandes, ajouter grep origin | avant cut pour filtrer seulement le origin .

si la commande ci-dessus échoue, essayez de supprimer les branches fusionnées de suivi à distance en premier:

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

puis git fetch la télécommande à nouveau et utilisez la commande précédente git push -vd à nouveau.

si vous l'utilisez souvent, envisagez d'ajouter des alias dans votre fichier ~/.gitconfig .

si vous avez enlevé des branches par erreur, utilisez git reflog pour trouver les propagations Perdues.

4
répondu kenorb 2017-05-23 11:55:03

basé sur certaines de ces réponses j'ai fait mon propre script Bash pour le faire aussi !

il utilise git branch --merged et git branch -d pour supprimer les branches qui ont été fusionnées et vous invite pour chacune des branches avant de supprimer.

merged_branches(){
  local current_branch=$(git rev-parse --abbrev-ref HEAD)
  for branch in $(git branch --merged | cut -c3-)
    do
      echo "Branch $branch is already merged into $current_branch."
      echo "Would you like to delete it? [Y]es/[N]o "
      read REPLY
      if [[ $REPLY =~ ^[Yy] ]]; then
        git branch -d $branch
      fi
  done
}
4
répondu earlonrails 2017-08-31 23:56:15

j'utilise un système de nommage git-flow esque, donc cela fonctionne très sûrement pour moi:

git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d

il cherche essentiellement des commits fusionnés qui commencent par la chaîne de caractères fix/ ou feature/ .

4
répondu Chad M 2017-09-01 00:01:20

ci-dessous la requête fonctionne pour moi

for branch in  `git branch -r --merged | grep -v '\*\|master\|develop'|awk 'NR > 0 {print}'|awk '{gsub(/origin\//, "")}1'`;do git push origin --delete $branch; done

et ceci filtrera n'importe quelle branche donnée dans le tuyau grep.

fonctionne bien sur le clone http, mais pas aussi bien pour la connexion ssh.

4
répondu user1460965 2018-01-19 10:50:35

Écrire un script dans lequel Git vérifie toutes les branches qui ont été fusionnées à maîtriser.

puis git checkout master .

enfin, supprimer les branches fusionnées.

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git checkout $branchnew
done

git checkout master

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git push origin --delete $branchnew
done
3
répondu Komu 2017-09-01 00:03:30

la solution acceptée est assez bonne, mais il y a un problème qu'elle supprime aussi les branches locales qui n'ont pas encore été fusionnées dans une télécommande.

si vous regardez la sortie de vous verrez quelque chose comme

$ git branch --merged master -v
  api_doc                  3a05427 [gone] Start of describing the Java API
  bla                      52e080a Update wording.
  branch-1.0               32f1a72 [maven-release-plugin] prepare release 1.0.1
  initial_proposal         6e59fb0 [gone] Original proposal, converted to AsciiDoc.
  issue_248                be2ba3c Skip unit-for-type checking. This needs more work. (#254)
  master                   be2ba3c Skip unit-for-type checking. This needs more work. (#254)

Branches bla et issue_248 sont des branches locales qui seraient supprimées en silence.

mais vous pouvez aussi voir le mot [gone] , qui indique les branches qui ont été poussées à une distance (qui est maintenant disparu) et donc dénoter des branches peuvent être supprimés.

la réponse originale peut donc être changée en (divisé en plusieurs lignes pour une longueur de ligne plus courte)

git branch --merged master -v | \
     grep  "\[gone\]" | \
     sed -e 's/^..//' -e 's/\S* .*//' | \
      xargs git branch -d

pour protéger les branches non encore fusionnées. Aussi le grêlage pour le maître pour le protéger, n'est pas nécessaire, car cela a une télécommande à l'origine et ne se présente pas comme disparu.

2
répondu Heiko Rupp 2018-06-15 08:53:22

pour éviter d'exécuter accidentellement la commande d'une autre branche que master j'utilise le script bash suivant. Sinon, exécuter git branch --merged | grep -v "\*" | xargs -n 1 git branch -d à partir d'une branche fusionnée de off master pourrait supprimer la branche master.

#!/bin/bash

branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)"     # detached HEAD
branch_name=${branch_name##refs/heads/}

if [[ $branch_name == 'master' ]]; then
   read -r -p "Are you sure? [y/N] " response
   if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
       git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
   fi
else
   echo "Refusing to delete branches that are not merged into '$branch_name'. Checkout master first."
fi
1
répondu Robert Kajic 2014-01-20 17:19:11

à partir de 2018.07

ajouter à [alias] section de votre ~/.gitconfig :

sweep = !"f() { git branch --merged | egrep -v \"(^\*|master|dev)\" || true | xargs git branch -d; }; f"

Maintenant, vous pouvez simplement appeler git sweep pour effectuer ce nettoyage nécessaire.

1
répondu sorin 2018-07-01 07:49:19

Pour Windows, vous pouvez installer Cygwin et supprimer toutes les branches distantes en utilisant la commande suivante:

git branch -r --merged | "C:\cygwin64\bin\grep.exe" -v master | "C:\cygwin64\bin\sed.exe" 's/origin\///' | "C:\cygwin64\bin\xargs.exe" -n 1 git push --delete origin
1
répondu Seyed Morteza Mousavi 2018-09-09 07:17:03

pour supprimer les branches locales qui ont été fusionnées à master branch j'utilise l'alias suivant ( git config -e --global ):

cleanup = "!git branch --merged master | grep -v '^*\|master' | xargs -n 1 git branch -D"

j'utilise git branch -D pour éviter les messages error: The branch 'some-branch' is not fully merged. alors que ma caisse actuelle est différente de la branche principale.

0
répondu dgt 2014-10-09 08:45:44

windoze-friendly Python script (parce que git-sweep s'est étouffé sur le dépôt Wesnoth):

#!/usr/bin/env python
# Remove merged git branches. Cross-platform way to execute:
#
#   git branch --merged | grep -v master | xargs git branch -d
#
# Requires gitapi - https://bitbucket.org/haard/gitapi
# License: Public Domain

import gitapi

repo = gitapi.Repo('.')
output = repo.git_command('branch', '--merged').strip()
for branch in output.split('\n'):
  branch = branch.strip()
  if branch.strip(' *') != 'master':
    print(repo.git_command('branch', '-d', branch).strip())

https://gist.github.com/techtonik/b3f0d4b9a56dbacb3afc

0
répondu anatoly techtonik 2015-01-06 18:52:02

si vous utilisez un modèle de branchement comme HubFlow ou GitFlow, vous pouvez utiliser cette commande pour supprimer les branches fusionnées:

git branch --merged | grep feature.* | grep -v "\*" | xargs -n 1 git branch -d

0
répondu bedrin 2015-02-26 14:02:42