Selezione di un solo ramo: fetch/ merge vs. pull
Le persone spesso consigliano di separare il "recupero" dalla "fusione". Dicono invece di questo:
git pull remoteR branchB
Fai questo:
git fetch remoteR
git merge remoteR branchB
Quello che non menzionano è che un tale comando fetch recupererà effettivamente tutti i rami dal repository remoto, che non è ciò che fa quel comando pull. Se hai migliaia di rami nel repository remoto, ma non vuoi vederli tutti, puoi eseguire questo oscuro comando:
git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
git branch -a # to verify
git branch -t branchB remoteR/branchB
Naturalmente, è incredibilmente difficile da ricordare, quindi se vuoi davvero evitare di recuperare tutti i rami, è meglio modificare il tuo .git/configcome descritto in ProGit.
Eh?
La migliore spiegazione di tutto questo è nel Capitolo 9-5 di ProGit, Git Internals - The Refspec ( o tramite github ). È incredibilmente difficile da trovare tramite Google.
Per prima cosa, dobbiamo chiarire un po 'di terminologia. Per il monitoraggio remoto dei rami, ci sono in genere 3 diversi rami di cui essere a conoscenza:
- Il ramo nel repository remoto:
refs/heads/branchBall'interno dell'altro repository
- Il tuo ramo di monitoraggio remoto :
refs/remotes/remoteR/branchBnel tuo repository
- Il tuo ramo:
refs/heads/branchBall'interno del tuo repo
I rami di monitoraggio remoto (in refs/remotes) sono di sola lettura. Non li modifichi direttamente. Si modifica il proprio ramo e quindi si esegue il push al ramo corrispondente nel repository remoto. Il risultato non si riflette nel tuo refs/remotesfino a dopo un appropriato pull o fetch. Questa distinzione è stata difficile per me da capire dalle pagine man di git, principalmente perché refs/heads/branchBsi dice che il ramo locale ( ) "traccia" il ramo di tracciamento remoto quando viene .git/configdefinito branch.branchB.remote = remoteR.
Pensa a "refs" come a puntatori C ++. Fisicamente, sono file contenenti SHA-digest, ma fondamentalmente sono solo puntatori nell'albero dei commit. git fetchaggiungerà molti nodi al tuo albero di commit, ma il modo in cui git decide quali puntatori spostare è un po 'complicato.
Come accennato in un'altra risposta , nessuno dei due
git pull remoteR branchB
né
git fetch remoteR branchB
si muoverebbe refs/remotes/branches/branchB, e quest'ultimo di certo non può muoversi refs/heads/branchB. Tuttavia, entrambi si muovono FETCH_HEAD. (Puoi vedere catuno qualsiasi di questi file all'interno .git/per vedere quando cambiano.) E git mergefarà riferimento a FETCH_HEAD, durante l'impostazione MERGE_ORIG, ecc.
git fetch origin an-other-branchmemorizza il suggerimento recuperato inFETCH_HEAD, ma nonorigin/an-other-branch(cioè il solito 'ramo di monitoraggio remoto'). Quindi, si potrebbe faregit fetch origin an-other-branch && git merge FETCH_HEAD, ma farlo come dice @Gareth è meglio (o semplicemente usare git pull ).