Posso excluir todas as filiais locais, exceto a atual?

95

Quero excluir todos os ramos listados na saída de ...

$ git branch

... mas mantendo o branch atual, em uma única etapa . Isso é possível? Se sim, como?

sensorario
fonte

Respostas:

66

Com base na resposta de @pankijs, criei dois aliases git:

[alias]
    # Delete all local branches but master and the current one, only if they are fully merged with master.
    br-delete-useless = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -d;\
    }; f"
    # Delete all local branches but master and the current one.
    br-delete-useless-force = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -D;\
    }; f"

Para ser adicionado em ~/.gitconfig


E, como @torek apontou:

Observe que letras minúsculas -dnão excluirão um branch "não totalmente mesclado" (consulte a documentação). Usar -D irá deletar tais branches , mesmo que isso faça com que os commits se tornem "perdidos"; use isso com muito cuidado , pois isso exclui os reflogs do branch também, de modo que o material usual de "recuperação de exclusão acidental" também não funcione.

Basicamente, nunca use a -forceversão se não tiver 300% de certeza de que não perderá nada importante. Porque está perdido para sempre .

Vadorequest
fonte
2
commits para um branch excluído ainda devem estar no reflog por um tempo.
CaptRespect
Na verdade, os commits permaneceriam em reflog. Mas não o próprio ramo. Eu não tentaria, mas acho que você pode encontrar seus commits, mas voltar para o estado de branch? Eu duvido. Cherry-pick pode ser usado para recuperar commits em um branch excluído, mas você não será capaz de restaurar o branch em si.
Vadorequest
1
@Vadorequest você pode recriar o branch apontando para um certo commit fazendogit branch branchname commitid
pqnet
@pqnet Não sabia que iria recriar toda a história desse ramo, obrigado, bom saber!
Vadorequest
1
@Vadorequest, uma vez que os objetos de commit são imutáveis ​​(e indexados como hashes), cada edição requer a criação de um novo objeto (com um hash diferente)
pqnet
179
$ git branch | grep -v "master" | xargs git branch -D 

irá deletar todos os branches exceto o master (substitua o master pelo branch que você deseja manter, mas então irá deletar o master)

pankijs
fonte
29
Se você deseja manter o uso do branch atualgrep -v ^* .
Schwern
2
Muitas fontes me mostram esse script, mas quando eu o executo, sempre me dizem que branches não encontrados :(
tucq88
1
isso não é preciso, não excluirá um branch chamado master-copy, por exemplo
mvallebr
2
Ajuste a regex conforme necessário, por exemplogrep -v "^ *master$"
Brad Koch
7
Se você quiser manter dois ramos, use grep -v "master\|my-other-branch".
Derek Soike
17

primeiro (mude para o branch que deseja manter> ex : master ):

git checkout master

segundo ( certifique - se de que você está no mestre )

git branch -D $(git branch)
KhogaEslam
fonte
3
muito rápido e fácil. Por que isso não está sendo votado?
princebillyGK
1
É a melhor e mais simples resposta para mim.
Saleh Enam Shohag
1
Se você estiver usando o PowerShell, use git branch -D $(git branch).Trim().
NatoBoram
13

git branch -d(ou -D) permite vários nomes de branch, mas é um pouco complicado fornecer automaticamente "todos os branches locais, exceto aquele em que estou agora" sem escrever pelo menos um pouco de código.

O "melhor" método (formalmente correto) é usar git for-each-refpara obter os nomes dos ramos:

git for-each-ref --format '%(refname:short)' refs/heads

mas então é ainda mais difícil descobrir em qual branch você está ( git symbolic-ref HEADé o método "formalmente correto" para isso, se você quiser escrever um script sofisticado).

Mais convenientemente, você pode usar o git branch, que imprime os nomes dos seus ramos locais precedidos por dois espaços ou (para o ramo atual) por um asterisco *. Então, execute isso por meio de algo para remover a *versão e você ficará com nomes de branch separados por espaço, que você pode então passar para git branch -d:

git branch -d $(git branch | grep -v '^*')

ou:

git branch | grep -v '^*' | xargs git branch -d

Observe que letras minúsculas -dnão excluirão um branch "não totalmente mesclado" (consulte a documentação). Usar -Dirá deletar tais branches, mesmo que isso faça com que os commits se tornem "perdidos"; use isso com muito cuidado, pois isso exclui os reflogs do branch também, de forma que as coisas usuais de "recuperação de exclusão acidental" também não funcionem.

Torek
fonte
Deveria ser git branch -D $(git branch | grep -v '^*'), se você quiser deletar aquelas ramificações que foram mescladas.
Pratik Singhal
@PratikSinghal: isso exclui todos os outros branches, não apenas branches que o Git considera "mesclados". Isso raramente é uma boa ideia. Já indiquei esses dois itens em minha resposta.
rasgou em
12

Para remover todas as ramificações mescladas (exceto as atuais -v ‘*’):

git branch --merged | grep -v '*' | xargs git branch -D

também fiz esse comando para limpeza completa do repo:

alias git-clean="git branch  | grep -v '*' | grep -v 'master' | xargs git branch -D  && git reset --hard && git clean -d -x -f"

tirado daqui .

Stepan Suvorov
fonte
1
Isso exclui apenas os ramos mesclados.
Pratik Singhal
10

Exclua todos os ramos, exceto um ramo específico :

git branch | grep -v "branch name" | xargs git branch -D

Exclua todos os branches locais, exceto Develop e Master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Asad Manzoor
fonte
6

Para Windows, no Powershell use:

git branch | %{ $_.Trim() } | ?{ $_ -ne 'master' } | %{ git branch -D $_ }
Robert Corvus
fonte
4

Exclua todas as ramificações mescladas localmente:

git branch -D `git branch --merged | grep -v \* | xargs`

Exclua todos os ramos, exceto um ramo específico :

git branch | grep -v "branch name" | xargs git branch -D

Exclua todos os branches locais, exceto Develop e Master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Asad Manzoor
fonte
3

Certa vez, criei essa construção para meu ambiente Windows. Talvez ajude outra pessoa. Durante a execução, o master e o branch atual não são excluídos . Todas as outras ramificações mescladas serão excluídas independentemente.

@echo off
cd PATH_TO_YOUR_REPO

REM -- Variable declerations
set "textFile=tempBranchInfo.txt"
set "branchToKeep=master"
set "branchToReplaceWith="
git branch --merged > %textFile%

REM -- remove "master" from list to keep the branch
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%textFile%" echo(!line:%branchToKeep%=%branchToReplaceWith%!
    endlocal
)

