Por que posso fazer checkout de uma ramificação que foi removida no GitHub?

26

Em nosso repositório GitHub, um colega de trabalho removeu um ramo chamado release. Mas quando executo git checkout releaselocalmente, sempre obtenho a ramificação removida release. Mesmo, mesmo quando fiz check-out de outro ramo, excluí o releaseramo git branch -D releasee executei novamente git checkout release.

Existe algo para corrigir no repositório GitHub ou devo corrigir algo localmente?

Tim
fonte
1
O que é git branch --remoteproduzido após a execução git fetch? Pode ser necessário remover git fetch -ppara esquecer as ramificações remotas excluídas.
Stephen Kitt
2
Se esse ramo já foi enviado ao GitHub e você o puxou depois disso, também possui uma cópia do ramo. Todo repositório git é completo por si só, a menos que você use um clone superficial ou algo assim.
187 muru
@StephenKitt: Obrigado. git branch --remotesaída origin/release. Você deseja executar git fetch -psem argumentos adicionais e removerá todas as ramificações remotas excluídas?
Tim
1
Sim, git fetch -psem argumentos adicionais, podará todas as ramificações remotas excluídas.
Stephen Kitt
1
Bem-vindo ao mundo do controle de versão distribuído!
chrylis -on strike-

Respostas:

24

Depois de excluir uma ramificação no lado remoto, você ainda poderá ver localmente essa ramificação remota anteriormente buscada, consulte:

$ git branch -a
[...]
release
remotes/origin/release
[...]

Você removeu apenas o "lançamento", mas não o "controle remoto / origem / lançamento". Exclua-o assim:

$ git branch -rd origin/release

Ou remova todos os ramos buscados que não existem mais no lado remoto:

$ git remote prune origin 
rudimeier
fonte
Obrigado. Em git branch -rd origin/release, o que -rsignifica? Será que -dsignifica o mesmo que -D? Pode git branch -rd origin/releaseser substituído por git branch -d remotes/origin/release?
Tim
@ Tim: A partir do manual; -r: List or delete (if used with -d) the remote-tracking branches.; -D:Shortcut for --delete --force.
looper
Obrigado. Pode git branch -rd origin/releaseser substituído por git branch -d remotes/origin/release?
Tim
@ Tim não -rse refere a filiais remotas , é necessário. As ramificações local e remota são armazenadas em diferentes diretórios, compare ls -l .git/refs/headse ls -l .git/refs/remotes. Você também pode ter um ramo local chamado remotes/origin/releaseque seria excluído sem -r. Pode parecer confuso, mas você pode apenas brincar, criar ramos com nomes estranhos e ver como fica .git/.
Rudimeier
15

Quando as ramificações são excluídas remotamente, você precisa remover seu repositório local - a maneira mais fácil de fazer isso é com

git fetch -p

Isso atualizará seu repositório local com todas as alterações feitas no repositório remoto, mas sem atualizar nenhuma de suas ramificações locais. Depois de executar isso,

git branch --remote

não mostrará mais a ramificação remota excluída.

Os repositórios git estão completos, seja no seu próprio sistema ou no servidor. Portanto, quando você clona um repositório pela primeira vez, você obtém uma cópia completa e seu git local “conhece” todas as ramificações remotas, bem como suas ramificações locais. Essas informações não são sincronizadas automaticamente; portanto, quando seu colega excluiu a releaseramificação no servidor, seu repositório git local não perdeu a noção de releaseramificação remota . A sincronização com git fetchatualiza todas as informações locais nas filiais remotas para que correspondam ao estado no servidor (a rigor, repositório remoto, onde quer que esteja), mas sem excluir nenhuma informação local nas filiais remotas. A remoção com git fetch -p(ou git fetch --prune, ou git remote prune) remove as informações locais nas ramificações remotas que foram excluídas.

Stephen Kitt
fonte
Obrigado. "atualize seu repositório local com todas as alterações feitas no repositório remoto, mas sem atualizar nenhuma de suas ramificações locais". Que atualização é essa, já que não é uma atualização de minhas filiais locais?
Tim
São todas as atualizações remotas. Seu repositório git local distingue suas ramificações locais e remotas, mas as ramificações remotas não são sincronizadas magicamente com o servidor - elas existem localmente também (como armazenadas em seu repositório git local). A busca sincroniza seu repositório local com o repositório remoto e atualiza o estado das ramificações remotas; por padrão, as ramificações remotas excluídas não são removidas das informações locais das ramificações remotas, -p( --prune) força isso.
Stephen Kitt
Obrigado. Por que não eliminar o releaseramo por git branch -D releasediante git checkout releasemake git checkout releaseparar de receber o releaseramo?
Tim
1
Porque git checkout releaserecriará automaticamente uma ramificação se houver uma ramificação remota com esse nome.
Stephen Kitt
Por "ramificação remota", você quer dizer uma ramificação no meu repositório local ou no Github? Se antigo, git branch -D releasejá excluiu a releaseramificação no meu repositório local; Se for o caso, um colega de trabalho excluiu a releaseramificação no GitHub; Então, ainda não sei por que "recriará automaticamente uma ramificação se houver uma ramificação remota com esse nome"?
Tim
3

Tim: O Git é VCS distribuído, portanto, quando você clona um repositório do remoto para o local, ele clona tudo (histórico). Então, quando você clonou seu repositório, ele tinha um ramo chamado release. Desde que seu colega excluiu a ramificação da versão remotamente, até que você faça uma remoção git fetch -pou exclua essa ramificação explicitamente, seu local terá essa ramificação.

ManiVI
fonte
3
Como esta resposta difere das respostas já presentes?
Stephen Rauch
1

Talvez um pouco tangencial, mas a perspectiva deste site pode ajudar a entender o tópico geral de exclusão de ramificações:

http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/

Há sobreposição com parte do que já foi discutido aqui, mas o foco está na limpeza: excluir filiais, remotas e locais, que não são mais necessárias em um ambiente colaborativo. Em particular, o git branch --mergedcomando identifica ramificações que podem ser excluídas com segurança devido à mesclagem com sua linha principal (ou com qualquer ramificação de sua preferência). Se você estiver colaborando, alguns mini scripts mais sofisticados como este apresentarão as coisas em um formato agradável e digerível com datas e autores.

for branch in `comm -12  <(git branch --merged|awk '{print($1)}') <(git branch -r --merged|awk '{print($1)}'|awk -F \/ '{print($2)}')`; do echo -e `git show --format="%ci %cr %an" $branch | head -n 1` \\t$branch; done | sort -r

(Infelizmente, "agradável, digerível" não se aplica à formatação dos próprios scripts.)

Camada B
fonte