'Git origine tirare mybranch' lascia mybranch locale N impegna avanti di origine. Perché?

StackOverflow https://stackoverflow.com/questions/1741143

  •  20-09-2019
  •  | 
  •  

Domanda

Ho appena notato qualcosa di strano in git pull, che non capisco.

Il Venerdì, ho lavorato su una filiale locale. chiamiamolo mybranch. Prima di lasciare l'ufficio ho spinto per provenienza (che è il mio github repo):. git push origin mybranch

Ieri a casa, ho pulled mybranch al mio portatile, fatto un po 'di più la codifica, e poi spinto il mio modifiche al github (origine).

Ora sono di nuovo al lavoro, e ho cercato di tirare le modifiche di ieri alla mia macchina di lavoro (Non ho cambiato nulla nella repo locale del mio posto di lavoro durante il fine settimana):

git pull origin mybranch

che ha causato un avanzamento rapido si fondono, che va bene. poi ho fatto un git status, e ha detto:

# On branch mybranch
# Your branch is ahead of 'origin/mybranch' by 6 commits.
#
nothing to commit (working directory clean)

Eh? Come può essere 6 impegna i avanti quando non ho neanche toccarlo durante il fine settimana, e solo tirato di origine? Così ho fatto funzionare un git diff origin/mybranch e le diff erano esattamente le 6 modifiche che ho appena tirato da remoto.

ho potuto solo "fissare" questo git fetch origin eseguendo:

From git@github.com:me/project
af8be00..88b0738  mybranch -> origin/mybranch

A quanto pare, il mio repo locale mancava alcuni oggetti di riferimento, ma come può essere? Voglio dire, un pull fa un recuperare già, e non ho lavorare su nulla, tranne quel ramo, quindi un git fetch origin e git fetch origin mybranch dovrebbero avere lo stesso risultato?

Devo sempre usare git pull origin invece di git pull origin branchname?

Sono confuso.

È stato utile?

Soluzione

git pull chiama git fetch con i parametri appropriati prima fusione delle teste esplicitamente recuperati (o se nessuna ramo remoto configurato per unione) nel ramo corrente.

La sintassi: git fetch <repository> <ref> dove <ref> è solo un nome ramo senza i due punti è un 'one shot' recuperare che non fa uno standard recuperare di tutti i rami tracciati del remoto specificato ma invece recupera solo il ramo chiamato in FETCH_HEAD .

Aggiornamento: per le versioni Git dal 1.8.4, se v'è una filiale di monitoraggio remoto che segue l'arbitro che hai chiesto di andare a prendere poi il ramo di monitoraggio sarà ora aggiornato da fetch. Questo cambiamento è stato fatto appositamente per evitare la confusione che il comportamento precedente causato.

Quando si esegue git pull <repository> <ref>, FETCH_HEAD viene aggiornato come sopra, poi fusa nella vostra HEAD verificato ma nessuno dei rami di tracciamento standard per il repository remoto sarà aggiornato (Git <1.8.4). Ciò significa che a livello locale è guarda come si sta davanti del ramo a distanza, mentre in realtà si sono fino ad oggi con esso.

Personalmente ho sempre fare git fetch seguito da git merge <remote>/<branch> perché riesco a vedere eventuali avvisi di aggiornamenti forzati prima di unire, e posso vedere in anteprima quello che sto fondendo. Se ho usato git pull un po 'più di me, lo farei un git pull pianura senza parametri maggior parte del tempo, basandosi su branch.<branch>.remote e branch.<branch>.merge a 'fare la cosa giusta'.

Altri suggerimenti

Che cosa significa rendimenti git remote -v show quando si tratta di origine?

Se punti di origine a GitHub, lo stato dovrebbe essere aggiornato, e non prima di qualsiasi repo remoto. Almeno, con il Git1.6.5 che sto usando per un test rapido.

In ogni caso, per evitare questo, definire in modo esplicito il repo remoto del ramo principale:

$ git config branch.master.remote yourGitHubRepo.git

poi un git pull origin master, seguito da un git status deve restituire uno stato pulito (non avanti).
Perché? perché l'ottenere prendere maestro origine (incluso nel master origine git pull) non solo aggiornare FETCH_HEAD (come Charles Bailey spiega in la sua risposta ), ma sarebbe anche aggiornare il "branch master a distanza" all'interno della vostra repository Git locale.
In questo caso, il tuo padrone locale non sembra più essere "avanti" del maestro a distanza.


posso verificare questa, con un git1.6.5:

Per prima cosa creo un workrepo:

PS D:\git\tests> cd pullahead
PS D:\git\tests\pullahead> git init workrepo
Initialized empty Git repository in D:/git/tests/pullahead/workrepo/.git/
PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo firstContent > afile.txt
PS D:\git\tests\pullahead\workrepo> git add -A 
PS D:\git\tests\pullahead\workrepo> git commit -m "first commit"

I simulare un repo GitHub con la creazione di un pronti contro termine nudo (uno che può ricevere spinta da qualsiasi luogo)

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone --bare workrepo github

aggiungo un modif al mio repo di lavoro, che mi spingono a github pronti contro termine (aggiunto come un telecomando)

PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo aModif >> afile.txt
PS D:\git\tests\pullahead\workrepo> git ci -a -m "a modif to send to github"
PS D:\git\tests\pullahead\workrepo> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo> git push github

creo un repo casa, clonato di GitHub, in cui faccio un paio di modifiche, spinto al GitHub:

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone github homerepo
PS D:\git\tests\pullahead> cd homerepo
PS D:\git\tests\pullahead\homerepo> type afile.txt
firstContent
aModif

PS D:\git\tests\pullahead\homerepo> echo aHomeModif1  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a first home modif"
PS D:\git\tests\pullahead\homerepo> echo aHomeModif2  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a second home modif"
PS D:\git\tests\pullahead\homerepo> git push github

Ho poi clonare workrepo per un primo esperimento

PS D:\git\tests\pullahead\workrepo4> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo2
Initialized empty Git repository in D:/git/tests/pullahead/workrepo2/.git/
PS D:\git\tests\pullahead> cd workrepo2
PS D:\git\tests\pullahead\workrepo2> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo2> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)

In questo repo, git status fa menzione padrone geing davanti a 'origin':

PS D:\git\tests\pullahead\workrepo5> git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)

Ma questa è solo origin non è GitHub:

PS D:\git\tests\pullahead\workrepo2> git remote -v show
github  d:/git/tests/pullahead/github (fetch)
github  d:/git/tests/pullahead/github (push)
origin  D:/git/tests/pullahead/workrepo (fetch)
origin  D:/git/tests/pullahead/workrepo (push)

Ma se ripeto la sequenza in un repo, che ha un'origine a github (o nessuna origine a tutti, solo un 'github' a distanza definita), lo stato è pulito:

PS D:\git\tests\pullahead\workrepo2> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo4
PS D:\git\tests\pullahead> cd workrepo4
PS D:\git\tests\pullahead\workrepo4> git remote rm origin
PS D:\git\tests\pullahead\workrepo4> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo4> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)
PS D:\git\tests\pullahead\workrepo4> git status
# On branch master
nothing to commit (working directory clean)

Se avessi origin solo puntando sulla github, status sarebbe pulita per git1.6.5.
Può essere un 'avanti' avvertimento per precedenza git, ma in ogni caso, un git config branch.master.remote yourGitHubRepo.git definito esplicitamente dovrebbe essere in grado di prendersi cura di che, anche con le prime versioni di Git.

Sei attento a aggiungere tutti telecomando (tranne origin che viene fornito con il vostro clone originale) utilizzando git remote add NAME URL? Ho visto questo bug quando hanno appena stato aggiunto alla configurazione git.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top