REM -- execute branch delete commands
for /f "delims=" %%a in (%textFile%) do (
    git branch -D %%a
)

REM -- remove temp-file with branch information inside
DEL %textFile%

REM -- show local branches after the cleaning
echo Local branches:
git branch

pause 
exit
George Maharis
fonte
3

Para excluir todos os branches, exceto o branch atual em uma etapa:

git branch | grep -v $(git rev-parse --abbrev-ref HEAD) | xargs git branch -D

Dan Dye
fonte
2

Assumindo que git branchmostra o branch atual prefixado com *; Usando o Powershell, o seguinte liner excluirá todos os branches que não começam com *.

git branch | ? { $_ -lt "*" } | % { git branch -D $_.Trim() }

? = Where-Object

% = Foreach-Object

Aaron
fonte
1

Portanto, vejo muitos nomes de branch codificados aqui ... E acho que minha resposta aqui é mais precisa para a parte "branch atual" da pergunta, mantendo-a em uma única linha e legível para iniciantes como eu. Apenas para colocar o crédito onde é devido, a resposta é obviamente também baseada na resposta de @pankijs.

git branch | grep -v $(git branch --show-current) | xargs git branch -d

e eu tenho um alias em uma linha em meu .bash_aliases no debian também.

alias gitbclean='git branch | grep -v $(git branch --show-current) | xargs git branch -d'

(Embora eu ache que alguns recursos do bash precisam ser habilitados para que o subcomando seja executado em algumas linhas de comando)

NullifiedWarp
fonte
1

Uso isso porque consigo ser mais seletivo no que não quero excluir. O comando abaixo remove todos os ramos, exceto master, desenvolver e o ramo atual.

BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
echo $BRANCHES

Então eu coloquei isso no meu ~/.zshrc

delete_branches() {
  BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
  echo $BRANCHES
}

alias cleanup_branches=delete_branches
Justin Rice
fonte
0

IMHO, a maneira mais segura de remover filiais locais é:

git branch -av | grep "\[gone\]" | awk '{print $1}' | xargs git branch -d

Além disso, mais informações relacionadas a este tópico você pode encontrar Delete all git branches locais

Elbik
fonte
para imprimir o gonemarcador que você deve usar -vv(verbose duas vezes), embora -anão vá ajudá-lo (ele lista também branches remotos)
pqnet