Você pode excluir várias ramificações em um comando com o Git?

355

Eu gostaria de limpar o meu repositório local, que tem uma tonelada de ramos velhos: por exemplo 3.2, 3.2.1, 3.2.2, etc.

Eu estava esperando uma maneira sorrateira de remover muitos deles ao mesmo tempo. Como eles geralmente seguem uma convenção de liberação de pontos, pensei que talvez houvesse um atalho para dizer:

git branch -D 3.2.*

e mate todos os ramos 3.2.x.

Eu tentei esse comando e, é claro, não funcionou.

Doug
fonte
11
git branch -D $(git branch | grep 3.2*)- isso funcionou para mim. Exclui os ramos cujo nome começa com "3.2". grep- correspondência de padrões na saída ( git branchneste caso). $()- significa executar e colocar o resultado. |- encadeamento.
Eduard
4
Vale ressaltar que aqueles que não sabem, que -Dé uma exclusão forçada , devem usar -dna maioria dos casos para serem mais seguros primeiro.
Redfox05

Respostas:

363

Não com essa sintaxe. Mas você pode fazer assim:

git branch -D 3.2 3.2.1 3.2.2

Basicamente, o git branch excluirá várias ramificações para você com uma única invocação. Infelizmente, ele não conclui o nome do ramo. Embora, no bash, você possa:

git branch -D `git branch | grep -E '^3\.2\..*'`
slebetman
fonte
2
A conclusão git branch -D/-dfunciona bem para mim. Pode querer atualizar o seu (talvez do diretório mais recente do git.git contrib).
Cascabel
19
Em vez de git branch | ...você poderia usar $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). É mais longo, eu sei, mas é garantido que seja uma saída adequada, enquanto git branchtem uma saída bonita com coisas como *e ->(para symrefs) que podem atrapalhar você em scripts / one-liners.
Cascabel
3
Talvez eu seja o único com esse problema, mas tenho um grepalias para sempre incluir a bandeira --color=always- git branch -Destava jogando error: branch 'my_branch' not found.até que eu corri sem a bandeira colorida.
eebbesen
@eebbesen Você o desativou globalmente? Eu corro para o mesmo problema ao executargit branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr 10/08
2
Com a expansão cinta você poderia escrever git branch -D 3.2{,.1,.2}para apagar todos os três ramos gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck
147

Bem, no pior dos casos, você pode usar:

git branch | grep '3\.2' | xargs git branch -d
Carl Norum
fonte
22
Esse é praticamente o método perfeito para quem usa uma notação de prefixo padronizado para nomes de ramificações (por exemplo, "fix / ..." ou "feature / ...").
Haz
4
Simples e eficiente! Eu recomendo que seja executado primeiro sem a | xargs git branch -dparte para verificar o que realmente será excluído.
Mathielo 19/07/2018
Recomenda-se não grepa saída de git branch, como destinada para leitura, não para análise. Pode mudar a qualquer momento. use o for-each-refjunto com os --formatparâmetros, conforme sugerido em outras respostas, e depois combine com as sugestões nesta resposta.
Redfox05
138
git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches

EDITAR:

Uma versão mais segura (sugerida por Jakub Narębski e Jefromi), pois a saída do ramo git não deve ser usada no script:

git for-each-ref --format="%(refname:short)" refs/heads/3.2\* | xargs git branch -D

... ou o xargs-free:

git branch -D `git for-each-ref --format="%(refname:short)" refs/heads/3.2\*`
gawi
fonte
14
Não use a git branchsaída para scripts. Use git for-each-ref.
Jakub Narębski
11
Para excluir tags com o símbolo @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt
Tem um erro de digitação. Deve ser "/3.2/*" e não "/3.2*". Além disso, parece que você copiou e colou outras respostas por conta própria.
Max MacLeod
Nenhum erro de digitação aqui. Na página do manual:If one or more patterns are given, only refs are shown that match against at least one pattern, either using fnmatch(3) or literally, in the latter case matching completely or from the beginning up to a slash
gawi
11
Vale ressaltar que aqueles que não sabem, que -Dé uma exclusão forçada , devem usar -dna maioria dos casos para serem mais seguros primeiro.
redfox05
115

Você pode usar o git branch --list para listar os ramos elegíveis e o git branch -D / -d para remover os ramos elegíveis.

Um exemplo de revestimento:

