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/config
come 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/branchB
all'interno dell'altro repository
- Il tuo ramo di monitoraggio remoto :
refs/remotes/remoteR/branchB
nel tuo repository
- Il tuo ramo:
refs/heads/branchB
all'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/remotes
fino a dopo un appropriato pull o fetch. Questa distinzione è stata difficile per me da capire dalle pagine man di git, principalmente perché refs/heads/branchB
si dice che il ramo locale ( ) "traccia" il ramo di tracciamento remoto quando viene .git/config
definito 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 fetch
aggiungerà 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 cat
uno qualsiasi di questi file all'interno .git/
per vedere quando cambiano.) E git merge
farà riferimento a FETCH_HEAD
, durante l'impostazione MERGE_ORIG
, ecc.
git fetch origin an-other-branch
memorizza 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 ).