git pull 真的是 git fetch + git merge 吗?
Is git pull really git fetch + git merge?
我在以下沙箱中练习 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
没有更新所有远程跟踪 b运行ches。这只是沙盒的一个缺陷,还是 git 中实际发生的情况?
注意:命令 git clone
和 git fakeTeamwork
只是为沙盒构建的命令
谢谢!
It seems that git pull does not update all the remote tracking branches.
这可以发生,是的。它 会在以下时间发生:
例如 git pull
运行s 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 pull
在 git rebase --fork-point
存在之前为 rebase 实现了 --fork-point
模式(实际的 --fork-point
选项第一次出现在 Git 1.9,但 git pull
从某个 1.6 版本开始做特殊工作——我查过一次准确的版本,但最近使用的最老的 Git 似乎是 CentOS,在某些发行版中包含一些 Git 1.7 版本)。
- 有一个非常的特殊情况:如果您创建一个空存储库,添加一个远程,并且运行
git pull
,没有现有分支然而。 (稍后您可以使用孤立分支再次触发这种情况。)在这种情况下,git pull
运行 不是合并或变基,而是一个专门的 git checkout
.
分支的 upstream 设置在这里很重要,具体取决于您传递给 git pull
或 fetch 和第二个命令的参数。一般来说,这些大多以相同的方式结束,除了你注意到的一些远程跟踪名称有时不会更新的警告。
Is git pull
really git fetch
+ git merge
?
简而言之,是的。
然而,值得指出的是 哪个 远程跟踪分支由 git fetch
更新(当调用时不带任何参数)由 remote.<repository>.fetch
决定配置变量。
如果您 运行 git config remote.origin.fetch
在真正的 Git 回购中,您应该看到以下内容:
+refs/heads/*:refs/remotes/origin/*
这叫做refspec。 *
告诉 Git 获取 origin
远程(:
的右侧)中的所有分支并将它们放入本地仓库(左侧 - :
的手边)。如果您 运行 git pull
或 git fetch
没有任何参数,所有新的和现有的远程跟踪分支都将由于此设置而更新。
When git fetch
is run without specifying what branches and/or tags
to fetch on the command line, e.g. git fetch origin
or git fetch
,
remote.<repository>.fetch
values are used as the refspecs—they
specify which refs to fetch and which local refs to update. The
example above will fetch all branches that exist in the origin
(i.e.
any ref that matches the left-hand side of the value, refs/heads/*
)
and update the corresponding remote-tracking branches in the
refs/remotes/origin/*
hierarchy.
一旦您开始将分支名称传递给 git pull
或 git fetch
,此行为将不再适用,如 @torek pointed out in 。
我在以下沙箱中练习 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
没有更新所有远程跟踪 b运行ches。这只是沙盒的一个缺陷,还是 git 中实际发生的情况?
注意:命令 git clone
和 git fakeTeamwork
只是为沙盒构建的命令
谢谢!
It seems that git pull does not update all the remote tracking branches.
这可以发生,是的。它 会在以下时间发生:
-
例如
git pull
运行sgit 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 pull
在git rebase --fork-point
存在之前为 rebase 实现了--fork-point
模式(实际的--fork-point
选项第一次出现在 Git 1.9,但git pull
从某个 1.6 版本开始做特殊工作——我查过一次准确的版本,但最近使用的最老的 Git 似乎是 CentOS,在某些发行版中包含一些 Git 1.7 版本)。 - 有一个非常的特殊情况:如果您创建一个空存储库,添加一个远程,并且运行
git pull
,没有现有分支然而。 (稍后您可以使用孤立分支再次触发这种情况。)在这种情况下,git pull
运行 不是合并或变基,而是一个专门的git checkout
.
分支的 upstream 设置在这里很重要,具体取决于您传递给 git pull
或 fetch 和第二个命令的参数。一般来说,这些大多以相同的方式结束,除了你注意到的一些远程跟踪名称有时不会更新的警告。
Is
git pull
reallygit fetch
+git merge
?
简而言之,是的。
然而,值得指出的是 哪个 远程跟踪分支由 git fetch
更新(当调用时不带任何参数)由 remote.<repository>.fetch
决定配置变量。
如果您 运行 git config remote.origin.fetch
在真正的 Git 回购中,您应该看到以下内容:
+refs/heads/*:refs/remotes/origin/*
这叫做refspec。 *
告诉 Git 获取 origin
远程(:
的右侧)中的所有分支并将它们放入本地仓库(左侧 - :
的手边)。如果您 运行 git pull
或 git fetch
没有任何参数,所有新的和现有的远程跟踪分支都将由于此设置而更新。
When
git fetch
is run without specifying what branches and/or tags to fetch on the command line, e.g.git fetch origin
orgit fetch
,remote.<repository>.fetch
values are used as the refspecs—they specify which refs to fetch and which local refs to update. The example above will fetch all branches that exist in theorigin
(i.e. any ref that matches the left-hand side of the value,refs/heads/*
) and update the corresponding remote-tracking branches in therefs/remotes/origin/*
hierarchy.
一旦您开始将分支名称传递给 git pull
或 git fetch
,此行为将不再适用,如 @torek pointed out in