git branch -d `git branch --list '3.2.*'`
50shadesofbae
fonte
Quando tento isso, recebo várias mensagens de erro como error: branch 'package.json' not found.. Parece que o * é expandido muito cedo e tenta excluir um ramo correspondente ao nome de cada arquivo e diretório.
Antimony
Isso funciona bem! Estou tendo problemas para usar isso como um pseudônimo com gitconfig...
whomaniac
6
Esta resposta precisa ser superior na lista, super limpo, obras, não grep
jemiloii
11
É bom que este seja fácil de testar primeiro apenas com a emissão #git branch --list '3.2.*'
Will
3
No windowsgit branch -d (git branch --list '3.2.*').trim()
Mattias Josefsson
38

Recentemente, eu estava procurando a solução do mesmo problema, finalmente encontrei uma resposta e está funcionando muito bem:

  1. Abra o terminal ou equivalente.
  2. Digite o ramo git | grep "pattern" para uma visualização dos ramos que serão excluídos.
  3. Digite o ramo git | grep "padrão" | xargs git branch -D

Esta solução é incrível e, se você quiser uma explicação completa de cada comando e como ele está funcionando, é fornecido aqui .

KJ Gor
fonte
28

Usar

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D
Jakub Narębski
fonte
7
Uma pequena dica é que, se você remover a última parte do comando "| xargs git branch -D", ele produzirá apenas os ramos correspondentes. Assim, você pode visualizar ramos que serão excluídos
Max MacLeod
11
Também acrescentei um alias para simplificar isso: alias grefs='git for-each-ref --format="%(refname:short)"'para que eu possa então fazergrefs | grep 'regexpattern' | xargs git branch -D
angularsen
Amei. Agradável e simples!
Bhargav Ponnapalli
15

Talvez você ache isso útil:

Se você deseja remover todos os ramos que não são, por exemplo, 'mestre', 'foo' e 'bar'

git branch -D `git branch | grep -vE 'master|foo|bar'`

grep -v 'something' é um combinador com inversão.

Adi
fonte
Eu, pessoalmente, gosto de -Dcomparar opções com outras respostas Obrigado pela resposta aqui @Adi. Soluções funciona para mim.
AMIC MING
9

Coloquei minhas iniciais e um hífen (at-) como os três primeiros caracteres do nome do ramo por esse motivo exato:

git branch -D `git branch --list 'at-*'`
Alan Tweedie
fonte
Todas as respostas dizem basicamente isso, isso é o mais simples.
Tfantina
7

Se você não estiver limitado a usar o prompt de comando git, sempre poderá executar git guie usar o item de menu Filial-> Excluir. Selecione todos os ramos que você deseja excluir e deixe rasgar.

Efpophis
fonte
isso apenas permite excluir filiais locais #
Stealth Rabbi
7

Solução Powershell:

Se você estiver executando o Windows, poderá usar o PowerShell para remover várias ramificações de uma só vez ...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.

Você também pode ajustar como a correspondência de padrões deve funcionar usando o comando Select-String do Powershell. Dê uma olhada nos documentos do PowerShell .

Imtiaz Shakil Siddique
fonte
6

Mantenha "desenvolver" e exclua todos os outros em locais

    git branch | grep -v "develop" | xargs git branch -D 
Daniel
fonte
5

Fiz uma pequena função que pode ser útil com base na resposta fornecida por @ gawi (acima).

removeBranchesWithPrefix() {
  git for-each-ref --format="%(refname:short)" refs/heads/$1\* | xargs git branch -d
}

Adicione isso ao seu .bash_profilee reinicie seu terminal. Em seguida, você pode chamar da linha de comando da seguinte maneira:

removeBranchesWithPrefix somePrefix

Nota

Atualmente, tenho a configuração para uma exclusão reversível, o que significa que não excluirá as ramificações, a menos que elas já tenham sido mescladas. Se você gosta de viver no limite, mude -dpara -De ele excluirá tudo com o prefixo, independentemente!

Logan
fonte
5

Se você realmente precisa limpar todos os seus galhos, tente

git branch -d $(git branch)

Ele excluirá todas as suas ramificações locais mescladas, exceto a que você está fazendo check-in.

É uma boa maneira de limpar seu local

Yulin
fonte
Isso funcionou bem o suficiente para mim. Deixou duas ramificações, exceto a que eu era, que eu removi usando o mesmo comando, mas usando um "-D" maiúsculo em vez de "-d". Eu recebi alguns erros sobre o git não encontrar arquivos, mas os ramos foram excluídos.
Lurifaxel
3

Você pode gostar deste pequeno item ... Ele puxa a lista e solicita a confirmação de cada item antes de finalmente excluir todas as seleções ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "remove branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done`

Use -D para forçar exclusões (como de costume).

