'git pull origin mybranch'离开本地mybranch N承诺原产地。为什么?

时间:2009-11-16 09:50:36

标签: git version-control git-pull

我刚刚发现git pull有些奇怪,我不明白。

周五,我在一家当地分公司工作。我们称之为mybranch。在离开办公室之前我把它推到了原点(这是我的github回购):git push origin mybranch

昨天在家,我{my}将mybranch添加到我的笔记本电脑上,做了更多编码,然后将我的更改推回到github(原点)。

现在我再次上班,并试图将改变从昨天拉到我的工作机器上(周末我的工作地点当地回购没有改变):

pull

导致快速合并,这很好。然后我做了一个git pull origin mybranch ,它说:

git status

咦?如果我周末没有触摸它,只是从原点拉出来,它怎么能提前6次?所以我跑了一个# On branch mybranch # Your branch is ahead of 'origin/mybranch' by 6 commits. # nothing to commit (working directory clean) ,差异就是我刚刚从远程拉出的6个变化。

我只能通过运行git diff origin/mybranch

来“解决”这个问题
git fetch origin

显然,我的本地仓库缺少一些参考对象,但怎么会这样呢?我的意思是,一个pull已经进行了一次获取,除了那个分支之外我没有处理任何事情,所以From git@github.com:me/project af8be00..88b0738 mybranch -> origin/mybranch git fetch origin应该有相同的结果吗?

我应该始终使用git fetch origin mybranch代替git pull origin吗?

我很困惑。

3 个答案:

答案 0 :(得分: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&lt; ; 1.8.4)。这意味着本地看起来就像你在远程分支之前,而实际上你是最新的。

我个人总是git fetch后跟git merge <remote>/<branch>,因为在合并之前我会看到有关强制更新的任何警告,我可以预览我正在合并的内容。如果我使用{{1比我更多,我会在大多数情况下做一个没有参数的简单git pull,依靠git pullbranch.<branch>.remote“做正确的事情”。

答案 1 :(得分:3)

git remote -v show在原点时会返回什么?

如果origin指向github,则状态应该是最新的,而不是在任何远程repo之前。至少,我使用Git1.6.5进行快速测试。

无论如何,要避免这种情况,请明确定义master分支的远程仓库:

$ git config branch.master.remote yourGitHubRepo.git

然后git pull origin master,然后是git status应该返回一个干净的状态(没有提前)。
为什么?因为get fetch origin master(包含在git pull origin master中)不仅会更新FETCH_HEADCharles Bailey中解释为his 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"

我通过创建一个裸仓库来模拟一个GitHub仓库(一个可以从任何地方接收推送的仓库)

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

我在我的工作回购中添加了一个modif,我推送到github repo(作为远程添加)

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

我创建了一个家庭仓库,克隆了GitHub,我在其中进行了一些修改,推送到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 status确实提到了'origin'之前的主geing:

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)

但是如果我在一个repo中重复序列,它有一个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指向github,则status对于git1.6.5会很干净。
对于早期的git,它可能会有一个“提前”警告,但无论如何,明确定义的git config branch.master.remote yourGitHubRepo.git应该能够处理它,即使是早期版本的Git。

答案 2 :(得分:2)

您是否小心使用origin添加所有遥控器(原始克隆附带的git remote add NAME URL除外)?我刚刚将它们添加到git配置中时看到了这个错误。