git pull与git-fetch的区别引起了一些困惑

17
所以,有人能澄清一下这个问题吗:
我运行:
git pull origin master  
git status

然后它会拉取更改并显示:

your branch is ahead of origin/master ... blahblah by 6 commits...

当我运行以下命令时:
git fetch
git status

这里写着:

# On branch master
nothing to commit (working directory clean)

因此 - 我认为git pull默认会进行git fetch操作 - 那么为什么不需要额外的git fetch就显示"ahead by 6 commits"?

在这种情况下,它的意思就是字面上的意思:你的分支领先,即包含未推送的提交,这与拉取无关,只是提醒你。 - bredikhin
@bredikhin,但我刚刚拉取了这些提交——为什么它们会被归类为未推送的?这就是我困惑的地方。当我从远程分支拉取更改时,为什么我不会立即收到“没有要提交的内容(工作目录已干净)”的消息呢? - Dannyboy
在你第二次运行 git status 之前,你是否有运行过 git push 命令? - micromoses
@Dannyboy,你的本地提交还没有推送,而不是你已经拉取的提交。 - bredikhin
@bredikhin 但是根据文档:“在默认模式下,git pullgit fetchgit merge FETCH_HEAD 的简写”。所以pull也会fetch - 我错了吗? - Dannyboy
显示剩余5条评论
1个回答

3
git status中,“ahead or behind by X commits”文本基于当前分支的跟踪分支的状态;例如,如果您在master上,则为remotes/origin/master
当您使用远程和分支指定运行git pull时,它会获取新提交并将其合并到当前分支,但是它不会更新源的远程跟踪分支。相反,它将刚提取的提交指向为FETCH_HEAD
另一方面,运行没有指定参数的git fetch实际上会更新所有的远程跟踪分支,因此它会使消息消失。没有参数的git pull也会执行相同操作。
这是我自己遇到过多次的微妙问题!我希望git每次针对特定远程内容进行提取时都会更新所有远程跟踪分支。

只是出于好奇,你知道为什么 git pull <remote> <branch> 不会更新 remote/branch 引用吗?这只是历史原因,还是有一些好的理由呢? - torek
事实证明,它实际上根本不是 git pull <remote> <branch>;它真正的形式是 git pull <remote> <refspec>。 "refspec" 基本上是由冒号分隔的源-目标对,例如 master:origin/mastergit pull origin master:origin/master 的意思是“转到 origin 远程,给我它的主分支,并在本地仓库中更新 origin/master。” 如果您省略冒号,则提取操作将不会更新任何本地引用,只会更新 FETCH_HEAD - Ash Wilson
进一步阅读:http://git-scm.com/book/en/Git-Internals-The-Refspec - Ash Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接