Para facilitar a leitura, aqui está o que separamos linha por linha ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* |
    while read -r line; do 
        read -p "remove branch: $line (y/N)?" answer </dev/tty;
        case "$answer" in y|Y) echo "$line";; 
        esac; 
    done`

aqui está a abordagem xargs ...

git for-each-ref --format="%(refname:short)" refs/heads/\* |
while read -r line; do 
    read -p "remove branch: $line (y/N)?" answer </dev/tty;
    case "$answer" in 
        y|Y) echo "$line";; 
    esac; 
done | xargs git branch -D

finalmente, eu gosto de ter isso no meu .bashrc

alias gitselect='git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "select branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done'

Dessa forma, eu posso apenas dizer

gitSelect | xargs git branch -D.
Artesão do Caos
fonte
3

Para almas puras que usam o PowerShell aqui, o pequeno script git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })

codevision
fonte
2

funciona corretamente para mim:

git branch | xargs git branch -d

git branch | xargs git branch -D

excluir todas as ramificações locais

velastiqui
fonte
2

Use o comando a seguir para remover todas as ramificações (a ramificação com check-out não será excluída).

git branch | cut -d '*' -f 1 | tr -d " \t\r" | xargs git branch -d

Edit: Estou usando um Mac Os

ILYAS_Kerbal
fonte
0

Se você está no Windows, pode usar o PowerShell para fazer isso:

 git branch | grep 'feature/*' |% { git branch -D $_.trim() }

substitua feature/*por qualquer padrão que desejar.

Mo Valipour
fonte
6
grep é um cmdlet não reconhecido para mim ... então mudei para este ramo git | onde {$ _. Trim (). StartsWith ("bug")} | % {git branch -D $ _. Trim ()} e funcionou!
Alex
0

Você pode usar git guipara excluir várias ramificações de uma só vez. Em Prompt de Comando / Bash -> git gui-> Remoto -> Excluir ramificação ... -> selecione ramificações remotas que você deseja remover -> Excluir.

Terry Truong
fonte
0

Acabei de limpar um grande conjunto de filiais locais / remotas obsoletas hoje.

Abaixo está como eu fiz isso:

1. liste todos os nomes de ramificações em um arquivo de texto:

git branch -a >> BranchNames.txt

2. acrescente os ramos que desejo excluir ao comando "git branch -D -r":

git branch -D -r origem / dirA / branch01 origem / dirB / branch02 origem / dirC / branch03 (... acrescente quaisquer nomes de ramos)

3. execute o cmd

E este funciona muito mais rápido e confiável do que " git push origin --delete ".

Essa pode não ser a maneira mais inteligente, conforme listado em outras respostas, mas essa é bastante direta e fácil de usar.

RainCast
fonte
0

Se você instalou a GUI do Git, que é um complemento padrão para Windows, é a mais simples. Você pode usar ctrl para escolher vários ramos e excluí-los com um clique.

peiz
fonte
0

Se você estiver usando o Fish shell, poderá aproveitar as stringfunções :

git branch -d (git branch -l "<your pattern>" | string trim)

Isso não é muito diferente das opções do PowerShell em algumas das outras respostas.

mdiin
fonte
0

Se você tiver todos os ramos a serem excluídos em um arquivo de texto (ramos para del.txt) (um ramo por linha), poderá fazer isso para excluir todos os ramos do controle remoto (origem): xargs -a branches-to-del.txt git push --delete origin

code4kix
fonte
0

Para excluir várias ramificações com base em um padrão especificado, faça o seguinte:

Abra o terminal ou equivalente e digite os seguintes comandos:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)

Remova todas as ramificações 3.2.x, você precisa digitar

git branch | grep "3.2" | xargs git branch -D

Isso é tudo!

Você está pronto para ir!

Ankit Jindal
fonte
-1

Como no Git, todas as ramificações não são nada por referências ao .git/refrepositório git, por que você não exclui as ramificações e, se algo deixado de fora que não é interessante no repositório será automaticamente coletado como lixo? precisa se preocupar.

Debajit
fonte
-3

git branch -D <branchName>

Aakash Pahuja
fonte
-4

Você pode remover todas as ramificações removendo todas as referências desnecessárias:

rm .git/refs/heads/3.2.*

Artur Owczarek
fonte
2
A votação foi reduzida por duas razões: 1. ele usa um detalhe de implementação (o fato de que as versões atuais do Git armazenam as ramificações como arquivos em um determinado diretório). Isso pode mudar em versões futuras, tornando a resposta inválida. 2. Não funciona se o repositório estiver localizado em um diretório separado .
axiac 12/12
Além disso, isso produz resultados muito inesperados se você o executar em um repositório compactado ( git gc). Não faça isso.
Matthieu Moy