git 拉 <link-to-remote> 有什么作用?

What does git pull <link-to-remote> do?

我工作中的一个新 git 用户错误地 运行 命令

git pull https://github.com/our-repo.git

他们的意思是:

git clone https://github.com/our-repo.git

或至少

git remote add origin https://github.com/our-repo.git

git pull origin master

然而 git pull https://github.com/our-repo.git 似乎引入了一些代码,但显然它并没有创建 origin 或任何 b运行ches。

git pull <url-to-remote> 究竟会做什么?

pull 命令用于在一个 git fetch 之后进行 git merge单个命令。

fetch 命令从远程存储库导入信息。导入是通过特殊分支完成的,以便我们进行比较。

git 合并。将分支与当前分支合并

感谢提问。

假设您已经拥有存储库的克隆副本,并且有许多开发人员在处理该存储库,并且最近在远程存储库中合并了一个拉取请求,现在远程存储库比 forked/local 存储库。 现在要保持 local/forked repo 即使与远程存储库我们必须 git pull 远程然后 git push 保持本地和分叉甚至与远程存储库。

更多详细信息,请看这里:https://git-scm.com/docs/git-pull

TL;DR

由于您的 Git 对命名遥控器一无所知,Git 只是询问另一个 Git 它推荐什么——具体来说,它的 HEAD 是什么。您的 Git 然后将其用于提取和合并步骤。

换句话说,这相当于:

git pull <url> HEAD

这还有一些奇怪的地方需要解释。

正如到目前为止其他两个回答者所说,git pull 只是 运行s git fetch 后跟第二个 Git 命令,通常是 git merge。棘手的部分在于 如何 git pull 运行 这两个命令,以及它们随后执行的操作。

如果在命令行输入:

git pull abc bra

然后 abc 部分被视为 远程或存储库 bra 部分被视为 refspec。 Git 然后 运行s:

git fetch abc bra

如果您从 git pull 命令中省略 bra 部分(refspec),Git 只需 运行s:

git fetch abc

即,它也省略了 fetch 步骤中的 refspecs。 (请注意,在 remote-or-repository 之后的 every 非选项参数是一个 refspec,但在命令行中放置多个参数通常是不明智的。)

如果省略两个名字,git pull将运行git fetch两个远程 refspec 参数。所以现在我们需要看看 git fetch 对其 remote-or-repository 和 refspec,参数做了什么。

git fetch 获取的内容

你——或者你的 git pull——将 运行 git fetch 具有:

  • 没有命名的远程或存储库,也没有引用规范;或者
  • 一个名为 remote-or-repository 且没有 refspecs;或者
  • 一个名为 remote-or-repository 和一个或多个 refspecs。

在第一种情况下,git fetch 根据您当前的分支找出要使用的遥控器(它 运行 相当于 git 配置 -- get branch.<em>branch</em>.remote),或者如果失败,假设 origin。在第二种或第三种情况下,你可以给它一个像origin这样的远程名称,或者你可以给它一个像https://github.com/our-repo.git这样的URL。由于第一种情况转化为第二种情况,我们这里只需要担心这两种情况。

如果您使用 命名的遥控器 ,例如 origin,您的 Git 查找 remote.origin.url 以获得 URL,还有 remote.origin.fetch。通常 remote.origin.fetch 设置为:

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

因此,当您 运行 git fetch origin 时,您的 Git 获取 所有 其他 Git 提供的分支,转向他们变成远程跟踪名称。当您 运行 git fetch origin bra 时,您的 Git 只获取获取 bra 所需的任何内容(我在这里假设 bra 是一个分支名称)。如果您的 Git 至少是 1.8.4,它仍然会进行相同的重命名,因此也会更新 refs/remotes/origin/bra

当你给你的 Git 一个原始的 URL 时,它可能找不到 remote.https://github.com/our-repo.git.fetch 配置(它甚至可能不会尝试查找,但如果它确实如此,它不会找到任何东西)。它仍然知道要联系什么URL,所以它联系那里的Git;但它没有特定的 fetch = 指令。如果您给 git fetch 一个分支名称,您的 Git 将向他们的 Git 询问该分支。但你也没有这样做——所以你的Git只是问他们的Git:嘿,其他Git,你设置了什么HEAD?

