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?

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}'

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.


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 :{}

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: {}


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.


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

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

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

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.


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.


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.


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


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 :{}

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.


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


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.


-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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.