Excluir várias ramificações remotas no git

128

Eu tenho um membro da equipe que inadvertidamente empurrou mais de 150 de suas filiais locais para o nosso repositório central. Felizmente, todos eles têm o mesmo prefixo. Usando esse prefixo, existe um comando git ou um pequeno shell script que eu possa usar que excluirá todos eles de uma só vez?

Jake A. Smith
fonte

Respostas:

150

Use o comando a seguir para remover todas as ramificações com PREFIXprefixo no servidor remoto.

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

Você pode fazer um teste a seco primeiro para ver se são os galhos que deseja remover:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'
neevek
fonte
2
Eu gosto disso porque é uma linha e eu posso fazer uma corrida a seco primeiro. Infelizmente, ele erro com esta mensagem: $ 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
Com git branch -r | awk -F/ '/\/APR/{print $2}', você pode ver todos os nomes de filiais prefixados da APR listados?
11402 neevek
1
OK, é porque o APR-04-DPHramo já foi excluído. Dê uma olhada nestas perguntas respondidas: isto e isto e também isso . As respostas para essas perguntas abordam o mesmo problema; você pode testar as soluções por conta própria.
11402 neevek
26
se você tem / em seus nomes do ramo (se você estiver usando git-flow ou algo assim), em seguida, imprimir {$ 2 "/" $ 3} em vez disso
ajma
4
Eu estou usando msysgit no Windows, e o comando a seguir trabalhou para mim (em conjunto com @ do ajma comentário para nomes ramo que contém barras:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe
96

Se você preferir uma abordagem mais simples, exclua 3 ou 4 ramos:

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

Importante: Funciona apenas no Git v1.7.0 e superior.

jfeston
fonte
6
Acabei usando #git branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Aram Kocharyan
36

Agradecimentos a Neevek pela excelente e elegante solução!

Mas tenho alguns problemas com barras nos nomes das filiais (estou usando o Git Flow), por causa do awkseparador de campos /( -Fopção)

Portanto, minha solução se baseia na de Neevek , mas analisa corretamente os nomes dos ramos /. Nesse caso, presumo que seu controle remoto tenha sido chamado origin. Comando para excluir ramificações remotas com nomes marcados com PATTERN:

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

E não se esqueça de verificar o que você vai excluir:

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

DICA ÚTIL: Se os nomes de sua filial (sem origin/prefixo) armazenados em um arquivo de texto (um nome de filial por linha), basta executar:

cat your_file.txt | xargs -I {} git push origin :{}
Dmitriy
fonte
2
Use em xargs -a file -Lvez de cat file | xargs. Ainda mais simples xargs -a file git push --delete origin.
MusiKk 10/09/2015
15

Esta pode ser uma resposta duplicada, mas abaixo testada e funcionou perfeitamente para mim.

  1. Excluir filial local com força

git branch -D branch-name

  1. Excluir filial remota

git push origin --delete branch-name

  1. Excluir mais de 1 filial local

git branch -D branch-name1 branch-name2

  1. Excluir mais de 1 filial remota

git push origin --delete nome-da-filial1 nome-da-filial2

  1. Exclua a ramificação local com prefixo. Por exemplo, recurso / *

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

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

  1. Listar ramificação remota com prefixo.

ramo git -r | grep -Eo 'feature /.*'

  1. Excluir ramificação remota com prefixo

ramo git -r | grep -Eo 'feature /.*' | xargs -I {} origem do push do git: {}

Naren
fonte
2
i acho que você quis escapar dos acentos graves no passo 5
GPL
Como adicionar backticks?
Naren
1
@ Naren: o problema é que a formatação de remarcação transforma seus backticks em um comando de estilo. Substituí-los por um método de substituição de comando diferente (por exemplo, "$ (command)" é equivalente a `command`, mas não é traduzido por markdown em algo estranho.) A outra coisa que você pode fazer é escapar dos backticks com '\'
Stabledog
13

O mesmo com o grep: git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -rmostra origin/prefix/branchname. Então vai demorar prefix/branchname.

Kirby
fonte
Eu acho que você quis dizer xargs -I {} git push origin :{}, não -i.
jojo
1
@jojo, AFAIK, -ipois usa a substituição padrão para, {}mas -Ivocê pode declarar a sua própria. ... acabei de encontrar no manual:-i ... the same as -I{}
Kirby
10

A solução da Neevek é elegante, mas pode ser melhor: a solução proposta chama de 'git push' uma vez por filial, o que significa que um ida e volta da rede adicional por filial será excluído. Como você está usando o awk de qualquer maneira, por que não usá-lo para prefixar o ':' e o xargs pode chamar 'git push' exatamente uma vez e excluir todos os ramos de uma só vez:

Execute a seco para listar as ramificações que seriam excluídas:

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

Solução final para realmente enviar as exclusões:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin
falta
fonte
2
Funciona perfeitamente na situação em que você não pode usar a opção "-I" para xargs quando você tem uma versão inferior do bash ou usa uma versão do Windows git bash.
Zchholmes
Eu tive um xargs: replstr may not be emptycom a solução de Neevek, talvez versão git .. git version 1.9.5Mas isso funcionou muito bem para mim. Obrigado a vocês dois
IamFace 23/03
8

recurso 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
fonte
Graças isso funcionou para mim. No caso mu, eu poderia excluir várias ramificações locais. Obrigado!
Prashant Kabade
5

Graças a Steve e Neevek, encontrei uma solução que funcionou muito bem para mim e achei que valeria a pena compartilhar:

A solução de Steve funcionou para mim com um pequeno ajuste. Meus controles remotos foram nomeados, origin/feature/some-feature-nameentão eu aparei o seu awk:

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

Agora está fazendo um bom fluxo de exclusão:

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

Fiquei imaginando se alguém tinha alguma idéia para uma solução mais elegante, porém, que pudesse gerar algo assim (meu script CLI é muito ruim, por isso levaria um tempo para descobrir isso):

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

Isso resultaria em uma única saída agradável com uma solicitação de rede:

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
fonte
4

Graças a Neevek. Isso funcionou bem depois de reconfigurá-lo para o meu propósito:

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

Eu também precisava levar em conta a estrutura da pasta. Meus ramos de recursos estão em uma estrutura de pastas como origem / recurso / PREFIX-FEATURENUMBER. Então, eu tive que construir meu padrão a partir de $ 2 = pasta + $ 3 = branchname.

user3416278
fonte
4

Todo mundo está usando awk, não sei por quê. Eu sinto que isso é mais complexo. Aqui está o que eu uso para excluir todas as ramificações remotas no meu forkcontrole remoto:

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

Jogue grepentre xargse sedse você precisar filtrar a lista para baixo apenas para um subconjunto de ramificações remotas.

void.pointer
fonte
1
Muito obrigado. Este realmente funcionou para mim entre todas as soluções .. grep estava retornando o ramo completo com nome remoto, assim como origin/blaprefix_anotherbla. Mas usar sedlidou bem com isso. Outra vantagem dessa abordagem é que eu uso o bitbucket e não preciso inserir a senha de autenticação para cada exclusão de ramificação manualmente. Este exclui todas as ramificações em um único lote.
Madhur Bhaiya
Para excluir todos os ramos do git branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
Greenkeeper
4

Sei que isso é para o comando git, mas se você estiver procurando por uma solução alternativa para obter o mesmo resultado:

Você pode fazer isso aqui (Git Remove Remote Branches):

Em seguida, selecione os ramos que você deseja:

Verifique se você tem permissões para remover as ramificações remotas.

Ewin Hong
fonte
Esta deve ser a resposta principal, pois é independente da plataforma.
precisa saber é o seguinte
Qual é o software e está disponível para linux?
abhisekp 19/07
1

O Github também possui uma interface de usuário e um mecanismo agradáveis ​​para excluir ramificações rapidamente, ou seja, se você preferir usar uma interface de usuário

Alex
fonte
1
Sim, está documentado aqui , mas você ainda deve clicar uma vez para cada ramificação individual. A solução mais votada aqui é a melhor maneira de fazer muitos ramos com os quais você pode escrever um regex para corresponder.
thewoolleyman
0

Tentei excluir todas as ramificações remotas origin / release / r1-1 *, portanto, a linha de comando a seguir funcionou bem.

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

Não pude usar o awk porque estamos usando uma estrutura de barra para o nome de nossas filiais.

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

Isso obtém toda ramificação remota, obtém apenas a de um único usuário, remota a string "origin /" e executa uma exclusão em cada uma delas.

Patrick Desjardins
fonte
0

Funcionamento a seco:

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

Exclua ramificações remotas:

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

Exclua apenas ramificações remotas totalmente mescladas:

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

Explicação:

sed "s/origin\///"irá remover origin/do nome do ramo. Sem tirar isso, consegui:remote ref does not exist

Tobias Ernst
fonte
0

As respostas anteriores me ajudaram a remover todas as ramificações de lançamento a partir de 2018. Eu executei isso no prompt de comando do Windows 10. Eu instalei o clink , então os comandos do Linux funcionam para mim.

Funcionamento a seco:

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

Se o funcionamento a seco mostrar galhos que não estão remotos / de origem. Execute o comando git prune abaixo para corrigir e verificar novamente.

git remote prune origin

Exclua assim que estiver satisfeito com o resultado acima:

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

Se você ver: error: unable to delete 'release-...2018': remote ref does not exist. Em seguida, execute o comando de remoção anterior e tente novamente.

Damodar Bashyal
fonte
-4

Aviso: Isso excluirá todas as ramificações remotas. Use com cuidado.

Eu acho que a minha maneira de excluir filiais remotas é a melhor.

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

Aviso: Isso excluirá todas as ramificações remotas. Use com cuidado.

Dmytro Gorpynenko
fonte
4
Votado como um troll óbvio. Excluiria se eu tivesse os direitos.
Jake A. Smith
onde você encontrou trolling?
Dmytro Gorpynenko
2
isso não está correto, você está perdendo alguns argumentos vitais para o xargs e ele não responde à pergunta.
Rob
@ JakeA.Smith Jake, acho que você pensou que esse código removeria o mestre remoto - o que não é o caso do grep -v master, encontre tudo, exceto o mestre.
Vadim Samokhin
@ Rob o que está incorreto aqui? A declaração final executada será semelhante ao git push: some_branch: another_branch, o que é absolutamente correto.
Vadim Samokhin