2009-11-16 15 views
91

我剛剛觀察到一些關於git pull的奇怪現象,我不明白。'git pull origin mybranch'留下本地mybranch N提前提交。爲什麼?

週五,我在當地的一家分店工作。我們稱之爲mybranch。離開辦公室前,我把它推到原點(這是我的github回購):git push origin mybranch

昨天在家,我 ed mybranch到我的筆記本電腦,做了一些更多的編碼,然後把我的變化推回到github(原產地)。

現在,我在工作中我再次,並試圖拉從昨天的更改我的工作機(我沒有改變過週末在我工作的地方的本地倉庫的任何東西):

git pull origin mybranch 

那導致了快速前向合併,這很好。然後我做了git status,它說:

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

咦?如果我在週末沒有觸及它,它會如何提前完成6,並且剛從原點拉出來?所以我跑了git diff origin/mybranch,差異恰恰是我剛從遙控器拉出來的6個變化。

我只能「修理」這個運行git fetch origin

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

很顯然,我的本地回購是缺少一定的參考對象,但是這怎麼可能呢?我的意思是,拉已經提取了,除了那個分支我什麼都沒有做,所以git fetch origingit fetch origin mybranch應該有相同的結果?

我是否應該始終使用git pull origin而不是git pull origin branchname

我很困惑。

+0

我也注意到了這一點;一個'git push'似乎也能解決它(報告「全部是最新的」)。 – 2009-11-16 09:54:49

+4

'git config --get-regexp br。*'可以告訴你你的配置是否有本地分支正在跟蹤另一個分支 – VonC 2009-11-16 15:08:02

+3

你可以在你的workRepo中輸入'git config branch.master.remote yourGitHubRepo.git'並檢查如果狀態保持「提前」警告,下一個'git pull origin')? – VonC 2009-11-16 15:09:16

回答

113

git pull在將顯式提取的頭合併(或者如果遠程分支都沒有配置爲合併)之前將合適的參數調用git fetch到當前分支中。

語法:git fetch <repository> <ref>其中<ref>只是一個沒有冒號的分支名稱,它是一個「一次性」提取,它不會對指定遠程的所有跟蹤分支執行標準提取,而是僅將命名分支提取到FETCH_HEAD

更新:自1.8.4的版本的Git,如果有一個遠程跟蹤分支,它會跟蹤你問那麼來獲取跟蹤分行將現在fetch更新裁判。這一改變是爲了避免以前的行爲造成的混亂。

當您執行git pull <repository> <ref>FETCH_HEAD如上更新,然後合併到簽出HEAD但沒有遠程倉庫的標準跟蹤分支將被更新(GIT < 1.8.4)。這意味着在本地它看起來像就像你在遠程分支之前一樣,而實際上你已經與它保持同步了。

個人而言,我總是做git fetch其次git merge <remote>/<branch>因爲我能看到關於強制更新任何警告之前,我合併了,我可以預覽我在我的合併。如果我用git pull一點比我還多,我會大多數時候做一個沒有參數的普通git pull,依靠branch.<branch>.remotebranch.<branch>.merge來「做正確的事情」。

+4

+1這真是一個很好的解釋!我知道這個解釋隱藏在'git help fetch'裏面的某個地方,但是無法將它解決...... – 2009-11-16 19:22:54

+1

+1。好帖子,採用類似於http://gitster.livejournal.com/28309.html的方法 – VonC 2009-11-16 22:40:44

+1

因此,如果'git pull ''修復了問題,因爲提取會更新標準跟蹤分支?此外,感謝這個答案,開始有意義:) – 2012-03-02 02:20:28

3

git remote -v show什麼是原產地?

如果origin指向github,狀態應該是最新的,而不是任何遠程repo。至少,使用Git1.6.5進行快速測試。

總之,要避免這種情況,定義明確主分支的遠程回購:

$ git config branch.master.remote yourGitHubRepo.git 

然後git pull origin master,隨後git status應該返回一個乾淨的狀態(無提示)。
爲什麼?因爲獲取獲取原點主(包括在git pull原點主)不會更新FETCH_HEAD(因爲Charles Baileyhis answer中解釋),但它會更新本地Git存儲庫中的「遠程主分支」。
在這種情況下,您的本地主人似乎不再是遠程主人的「前面」。


我可以測試這個,用git1.6。5:

首先創建一個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" 

我通過創建一個裸回購(其中之一可以從任何地方接收推送)

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

模擬GitHub庫我一個修飾的添加我的工作回購,我推github回購(作爲遠程添加)

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 

我創建了一個家庭回購,克隆o ˚FGitHub上,我在其中做一些修改,推到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 

我再克隆workrepo的第一個實驗

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

在這種回購,git的狀態確實提到主geing提前'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) 

不過,這只是origin不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) 

但是,如果我重複序列,其中有一個原點github上(或無產地可言,只需要一個遙控「GitHub的」定義),狀態是乾淨的回購:

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) 

如果我有隻有origin指向githubstatus對git1.6.5來說是乾淨的。
對於早期的git,可能會提前發出警告,但無論如何,明確定義的git config branch.master.remote yourGitHubRepo.git應該能夠處理該問題,即使是早期版本的Git也是如此。

+0

感謝您花時間查看此信息。遠程的來源已經指向我的GitHub回購。我從GitHub url克隆了該項目,我的本地主分支正在跟蹤origin/master。至於mybranch,我很確定我從origin/mybranch分支創建了它,它應該自動跟蹤它。但是,也許這是問題所在?當地的mybranch實際上並不追蹤origin/mybranch? PS:我使用git 1.6.1(通過MacPorts)。 – Matthias 2009-11-16 14:22:39

+0

有沒有讓我看看本地分支是否跟蹤另一個分支的git命令?我無法在手冊頁中找到它。 – Matthias 2009-11-16 14:23:40

+0

你可以看到使用'git remote show origin'跟蹤了哪些遠程分支。 – 2011-12-01 21:57:52

2

您是否小心地使用git remote add NAME URL來添加您的所有遠程設備(origin,附帶您的原始克隆除外)?當他們剛被添加到git配置中時,我看到了這個bug。

+0

我在克隆回購時做到了這一點。但是,我沒有在每個分支上做這個。對於例如mybranch我會先從原點獲取,然後'git checkout -b mybranch origin/mybranch'。根據git-branch的手冊頁,origin/mybranch是起點,此外,它聲明爲--track:「...如果您總是從同一上游分支拉入新分支,如果你不想明確地使用「git pull 」,當起始點是遠程分支時,這種行爲是缺省的。「 – Matthias 2009-11-16 18:12:18

相關問題