Come faccio a "git fetch" e "git merge" da un ramo di monitoraggio remoto (come "git pull")


111

Ho impostato alcuni rami di tracciamento remoto in git, ma non riesco mai a unirli nel ramo locale una volta che li ho aggiornati con "git fetch".

Ad esempio, supponiamo che io abbia un ramo remoto chiamato "an-other-branch". L'ho impostato localmente come ramo di monitoraggio utilizzando

git branch --track an-other-branch origin/an-other-branch

Fin qui tutto bene. Ma se quel ramo viene aggiornato (di solito da me spostando la macchina e effettuando il commit da quella macchina), e voglio aggiornarlo sulla macchina originale, sto riscontrando problemi con il recupero / unione:

git fetch origin an-other-branch
git merge origin/an-other-branch

Ogni volta che lo faccio, ricevo un messaggio "Già aggiornato" e nulla viene unito.

Tuttavia, a

git pull origin an-other-branch

lo aggiorna sempre come ti aspetteresti.

Inoltre, eseguendo git diff

git diff origin/an-other-branch

mostra che ci sono differenze, quindi penso di avere la mia sintassi sbagliata.

Che cosa sto facendo di sbagliato?

EDIT [2010-04-09]: Ho controllato un paio di volte, e sicuramente non sono su un ramo diverso. Il mio "git fetch" seguito da "git merge" (come mostrato sopra) dovrebbe fare esattamente la stessa cosa di un git pull? Otterrò un flusso di lavoro che mostra i risultati di uno stato git ecc.

Risposte:


170

Non prendi un ramo, prendi un intero telecomando:

git fetch origin
git merge origin/an-other-branch

8
Maggiori dettagli: git fetch origin an-other-branchmemorizza il suggerimento recuperato in FETCH_HEAD, ma non origin/an-other-branch(cioè il solito 'ramo di monitoraggio remoto'). Quindi, si potrebbe fare git fetch origin an-other-branch && git merge FETCH_HEAD, ma farlo come dice @Gareth è meglio (o semplicemente usare git pull ).
Chris Johnsen

quindi se l'origine ha 1000 rami, saresti un ramo remoto per tutti loro?
Gauthier

4
Sicuro. Se ho aggiunto un repository remoto con 1000 rami al mio e chiedo quali rami ha il telecomando, è dannatamente meglio darmi tutti i 1000
Gareth

si git merge origin/an-other-branchfonderà origin/an-other-branchin tutti i rami locali che sono impostati per seguirlo? come posso unirmi in una sola filiale locale?
anfibio

1
Quindi cosa fa git pull(senza argomenti) - quale ramo unisce? Unisce il ramo di monitoraggio remoto corrispondente al ramo corrente ?
The Red Pea

69

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:

  1. Il ramo nel repository remoto: refs/heads/branchBall'interno dell'altro repository
  2. Il tuo ramo di monitoraggio remoto : refs/remotes/remoteR/branchBnel tuo repository
  3. 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

    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.


1
Sei consapevole che il tuo collegamento a Git Internals è un collegamento alla stessa domanda?
Shahbaz

9

Sei sicuro di essere in locale an-other-branchquando ti unisci?

git fetch origin an-other-branch
git checkout an-other-branch
git merge origin/an-other-branch

L' altra spiegazione :

tutte le modifiche dal ramo che stai tentando di unire sono già state unite al ramo in cui ti trovi attualmente.
Più specificamente significa che il ramo che stai tentando di unire è un genitore del tuo ramo corrente

se sei in vantaggio rispetto al repository remoto di un commit, è il repository remoto che non è aggiornato, non tu.

Ma nel tuo caso, se git pullfunziona, significa semplicemente che non sei sul ramo giusto.


3

Git pull è in realtà uno strumento combinato: esegue git fetch (ottenendo le modifiche) e git merge (unendole alla copia corrente)

Sei sicuro di essere nel ramo corretto?


Penso che l'OP sia in diff. ramo, succede a me.
Chaklader Asfak Arefe

1

questi sono i comandi:

git fetch origin
git merge origin/somebranch somebranch

se lo fai sulla seconda riga:

git merge origin somebranch

proverà a fondere il master locale nel tuo ramo corrente.

La domanda, per come l'ho capito, è stata che hai già recuperato localmente e vuoi ora unire il tuo ramo all'ultimo dello stesso ramo.

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.