Quais são as diferenças entre o Git remoto prune, git prune, git fetch --prune, etc
a maioria das pessoas que perguntaram sobre este tipo de problema no fluxo de pilha, ou outros sites têm a questão de ramos ainda mostrando em sua lista de ramificações de rastreamento remoto git branch -a
No fundo:
* master
develop
feature_blah
remotes/origin/master
remotes/origin/develop
remotes/origin/feature_blah
remotes/origin/random_branch_I_want_deleted
No entanto, na minha situação, o ramo que não devia estar lá, é local.
* master
develop
feature_blah
random_branch_I_want_deleted
remotes/origin/master
remotes/origin/develop
remotes/origin/feature_blah
Quando faço alguma coisa a seguir, não é removida. localmente:
$ git prune
também tentei:
$ git remote prune origin
$ git fetch --prune
informação mais útil: quando eu verificar git remote show origin
isto é o que parece:
* remote origin
Fetch URL: utilities:homeconnections_ui.git
Push URL: utilities:homeconnections_ui.git
HEAD branch: master
Remote branches:
master tracked
develop tracked
feature_blah tracked
other123 tracked
other444 tracked
other999 tracked
Local branches configured for 'git pull':
develop merges with remote develop
feature_blah merges with remote other999
master merges with remote master
random_branch_I_want_deleted merges with remote random_branch_I_want_deleted
Local refs configured for 'git push':
develop pushes to develop (local out of date)
master pushes to master (up to date)
feature_blah pushes to feature_blah(up to date)
Repara que só está na secção intitulada Local branches configured for 'git pull':
Porquê?
4 answers
- a sucursal real no repositório remoto
- a sua imagem desse ramo localmente (guardada em
refs/remotes/...
)
E um ramo local que pode estar a seguir o ramo remoto.
random_branch_I_want_deleted
que se refere a alguns objetos que representam a história desse ramo. Então, por definição, git prune
não irá remover random_branch_I_want_deleted
. Realmente, git prune
é uma maneira de apagar dados que se acumularam no Git, mas que não estão a ser referenciados por nada. Em geral, não afecta a sua visão de nenhum ramo.
git remote prune origin
e {[7] } ambos operam com referências em {[[0]} (vou referir-me a estas como referências remotas). Ele não afecta os ramos locais. A versão git remote
é útil se você só quiser remover as referências remotas sob um remoto em particular. Caso contrário, os dois fazem exactamente a mesma coisa. Então, em resumo, git remote prune
e git fetch --prune
operam no número 2 acima. Por exemplo, se você excluir uma ramificação usando a GUI web do git e não quiser que ela apareça mais na sua lista de ramificações local (git branch -r
), então este é o comando que você deve usar.
Para remover um ramo local, deve usar git branch -d
(ou -D
Se não for fundiu-se em qualquer lugar). FWIW, não existe nenhum comando git para remover automaticamente os ramos de rastreamento locais se um ramo remoto desaparecer.
git remote prune
e git fetch --prune
faz a mesma coisa: apagar os árbitros para os ramos que não existem no remoto, como disseste. O segundo comando conecta-se ao remoto e pega seus ramos atuais antes da poda.
No entanto, não toca nos ramos locais que você verificou, que você pode simplesmente apagar com {[[8]}
git branch -d random_branch_I_want_deleted
Substituir -d
por -D
se o ramo não estiver reunido noutro lado
git prune
faz alguma coisa diferente, purgaobjectos inacessíveis, aqueles commits que não são alcançáveis em nenhum branch ou tag, e assim não precisa mais.
Note que uma diferença entre git remote --prune
e git fetch --prune
está a ser fixada, com commit 10a6cc8 , por Tom Miller (tmiller
) (para o git 1.9/2.0, T1 2014):
Quando temos um ramo de rastreamento remoto chamado "Então ... : quando um upstream repo tem uma ramificação ("frotz") com o mesmo nome como um ramo de hierarquia ("frotz/xxx", uma possível ramo de convenção de nomenclatura),frotz/nitfol
"de um busca anterior, e o upstream agora tem um ramo chamado" * * frotz"**,fetch
seria incapaz de remover "frotz/nitfol
"com um"git fetch --prune
"do rio acima.
o git informaria o usuário a usar "git remote prune
" para corrigir o problema.
git remote --prune
foi sucesso (na limpeza remota de seguimento o ramo de seu repo), mas git fetch --prune
estava falhando.
Já não.
Mude a forma como "
fetch --prune
" funciona movendo a operação de poda antes da operação de obtenção.
Desta forma, em vez de avisar o utilizador de conflito, ele corrige automaticamente.
Guarde-o num ficheiro chamado git-rm-ntb
(chame-lhe o que quiser) em PATH
e execute:
git-rm-ntb <remote1:optional> <remote2:optional> ...
clean()
{
REMOTES="$@";
if [ -z "$REMOTES" ]; then
REMOTES=$(git remote);
fi
REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
RBRANCHES=()
while read REMOTE; do
CURRBRANCHES=($(git ls-remote $REMOTE | awk '{print $2}' | grep 'refs/heads/' | sed 's:refs/heads/::'))
RBRANCHES=("${CURRBRANCHES[@]}" "${RBRANCHES[@]}")
done < <(echo "$REMOTES" )
[[ $RBRANCHES ]] || exit
LBRANCHES=($(git branch | sed 's:\*::' | awk '{print $1}'))
for i in "${LBRANCHES[@]}"; do
skip=
for j in "${RBRANCHES[@]}"; do
[[ $i == $j ]] && { skip=1; echo -e "\033[32m Keeping $i \033[0m"; break; }
done
[[ -n $skip ]] || { echo -e "\033[31m $(git branch -D $i) \033[0m"; }
done
}
clean $@