Quando excluir ramificações no Git?

284

Suponha que tenhamos um aplicativo estável.

Amanhã, alguém relata um grande problema que decidimos corrigir imediatamente. Portanto, criamos uma ramificação para esse hotfix fora de "master", o denominamos "2011_Hotfix" e o empurramos para que todos os desenvolvedores possam colaborar na correção.

Corrigimos o erro e mesclamos "2011_Hotfix" em "master" e também no ramo de desenvolvimento atual. E pressione "mestre".

O que fazemos com o "2011_Hotfix" agora? Deveria permanecer ali como um ramo para sempre até o fim dos tempos ou devemos excluí-lo agora, pois serviu a seu propósito? Parece impuro deixar galhos espalhados por toda parte, pois a lista de galhos provavelmente se tornará muito longa, a maioria dos quais nem é mais necessária.

No caso de ser excluído, o que acontecerá com seu histórico? Isso será mantido, mesmo que a ramificação real não esteja mais disponível? Além disso, como removeria uma ramificação remota?

Anthony Compton
fonte
33
Muitas vezes, ajuda a pensar nos galhos como idéias. Uma regra prática bastante boa é que, se você terminar de trabalhar nas idéias que o ramo representa - incluindo testar e incorporar essas alterações (mesclando-as no mestre) -, você concluirá com o próprio ramo.
Cascabel
3
O que eu gostaria de saber: se o hotfix remoto estiver sendo removido, ele será removido localmente para todos os desenvolvedores que colaboraram? Se não; como conseguir isso? Eu acho que uma pessoa migra o hotfix para o mestre, mas depois disso ele deve ser limpo para todos os colaboradores, para impedir que eles adicionem confirmações a esse ramo.
Rolandow
1
Você não pode afetar os repositórios locais dos computadores de seus colegas de trabalho. Você tem que dizer-lhe para apagar o ramo localmente ou você também pode aplicar este lado do servidor com segurança ganchos git / filial para evitar empurrões do seu ramo que você deseja manter apagado
srz2

Respostas:

183

Você pode remover com segurança um ramo com git branch -d yourbranch. Se ele contiver alterações não imersas (ou seja, você perderá os commit excluindo o branch), o git dirá a você e não o excluirá.

Portanto, excluir uma ramificação mesclada é barato e não fará com que você perca nenhum histórico.

Para excluir uma ramificação remota, use git push origin :mybranch, assumindo que seu nome remoto seja origem e a ramificação remota que você deseja excluir seja nomeada mybranch.

Artefato2
fonte
35
"excluir uma ramificação mesclada é barato", mas também mantê-la por perto. Não há impacto significativo no desempenho em termos de tempo ou espaço que o git usa, se você o mantiver por perto. Dito isso, eu excluiria o ramo porque todos os commits já estão lá no histórico do master, portanto isso torna as coisas muito mais limpas.
MatrixFrog
22
Uma das minhas razões para querer excluir ramificações é: Fazemos muitas alterações nas ramificações (na verdade, todas as alterações), para que você tenha uma lista longa ao usar o comando 'git branch'. Para uma visão geral, quero encurtar essa lista. Os ramos antigos serão excluídos. Os lançamentos da Reale estão marcados, portanto não estão nessa discussão para mim.
Michel.iamit
7
Embora concorde com a exclusão de ramos que já foram incorporadas, se você quiser ver uma lista de agências que não foram fundidas ao ramo atual, você pode usar: git branch --no-se fundiu
lsklyut
51
@MatrixFrog É barato ficar por aí em termos de git, no entanto, o custo humano pode se tornar caro. Acabei de entrar em um projeto com cerca de 40 ramificações, todas com nomes de ramificação numéricos. Não tenho ideia do que é o que é, e quase todos esses galhos estão obsoletos. A sobrecarga de pesquisar por esses ramos e descobrir o que é cansativo e leva tempo. Então sim, tecnicamente é barato, mas na verdade não é. Eu gosto de manter minha forma de reporte do Git. Se não estiver no dev ativo e tiver sido mesclado, exclua-o. Mas esse é apenas o meu MO e eu respeito que outras pessoas possam fazer algo diferente.
Dudewad
1
Qual é o comando para tornar --no-mergedo padrão? Eu tentei git config --global --add branch.noMerged truee foi adicionado, mas não fez nenhuma diferença.
Craig Silver
55

