20

我有一个名为foo.

> git status
# On branch foo
nothing to commit (working directory clean)

它最初是使用以下命令签出的:

> git checkout origin/foo -b foo --track

我想从远程存储库获取此分支的更新。我知道这些命令中的任何一个都足够了:

> git fetch origin foo # ignore the lack of merging
> git pull origin foo

如果我省略fetchor的参数pull,git 会默认获取(或拉取)我当前已签出的分支吗?也就是说,以下成对的命令是否等效?

> git checkout foo
> git pull

> git checkout foo
> git pull origin foo
4

3 回答 3

26

不幸的是,它们是否等效通常取决于您所在的分支、您的配置、月相等。

正如我在下面所描述的,您可以从手册页中弄清楚这一点git pull,但我通常会尽量避免通过执行以下操作来解决这个问题:git fetch origin然后git merge origin/foo. (我写了一篇关于这个有点漫无边际的博客文章。)

但是,您的问题实际上是关于git pull您未指定远程或参考规范时的默认行为。git pull我们可以从手册页,尤其是DEFAULT BEHAVIOUR章节中找出这一点。这有点难以弄清楚,所以我用粗体表示了唯一真正适用于您的问题的部分,因为(a)您在分支上foo,(b)您按照问题中的描述创建了该分支,并且( c) 你没有改变你的配置。

人们经常使用 git pull 而不给出任何参数。传统上,这相当于说git pull origin但是,当branch.<name>.remote在 branch 上存在配置时<name>,将使用该值而不是origin.

为了确定要从哪个 URL 获取,请remote.<origin>.url查阅配置的值,如果没有任何此类变量,则使用文件中的URL:在线值。$GIT_DIR/remotes/<origin>

为了确定在命令行上没有任何 refspec 参数的情况下运行命令时要获取哪些远程分支(并且可以选择存储在远程跟踪分支中),请remote.<origin>.fetch咨询配置变量的值,如果没有,$GIT_DIR/remotes/<origin>查阅文件并使用其Pull: 行。除了 OPTIONS 部分中描述的 refspec 格式之外,您还可以使用如下所示的 globbing refspec:

refs/heads/*:refs/remotes/origin/*

一个全局引用规范必须有一个非空的 RHS(即必须存储在远程跟踪分支中获取的内容),并且它的 LHS 和 RHS 必须以/*. refs/remotes/origin/上面指定了所有远程分支都使用同名的层次结构中的远程跟踪分支进行跟踪。

在获取后确定要合并哪个远程分支的规则有点涉及,以免破坏向后兼容性。

如果在 git pull 的命令行上给出了明确的 refspecs,它们都会被合并。

当命令行上没有给出 refspec 时, git pull 使用配置中的 refspec 或$GIT_DIR/remotes/<origin>. 在这种情况下,以下规则适用:

  1. If branch.<name>.merge当前分支的配置存在,即被合并的远程站点的分支的名称。

  2. 如果 refspec 是一个通配符,则不会合并任何内容。

  3. 否则,第一个 refspec 的远程分支将被合并。

当您使用以下命令创建分支foo时:

git checkout origin/foo -b foo --track

...它将设置以下配置选项,将您的分支foo与存储库refs/heads/foo中的相关联origin

branch.foo.remote=origin
branch.foo.merge=refs/heads/foo

所以,如果你把它和上面加粗的句子放在一起,答案是“是的,在你描述的这种情况下,当你在 branchfoo时,命令git pullgit pull origin foo是等价的。”

于 2011-07-28T15:40:49.920 回答
6

即使在 Mark 描述的条件下,当它们看起来相同时,仍然存在细微差别——git pull origin foo不会更新远程跟踪分支,而git pull会。这记录在 git-pull 的手册页中:

A parameter <ref> without a colon is equivalent to <ref>: when pulling/fetching, so it merges <ref> into the current branch without storing the remote branch anywhere locally

所以在你的情况下,对于真正等价于git pull,你需要做git pull origin foo:refs/remotes/origin/foo

于 2013-02-11T06:27:16.933 回答
1

是的,他们是。跟踪信息保存在.git/config.

于 2011-07-28T14:47:32.140 回答