所以你什么都不说,他们的 Git 给你一个散列 ID 和 他们的 HEAD,你的 Git 写这到 .git/FETCH_HEAD。或者,你说 "give me your branch bra",他们的 Git 给你一个哈希 ID 和他们的 refs/heads/bra,然后你的 Git 把它写到 .git/FETCH_HEAD。在任何一种情况下,任何远程跟踪名称都不会发生任何变化。没有命名的远程名称,因此无法更新正确的远程跟踪名称。

尽管如此,您的 Git 总是将它获取的所有内容写入 .git/FETCH_HEAD 无论是否更新 origin/masterorigin/develop 这样的名称。这在一定程度上是一个古老的向后兼容性问题——除了 git pull 仍在使用它,我们稍后会看到。

git merge 运行 由 git pull 合并的内容

此步骤在几个方面比提取步骤简单,但仍然非常棘手。当git pull 运行s git merge时,它预先设置了一些选项和参数:

  • -m: git pull 始终提供初始合并消息。这不是一个非常 好的 合并消息,但它确实提供了一个。 (默认情况下,如果涉及实际合并,它会让您编辑此合并消息。)
  • 来自 git pull 的其他选项:如果您使用 --ff--no-ff--ff-only,或 -s strategy,或 [=] 中列出的各种其他选项91=], git pull 将它们传递给 git merge.
  • 一个或多个原始提交 ID。

git fetch.git/FETCH_HEAD 中留下踪迹后,git pull 代码读取整个文件。在该文件中,Git 记录了它获取的每个分支提示提交。在某些情况下,只有一个这样的提交。 (例如,对于这种获取 HEAD 的情况就是如此。)在其他情况下——none 适用于这种特殊情况,但为了完整性我们应该记住它们——它列出了更多;但它标记了其中的大多数 not-for-merge。它 没有 标记的是那些与您在命令行中提供的 refspec 名称相对应的名称,例如 bra,或者 - 如果您没有命名在命令行上——来自 branch.<em>branch</em>.merge 的那个,如果你从一个命名的 remote.

无论如何,git pull 提取任何 git fetch 没有 标记为 "not for merge" 的内容。理想情况下,这只是一个提交哈希,否则您的 git pull 将调用 git merge 以进行 octopus 合并 。这很少是你想要的——如果你不知道它是什么,你肯定不想要它!——所以如果只涉及一个哈希 ID(就像这里的情况),你会更开心。

此时,git merge 会根据选项和参数执行它一贯执行的操作。 Git 从当前提交(您自己的存储库的 HEAD)和参数提交计算合并基础。如果合并基础与其他(单个)提交相同,则没有要合并的内容:Git 如此说但什么也不做。如果合并基础是 HEAD,则可以进行快进非真正合并; Git 如果您没有禁止它,就会执行此操作。否则,需要真正的合并,如果您没有禁止它,Git 会这样做。

完成后,无法完成(在中间停下来获得用户的帮助),或者甚至不尝试合并,git merge 退出,现在 git pull 完成.

结论

通过 运行宁 git pull 与 URL,您已要求另一个 Git 将其 HEAD 发送给您(可能 master) 提交,加上任何其他所需的提交,然后将该提交合并到您当前的分支中,无论您当前的分支是什么。通过使用 URL 而不是 origin,您已经禁用了自己的 Git 对 origin/master 或任何其他 origin/* 名称的更新。因此,如果需要合并或快进以引入他们的 HEAD,并且没有被禁止,那么它要么现在完成,要么处于失败合并的半完成状态。


的缩写 git pull <URL> HEAD

可以通过
找到HEAD所在的位置 cat .git/FETCH_HEAD

示例:

  cat .git/FETCH_HEAD
      b521bea1b4b336864462e