O que você precisa fazer é marcar qualquer coisa que você liberar. Mantenha os ramos por perto para quando você estiver desenvolvendo ativamente.

Exclua ramificações antigas com

git branch -d branch_name

Exclua-os do servidor com

git push origin --delete branch_name

ou a sintaxe antiga

git push origin :branch_name

que lê como "enviar nada para branch_name na origem".

Dito isto, enquanto o DAG (gráfico acíclico direcionado) puder apontar para ele, os commits estarão lá na história.

O Google "git-flow" e isso podem fornecer mais informações sobre gerenciamento de liberação, ramificação e marcação.

Adam Dymitruk
fonte
31

Como a pergunta tem a tag "github", eu também adicionaria isso: especificamente no Github , se você solicitar uma ramificação e ela for mesclada (por meio da interface do usuário ou mesclando a ramificação da solicitação), você não perca os dados da solicitação de recebimento (incluindo comentários), mesmo se você remover a ramificação .

Uma conseqüência disso: se você incorporar solicitações pull como parte do seu fluxo de trabalho (que combina suavemente com as revisões de código), poderá excluir com segurança as ramificações assim que elas forem mescladas. Isso é tão comum que recentemente o Github adicionou um recurso (doce) que exibe um botão "excluir ramificação" logo após a mesclagem de uma solicitação pull.

Mas é importante notar que cada grupo deve adotar o fluxo de trabalho que melhor lhe convém (e pode ou não levar à exclusão de tais ramificações). Minha equipe de trabalho atual, por exemplo, remove todas as ramificações que não são mestre ou relacionadas à implantação (por exemplo, produção, preparo etc.) assim que suas solicitações pull são mescladas, e ainda temos um rastreamento completo de como as confirmações relacionadas foram formadas cada melhoria incremental de cada produto.

É claro que nenhum gerenciamento de histórico (solicitações de recebimento ou de outra forma) substitui a marcação adequada de versões (que você prefere automatizar com a mesma ferramenta / script que implanta / empacota uma versão), para que você possa sempre alternar rapidamente para o que seus usuários estiverem em um determinado momento. A marcação também é a chave para resolver seu problema original: se você estabelecer que qualquer ramificação mesclada com as ramificações "de trabalho" pode e deve ser excluída e que qualquer que seja mesclada com uma tag de versão, "produção" etc. , você sempre terá os hotfixes ativos até que sejam integrados em uma versão futura.

chesterbr
fonte
2
Obrigado por explicar por que o Github estava me mostrando um botão "Excluir ramo".
Todd Owen
Estamos usando o sourcetree e ele oferece a opção de manter a filial de hotfix local e a filial de hotfix remota abertas. Eu pensei que fechar um ramo de hotfix significava excluí-lo e você não pode reutilizá-lo. Por exemplo, precisamos enviar correções quentes todos os dias pelos próximos 5 dias. Então fechamos. Mas digamos que no sexto dia, precisamos de outro hotfix. Criamos um novo ramo de hotfix?
Danger14
É o que as pessoas costumam fazer. Se não for possível nomeá-los individualmente, você poderá nomeá-los com base no dia ou na referência do sistema de tickets que os gerencia (se houver). Obviamente, os fluxos de trabalho do git devem ser aplicados "com base no que for melhor para sua equipe", portanto, não se preocupe se você decidir trabalhar de maneira diferente.
Chesterbr #
7

Eu acrescentaria que a desvantagem de excluir ramificações é que você quebrará quaisquer hiperlinks para essas ramificações no GitHub (essa pergunta está marcada como github). Você receberá um 404 Not Founderro para esses links. É por isso que altero meus links para apontar para uma confirmação ou marca após excluir uma ramificação no GitHub.

Como alguns links não podem ser alterados, como no email, agora evito hiperlinks para as ramificações do GitHub inteiramente e vinculo a um commit ou tag desde o primeiro dia.

