'git pull origin mybranch'使本地mybranch N提交早于起源。为什么?


92

我只是发现一些奇怪的东西git pull,我不明白。

星期五,我在当地一家分公司工作。让我们称之为mybranch。在离开办公室之前,我把它推到原点(这是我的GitHub库)git push origin mybranch

昨天在家,我将pullmybranch带到笔记本电脑上,做了一些编码,然后将所做的更改推回了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 git@github.com:me/project
af8be00..88b0738  mybranch -> origin/mybranch

显然,我的本地仓库缺少一些参考对象,但是那怎么可能呢?我的意思是,pull已经完成了获取,并且除了该分支外,我什么都没做,所以a git fetch origingit fetch origin mybranch应该具有相同的结果?

我应该总是使用git pull origin代替git pull origin branchname吗?

我很困惑。


我也注意到了这一点。一个git push遗嘱似乎也可以解决这个问题(报告“最新”)。
本·詹姆斯

4
git config --get-regexp br.*可以告诉您您的配置是否有一个本地分支正在跟踪另一个分支
VonC

3
您可以输入git config branch.master.remote yourGitHubRepo.gitworkRepo并检查(在下一个git pull origin)状态是否带有“提前”警告吗?
VonC

未设置(空输出)。但git remote show origin向我显示来源指向我的GitHub存储库,所以我猜应该没问题吗?
马赛厄斯2009年

1
仅仅使用git remote(显示GitHub存储库的正确地址)是不够的。为了避免一个“ Your branch is ahead后”的警告信息git pull,你需要先 了一个分支定义远程名。因此,我的建议是:键入git config branch.master.remote yourGitHubRepo.git,然后尝试使用a git pull和a来git status查看问题是否仍然存在。
VonC

Answers:


115

git pullgit fetch在将显式提取的头(如果没有,则将远程分支配置为合并)合并到当前分支之前,使用适当的参数进行调用。

语法:git fetch <repository> <ref>where <ref>只是一个没有冒号的分支名称,是一次抓取,它不会对指定的远程服务器的所有跟踪分支进行标准抓取,而是仅将命名分支抓取到中FETCH_HEAD

更新:对于自1.8.4以来的Git版本,如果有一个远程跟踪分支跟踪您要获取的引用,则该跟踪分支现在将由更新fetch。专门进行此更改是为了避免先前行为引起的混乱。

当您执行时git pull <repository> <ref>FETCH_HEAD如上进行更新,然后合并到您的已签出中,HEAD但是不会更新远程存储库的标准跟踪分支(Git <1.8.4)。这意味着在本地它看起来像您在远程分支的前面,而实际上您是最新的。

我个人总是这样做git fetchgit merge <remote>/<branch>因为在合并之前我会看到有关强制更新的所有警告,并且可以预览要合并的内容。如果我使用git pull的内容比我多了一点,那么我会在git pull没有参数的情况下进行简单处理时,依靠branch.<branch>.remotebranch.<branch>.merge“做正确的事”。


4
+1这确实是一个很好的解释!我知道这种解释隐藏在“ git help fetch”的某个地方,但
无法解决

1
+1。好的帖子,采用类似于gitster.livejournal.com/28309.html
VonC

1
那么,由于获取将更新标准的跟踪分支,因此修复git fetch后是否会出现git pull <repository> <ref>问题?另外,感谢您的回答,这开始变得有意义了:)
Bart Jedrocha'3

1
我就遇到了这个问题太,你需要做的git fetch,然后git merge origin/master master
user1027169

3

什么git remote -v show回报,当谈到起源?

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

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

$ git config branch.master.remote yourGitHubRepo.git

,然后是git pull origin master,其后git status应是,应返回清除状态(不得超前)。
为什么?因为获取获取原始主机(包含在git pull原始主机中)不仅会更新FETCH_HEAD(如Charles Bailey他的回答中所述),而且还会更新还会更新本地Git存储库中的“远程主机分支”。
在这种情况下,您的本地主机似乎不再位于远程主机之前。


我可以用git1.6.5进行测试:

首先,我创建一个工作仓库:

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仓库(作为远程添加)

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' 之前的master 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)

但是,如果我在源于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可能带有“ ahead”警告,但是无论如何git config branch.master.remote yourGitHubRepo.git,即使使用早期版本的Git,显式定义的对象也应该能够解决这一问题。


感谢您抽出宝贵时间对此进行调查。原始远程服务器已经指向我的GitHub存储库。我从GitHub网址克隆了该项目,而我的本地master分支正在跟踪源/主节点。至于mybranch,我很确定我是在origin / mybranch分支上创建的,该分支应该自动跟踪它。但是,也许这是问题所在吗?本地mybranch实际上没有跟踪起源/ mybranch?PS:我正在使用git 1.6.1(通过MacPorts)。
马赛厄斯2009年

是否有一个git命令,让我看看本地分支是否正在跟踪另一个分支?我在手册页中找不到它。
马赛厄斯2009年

您可以查看跟踪了哪些远程分支git remote show origin
泰德·珀西瓦尔

2

您是否小心使用添加所有远程(origin原始克隆随附的除外)git remote add NAME URL?将它们添加到git配置时,我已经看到了此错误。


我在克隆仓库时是这样做的。但是,我没有对每个分支进行此操作。例如,我首先要从原点获取mybranch,然后从git checkout -b mybranch origin/mybranch。根据git-branch的手册页,origin / mybranch是起点,此外,它还声明--track:“ ...如果始终从同一上游分支拉入新分支,请使用此命令,并且如果您不想显式使用“ git pull <存储库> <refspec>”,则此行为是起点是远程分支时的默认行为。
马赛厄斯(Matthias)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.