Perché posso effettuare il checkout di un ramo che è stato rimosso su GitHub?


26

Nel nostro repository GitHub, un collega ha rimosso un ramo chiamato release. Ma quando corro git checkout releaselocalmente, ottengo sempre il ramo rimosso release. Lo stesso, anche quando ho verificato un altro ramo, ho eliminato il releaseramo con git branch -D releaseed eseguito di nuovo git checkout release.

C'è qualcosa da correggere nel repository GitHub o devo correggere qualcosa localmente?


1
Cosa fa l' git branch --remoteoutput, dopo l'esecuzione git fetch? Potrebbe essere necessario potare git fetch -pper dimenticare i rami remoti eliminati.
Stephen Kitt,

2
Se quel ramo è stato mai inviato a GitHub, e dopo lo hai fatto, allora hai anche una copia del ramo. Ogni repository git è completo in sé e per sé, a meno che tu non abbia usato un clone superficiale o qualcosa del genere.
muru,

@StephenKitt: grazie. git branch --remoteuscita origin/release. Intendi eseguire git fetch -psenza ulteriori argomenti e eliminerà tutti i rami remoti eliminati?
Tim

1
Sì, git fetch -psenza argomenti aggiuntivi potremo eliminare tutti i rami remoti eliminati.
Stephen Kitt,

1
Benvenuti nel mondo del controllo della versione distribuita!
Chrylis

Risposte:


24

Dopo aver eliminato un ramo sul lato remoto potresti ancora vedere questo ramo remoto precedentemente recuperato localmente, vedi:

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

Hai rimosso solo il "rilascio" ma non i "telecomandi / origine / rilascio". Eliminalo in questo modo:

$ git branch -rd origin/release

Oppure rimuovi tutti i rami recuperati che non esistono più sul lato remoto:

$ git remote prune origin 

Grazie. In git branch -rd origin/release, cosa -rsignifica? Non -dsignifica lo stesso che -D? Può git branch -rd origin/releaseessere sostituito con git branch -d remotes/origin/release?
Tim

@Tim: dal manuale; -r: List or delete (if used with -d) the remote-tracking branches.; MrGreen:Shortcut for --delete --force.
crochet

Grazie. Può git branch -rd origin/releaseessere sostituito con git branch -d remotes/origin/release?
Tim

@Tim no si -rriferisce a filiali remote , è necessario. Le filiali locali e remote sono memorizzate in diverse directory, confronta ls -l .git/refs/headse ls -l .git/refs/remotes. Potresti anche avere un ramo locale chiamato remotes/origin/releaseche sarebbe eliminato senza -r. Questo può sembrare confuso, ma potresti semplicemente giocare, creare rami con nomi strani e guardare come appare .git/.
rudimeier,

15

Quando i rami vengono eliminati in remoto, è necessario potare il repository locale - il modo più semplice per farlo è con

git fetch -p

Ciò aggiornerà il repository locale con tutte le modifiche apportate al repository remoto, ma senza aggiornare le filiali locali. Dopo aver eseguito questo,

git branch --remote

non mostrerà più il ramo remoto cancellato.

i repository git sono completi, sia sul proprio sistema che sul server. Quindi quando si clona per la prima volta un repository, si ottiene una copia completa e il proprio git locale "conosce" tutti i rami remoti e i rami locali. Queste informazioni non vengono sincronizzate automaticamente, quindi quando il collega ha eliminato il releaseramo sul server, il repository git locale non ha perso la nozione di releaseramo remoto . Sincronizzazione con gli git fetchaggiornamenti di tutte le informazioni locali sulle filiali remote in modo che corrispondano allo stato sul server (in senso stretto, repository remoto, ovunque si trovi), ma senza eliminare alcuna informazione locale sulle filiali remote. La potatura con git fetch -p(o git fetch --prune, o git remote prune) rimuove le informazioni locali sui rami remoti che sono stati eliminati.


Grazie. "aggiorna il tuo repository locale con tutte le modifiche apportate al repository remoto, ma senza aggiornare nessuna delle filiali locali". Che aggiornamento è quello, dato che non è l'aggiornamento delle mie filiali locali?
Tim

Sono tutti gli aggiornamenti remoti. Il tuo repository git locale distingue i tuoi rami locali e quelli remoti, ma i rami remoti non sono magicamente sincronizzati con il server - esistono anche localmente (come in, memorizzati nel tuo repository git locale). Il recupero sincronizza il repository locale con il repository remoto e aggiorna lo stato delle filiali remote; per impostazione predefinita i rami remoti eliminati non vengono rimossi dalle informazioni locali sui rami remoti, -p( --prune) impone che.
Stephen Kitt,

Grazie. Perché non l'eliminazione del releaseramo dalla git branch -D releaseprima git checkout releasemarca git checkout releasefermata ricevendo il releaseramo?
Tim

1
Perché git checkout releasericrea automaticamente un ramo se esiste un ramo remoto con quel nome.
Stephen Kitt,

Per "ramo remoto", intendi un ramo nel mio repository locale o nel repository Github? Se precedente, git branch -D releaseha già eliminato il releaseramo nel mio repository locale; In quest'ultimo caso, un collega ha eliminato il releaseramo su GitHub; Quindi non sono ancora sicuro del perché "ricrea automaticamente un ramo se esiste un ramo remoto con quel nome"?
Tim

3

Tim: Git è distribuito VCS, quindi quando cloni un repository da remoto a quello locale clona tutto (cronologia). Quindi, quando hai clonato il tuo repository, aveva un ramo chiamato release. Poiché il tuo collega ha eliminato il ramo di rilascio in remoto, fino a quando non esegui una potatura git fetch -po elimini quel ramo in modo esplicito, il tuo locale avrà quel ramo.


3
In che modo questa risposta differisce dalle risposte già presenti?
Stephen Rauch,

1

Forse un po 'tangenziale, ma la prospettiva di questo sito potrebbe aiutare a comprendere l'argomento generale dell'eliminazione dei rami:

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

Vi è una sovrapposizione con alcuni di quelli che sono già stati discussi qui, ma l'attenzione è rivolta alle pulizie: l'eliminazione di filiali, remote e locali, che non sono più necessarie in un ambiente collaborativo. In particolare il git branch --mergedcomando identifica i rami che possono essere eliminati in modo sicuro a causa della fusione con la linea principale (o qualsiasi ramo a cui tieni). Se stai collaborando, alcuni mini script più elaborati come questo presenteranno le cose in un formato piacevole e digeribile con date e autori.

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

(Purtroppo "bello, digeribile" non si applica alla formattazione degli script stessi.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.