Prefiro excluir ramificações depois que elas são mescladas. Isso evita a confusão visual de uma longa lista de ramificações em seu repositório. Essas ramificações também são propagadas para todos os garfos do repositório.

Primeiro, excluo minha filial local. Isso evita que ele seja empurrado acidentalmente mais tarde.

git branch -d branchName

Em seguida, excluo o ramo de rastreamento remoto

git branch -dr remoteName\branchName

Então eu apago a ramificação no GitHub. Eu uso a interface da web, mas o comando equivalente está abaixo.

git push remoteName :branchName

Mesmo que o ramo nunca seja mesclado, normalmente eu ainda gostaria de manter os commits disponíveis para a posteridade. No entanto, ainda gosto de excluir o ramo. Para espalhar as confirmações e impedir que elas sejam comidas pelo coletor de lixo, eu faço uma marca anotada apontando para a mesma confirmação que a ramificação excluída.

git tag -a tagName commitOrBranchName

Então eu empurro a tag para o github

git push remoteName tagName
Mark F Guerra
fonte
Quando o coletor de lixo come os commits do ramo? Você precisa marcar e enviar a etiqueta antes de excluir a ramificação?
Jared Thirsk
4

Parece que você deseja excluir o 2011_Hotfixramo sem perder o histórico. Discutirei a exclusão primeiro e a história depois.

Os gitmétodos usuais de exclusão de ramificação já foram descritos acima e funcionam conforme o esperado. gitnão possui um comando de uma ou duas palavras que significa "Ei git, exclua as ramificações local e remota". Mas esse comportamento pode ser imitado via shell script. Por exemplo, considere o script de shell de Zach Holman 'git-nuke' . É muito simples:

#!/bin/sh
git branch -D $1
git push origin :$1

Coloque isso em um arquivo executável (por exemplo, git-nuke) em um de seus $PATHdiretórios. Se você não estiver no 2011_Hotfixramo, você simplesmente executando git-nuke 2011_Hotfixexcluirá os ramos local e remoto. Isso é muito mais rápido e simples - embora talvez mais perigoso - do que o padrãogit comandos .

Sua preocupação com a preservação da história é boa. Nesse caso, você não precisa se preocupar. Uma vez que você mesclar 2011_Hotfixpara master, todas as submissões de 2011_Hotfixserá adicionado ao master's cometer história. Em resumo, você não perderá o histórico de uma mesclagem simples.

Tenho mais uma palavra a acrescentar que talvez esteja além do escopo da sua pergunta, mas seja relevante no entanto. Vamos imaginar que há 20 minúsculos "trabalhos em andamento" confirmados 2011_Hotfix; no entanto, você deseja que apenas uma confirmação completa 2011_Hotfixseja adicionada ao masterhistórico da. Como você combina todas as 20 pequenas confirmações em uma grande confirmação? Felizmente, gitpermite consolidar várias confirmações em uma confirmação usando git-rebase. Não vou explicar aqui como isso funciona; no entanto, se você estiver interessado, a documentação paragit-rebase é excelente. Observe que git rebasereescreve o histórico, portanto ele deve ser usado criteriosamente, especialmente se você é novo nele. Finalmente, seu 2011_Hotfixcenário é sobre um time de desenvolvimento, não um desenvolvedor solo. Se os membros da equipe do projeto usaremgit rebase, é aconselhável que a equipe tenha diretrizes explícitas sobre o uso git rebase, para que algum desenvolvedor de cowboys da equipe não danifique involuntariamente o githistórico de um projeto .

jfmercer
fonte
3

Se ele tiver sido mesclado com êxito e talvez até marcado, eu diria que não tem mais uso. Então você pode fazer com segurança git branch -d branchname.

Michael Fürstenberg
fonte
2

Se você deseja remover ramificações locais que foram removidas da origem, também é possível remover, enquanto estiver usando git fetch

git fetch --prune
huch
fonte
0

Você pode excluir ramificações em todas as principais UIs da web, como github, BitBucket. Após excluir a filial online, você pode excluir a filial local usando

git remote prune origin
tkruse
fonte