'git pull origin mybranch" les feuilles locales mybranch N engage en avant de l'origine. Pourquoi?

je viens d'observer quelque chose d'étrange dans git pull , que je ne comprends pas.

le vendredi, j'ai travaillé sur une succursale locale. appelons-le mybranch . Avant de quitter le bureau je l'ai poussé à l'origine (qui est mon github repo): git push origin mybranch .

hier à la maison, je pull ed mybranch à mon ordinateur portable, fait plus de codage, et puis repoussé mes changements de nouveau à github (origine).

maintenant je suis de nouveau au travail, et essayé de tirer les changements d'hier à ma machine de travail (je n'ai pas changé quoi que ce soit dans la déclaration locale de mon lieu de travail au cours du week-end):

git pull origin mybranch

qui a causé une fusion rapide vers l'avant, ce qui est bien. J'ai alors fait un git status , et il a dit:

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

Hein? Comment peut-il être 6 engage à l'avance quand je n'ai même pas touché au cours du week-end, et juste tiré d'origine? Donc j'ai lancé un git diff origin/mybranch et les diffs étaient exactement les 6 changements que j'ai juste tiré à partir de la télécommande.

Je ne pouvais "corriger" cela qu'en exécutant git fetch origin :

From [email protected]:me/project
af8be00..88b0738  mybranch -> origin/mybranch

apparemment, mon agent local manquait des objets de référence, mais comment est-ce possible? Je veux dire, une traction fait déjà un fetch, et je n'ai pas travaillé sur quoi que ce soit sauf cette branche, donc un git fetch origin et git fetch origin mybranch devrait avoir le même résultat?

devrais-je toujours utiliser git pull origin au lieu de git pull origin branchname ?

je suis confus.

91
demandé sur Matthias 2009-11-16 12:50:35
la source

3 ответов

git pull appelle git fetch avec les paramètres appropriés avant de fusionner les têtes explicitement récupérées (ou si aucune n'est configurée pour fusionner la branche distante) dans la branche courante.

la syntaxe: git fetch <repository> <ref><ref> est juste un nom de branche sans deux points est un fetch 'one shot' qui ne fait pas un fetch standard de toutes les branches tracées de la télécommande spécifiée mais va chercher juste la branche nommée dans FETCH_HEAD .

mise à Jour: pour Git les versions depuis la version 1.8.4, si il y a un suivi à distance de la branche qui suit la ref que vous avez demandé à récupérer, puis le suivi de la branche sera désormais mise à jour par fetch . Ce changement a été fait spécialement pour éviter la confusion que le comportement précédent causé.

quand vous effectuez git pull <repository> <ref> , FETCH_HEAD est mis à jour comme ci-dessus, puis fusionné dans votre coché HEAD mais aucun de la norme les branches de suivi pour le dépôt distant seront mises à jour (Git <1.8.4). Cela signifie que, localement, il regarde comme vous êtes en avance de la branche distante, alors qu'en fait vous êtes à jour avec elle.

personnellement je fais toujours git fetch suivi de git merge <remote>/<branch> parce que je peux voir tous les avertissements sur les mises à jour forcées avant que je fusionne, et je peux prévisualiser ce que je fusionne. Si j'utilisais git pull un peu plus que je ne le fais, je ferais une git pull sans paramètres la plupart du temps, s'appuyant sur branch.<branch>.remote et branch.<branch>.merge pour" faire la bonne chose".

113
répondu CB Bailey 2013-11-08 12:27:03
la source

Quoi git remote -v show retourne quand il s'agit à l'origine?

si l'origine pointe vers github, le statut doit être à jour, et non en avance sur tout repos à distance. Du moins, avec le Git1.6.5 j'utilise pour un test rapide.

de toute façon, pour éviter cela, définissez explicitement la prise en charge à distance de master branch:

$ git config branch.master.remote yourGitHubRepo.git

puis un git pull origin master , suivi d'un git status devrait retourner un statut propre (pas d'en avant).

Pourquoi? parce que le Get fetch origin master (inclus dans le git pull origin master) ne se contenterait pas de mettre à jour FETCH_HEAD (comme Charles Bailey explique dans sa réponse ), mais il serait également mettre à jour la "branche master distante" dans votre dépôt Git local.

Dans ce cas, votre maître local ne semble plus être "en avance" sur le maître éloigné.


je peux tester ceci, avec un git1.6.5:

D'abord je crée 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"

je simule un dépôt GitHub par la création d'un nu de pensions de titres (dont une pouvant recevoir des push à partir de n'importe où)

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

j'ajoute un modif à mon working repo, que je pousse sur GitHub repo (ajouté à distance)

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

je crée un home repo, cloné de GitHub, dans lequel je fais un quelques modifications, poussé à 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

je clone ensuite workrepo pour une première expérience

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(-)

dans ce rapport, le statut git mentionne maître geing avant de 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)

mais qui est seulement origin n'est pas 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)

Mais si je répète la séquence dans une pension qui a une origine à github (ou pas d'origine du tout, juste une distance 'github" défini), le statut est propre:

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)

si j'avais seulement origin pointant sur github , status serait propre pour git1.6.5.

Il peut s'agir d'un avertissement "ahead" pour Git plus tôt, mais quoi qu'il en soit, un git config branch.master.remote yourGitHubRepo.git défini explicitement devrait être en mesure de s'occuper de cela, même avec les premières versions de Git.

3
répondu VonC 2017-05-23 14:54:27
la source

faites-vous attention à ajouter toute votre télécommande (sauf origin qui vient avec votre clone original) en utilisant git remote add NAME URL ? J'ai vu ce bug quand ils ont été ajoutés à la configuration de git.

2
répondu Pat Notz 2009-11-16 17:14:15
la source

Autres questions sur git version-control git-pull