我在下面的沙箱中练习git:https://learngitbranching.js.org/?NODEMO
我在两个单独的会话中运行了两组命令。第一组命令的顺序如下:
git clone
git checkout -b feature
git push
git fakeTeamwork main 1
git fakeTeamwork feature 1
git pull
字符串
第二组命令的顺序类似,但我在最后使用git fetch
+ git merge
:
git clone
git checkout -b feature
git push
git fakeTeamwork main 1
git fakeTeamwork feature 1
git fetch
git merge o/feature
型
如果git pull
= git fetch
+ git merge
,为什么两个结果不同?似乎git pull
没有更新所有的远程跟踪分支。这只是沙箱的缺陷,还是这实际上是在git中发生的?
注意:命令git clone
和git fakeTeamwork
只是为沙箱构建的命令
谢谢你,谢谢你
3条答案
按热度按时间v1uwarro1#
似乎git pull并没有更新所有的远程跟踪分支。
这可能会发生,是的。它确实会发生在:
git pull
运行git fetch origin master
,git fetch origin master
仅更新origin/master
。但是,在1.8.4之前的Git版本中,一些
git fetch
操作根本不会更新任何远程跟踪名称。这里的git fetch origin master
对origin/master
没有影响。除此之外,我们还有其他几种特殊情况:
git pull
被配置或被告知运行git rebase
,它使用的第二个命令是git rebase
,而不是git merge
。因此,明显的替代是git fetch
后跟git rebase
。这里的一些细节甚至更多地依赖于Git版本:特别是,在git rebase --fork-point
出现之前,git pull
就实现了--fork-point
模式来进行变基(实际的--fork-point
选项最早出现在Git 1.9中,但git pull
在1.6版本中做了特殊的工作-我查过一次精确的版本,但现在使用的最早的Git似乎是CentOS,在一些发行版中包括一些Git 1.7版本)。git pull
,那么还没有现有的分支。(您可以在以后使用孤立分支再次触发这种情况。)在这种情况下,git pull
运行的不是merge或rebase,而是一个专门的git checkout
。分支的 upstream 设置在这里很重要,这取决于你传递给
git pull
或fetch和second命令的参数。一般来说,除了你注意到的一些远程跟踪名称有时不会更新的警告之外,这些命令的工作方式基本相同。uqdfh47h2#
git pull
真的是git fetch
+git merge
吗?简而言之,是的。
然而,值得指出的是,
git fetch
(在没有任何参数的情况下调用时)更新的 * 哪些 * 远程跟踪分支是由remote.<repository>.fetch
配置变量决定的。如果你在真实的Git仓库中运行
git config remote.origin.fetch
,你应该看到以下内容:字符串
这被称为 refspec。
*
告诉Git获取origin
远程中的所有分支(:
的右侧),并将它们放入本地存储库中(:
的左侧)。如果不带任何参数运行git pull
或git fetch
,所有新的和现有的远程跟踪分支都将通过此设置进行更新。从文档中:
当运行
git fetch
而没有在命令行上指定要获取的分支和/或标记时,例如git fetch origin
或git fetch
,remote.<repository>.fetch
值用作引用规范-它们指定要获取的引用和要更新的本地引用。(即任何与值refs/heads/*
的左侧匹配的ref),并更新refs/remotes/origin/*
层次结构中相应的远程跟踪分支。一旦开始将分支名称传递给
git pull
或git fetch
,这种行为就不再适用,正如@torek在his answer中指出的那样。mnowg1ta3#
你可以使用环境变量
GIT_TRACE=1
来查看git
的大致功能。例如,在我的git 2.42中:字符串
当然,除了这些命令之外,git还做其他事情(例如,根据本地状态做出决策,发布错误)。注意:您可能会看到其他
run_command:
跟踪,它们是fetch
或merge
的一部分。