'git pull origin mybranch'离开本地mybranch N提前提交。 Why?

我只是观察到一些关于git pull奇怪事情,我不明白。

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

昨天在家里,我pull 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 git@github.com:me/project
af8be00..88b0738  mybranch -> origin/mybranch

显然,我的本地回购是缺少一些参考对象,但怎么可能呢? 我的意思是,拉已经做了一个抓取,并且除了那个分支之外我没有做任何工作,所以git fetch origingit fetch origin mybranch应该有相同的结果?

我应该总是使用git pull origin而不是git pull origin branchname

我很困惑。


在合并明确提取的头部之前(或者如果远程分支没有配置为合并), 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了更多比起我,我会在大多数情况下依赖branch.<branch>.remote来完成一个没有参数的简单的git pull branch.<branch>.remotebranch.<branch>.merge为'做正确的事情'。


什么是git remote -v show返回来源?

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

无论如何,要避免这种情况,请明确定义主分支的远程回购:

$ git config branch.master.remote yourGitHubRepo.git

那么一个git pull origin master ,随后一个git status应该返回一个干净的状态(不提前)。
为什么? 因为get fetch origin master(包含在git pull origin master中)不会更新FETCH_HEAD (正如Charles Bailey在他的回答中所解释的),但它也会更新本地Git存储库中的“远程主分支”。
在这种情况下,您的本地主人似乎不再是远在主人的“前面”。


我可以用git1.6.5来测试这个:

首先我创建一个workrepo:

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

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

PS D:gittestspullaheadworkrepo> cd ..
PS D:gittestspullahead> git clone --bare workrepo github

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

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

我创建了一个家庭回购,克隆了GitHub,我在其中进行了一些修改,推送到GitHub:

PS D:gittestspullaheadworkrepo> cd ..
PS D:gittestspullahead> git clone github homerepo
PS D:gittestspullahead> cd homerepo
PS D:gittestspullaheadhomerepo> type afile.txt
firstContent
aModif

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

然后我克隆workrepo第一个实验

PS D:gittestspullaheadworkrepo4> cd ..
PS D:gittestspullahead> git clone workrepo workrepo2
Initialized empty Git repository in D:/git/tests/pullahead/workrepo2/.git/
PS D:gittestspullahead> cd workrepo2
PS D:gittestspullaheadworkrepo2> git remote add github d:/git/tests/pullahead/github
PS D:gittestspullaheadworkrepo2> 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状态确实提到了“ origin ”之前的主基因:

PS D:gittestspullaheadworkrepo5> 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:gittestspullaheadworkrepo2> 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的起源的repo中重复序列(或者根本没有起源,只是一个远程的'github'定义),状态就是干净的:

PS D:gittestspullaheadworkrepo2> cd ..
PS D:gittestspullahead> git clone workrepo workrepo4
PS D:gittestspullahead> cd workrepo4
PS D:gittestspullaheadworkrepo4> git remote rm origin
PS D:gittestspullaheadworkrepo4> git remote add github d:/git/tests/pullahead/github
PS D:gittestspullaheadworkrepo4> 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:gittestspullaheadworkrepo4> git status
# On branch master
nothing to commit (working directory clean)

如果我只在github指向origin ,那么git1.6.5的status将是干净的。
它可能与早期的git提前发出警告,但无论如何,明确定义的git config branch.master.remote yourGitHubRepo.git应该能够处理该问题,即使是早期版本的Git也是如此。


你是否小心地使用git remote add NAME URL添加所有的远程文件(原始克隆附带的origin文件除外)? 当他们刚被添加到git配置中时,我看到了这个bug。

链接地址: http://www.djcxy.com/p/3959.html

上一篇: 'git pull origin mybranch' leaves local mybranch N commits ahead of origin. Why?

下一篇: only repo's 'git status' saying the branch is ahead of origin/master. Why?