git pull <link-to-remote>做了什么?

时间:2018-02-12 15:21:17

标签: git github version-control git-pull

我工作的新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或任何分支。

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

4 个答案:

答案 0 :(得分:2)

TL; DR

由于你的Git对命名遥控器一无所知,Git只是向其他Git询问它推荐的内容 - 具体是它的HEAD是什么。然后你的Git将它用于获取和合并步骤。

换句话说,这相当于:

git pull <url> HEAD

留下了一些奇怪的东西需要解释。

正如其他两位回答者说的那样,git pull只是运行git fetch,然后是第二个Git命令,通常为git merge。棘手的部分在于 git pull如何运行这两个命令,然后他们做了什么。

如果您在命令行中输入:

git pull abc bra

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

git fetch abc bra

如果从bra命令中省略git pull部分 - refspec,Git只会运行:

git fetch abc

即,它也忽略了fetch步骤中的refspec。 (请注意,远程或存储库之后的每个非选项参数都是refspec,但通常在命令行上放置多个不明智。)

如果省略两个名称,git pull将使用 参数运行git fetch。所以现在我们需要查看git fetch对其remote-or-repository和refspec参数的作用。

git fetch取得什么

您或您的git pull - 将使用以下代码运行git fetch

  • 没有名为remote-or-repository且没有refspecs;或
  • 一个名为remote-or-repository且没有refspecs;或
  • 一个名为remote-or-repository和一个或多个refspec。

在第一种情况下,git fetch根据您当前的分支(它运行相当于git config --get branch.branch.remote)计算出要使用的远程,或者如果失败,则假设为origin。在第二种或第三种情况下,您可以为其指定一个名为origin的远程名称,也可以为其指定https://github.com/our-repo.git之类的网址。由于第一种情况转化为第二种情况,我们只有两种情况需要担心。

如果您使用名为remote ,例如origin,则您的Git会查找remote.origin.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提供原始网址时,它可能无法找到remote.https://github.com/our-repo.git.fetch配置(它甚至可能不会尝试查找,但如果确实如此,则会赢得&#39;找不到任何东西)。它仍然知道要联系的 URL ,所以它在那里联系了一个Git;但它没有特定的fetch =指令。如果你给git fetch一个分支名称,你的Git会向他们的Git询问该分支。但你也没有这样做 - 所以你的Git只是问他们的Git:嘿,其他Git,你设置为HEAD

所以你什么都不说,他们的Git给你一个哈希ID来跟他们的 HEAD一起,你的Git把它写给.git/FETCH_HEAD。或者,你说&#34;给我你的分支bra&#34;,他们的Git会给你一个哈希ID来跟他们的refs/heads/bra一起使用,而你的Git会把它写给{{1} }。在任何一种情况下,没有任何远程跟踪名称发生。没有名为remote的,因此无法更新正确的远程跟踪名称。

但是,您的Git始终将其提取的所有内容写入.git/FETCH_HEAD是否更新了.git/FETCH_HEADorigin/master 这样的名称。这部分是一个古老的向后兼容的东西 - 除了origin/develop仍然使用它,我们稍后会看到。

git pull合并的git merge合并

此步骤在几个方面比获取步骤更简单,但仍然相当棘手。当git pull运行git pull时,它会预先设置一些选项和参数:

  • git merge-m始终提供初始合并消息。它不是一个非常好的好的合并消息,但它提供了一个。 (默认情况下,如果涉及实际合并,则可以编辑此合并消息。)
  • git pull的其他选项:如果您使用git pull--ff--no-ff,或--ff-only,或the documentation中列出的各种其他选项},-s strategy将这些内容传递给git pull
  • 一个或多个原始提交ID。

git mergegit fetch后面的曲目留在.git/FETCH_HEAD后,git pull代码将读取该文件。在该文件中,Git记录了它所获取的每个分支提示。在某些情况下,只有一个这样的提交。 (例如,对于这种获取HEAD的情况,情况确实如此。)在其他情况下 - 这些都不适用于这种特殊情况,但我们应该记住它们的完整性 - 它列出更多;但它标志着他们中的大部分not-for-merge。它没有标记的那些是与您在命令行上给出的refspec名称相对应的那些,例如bra,或者 - 如果你没有命名在命令行上的任何一个 - branch.branch.merge中的任何一个,如果你是从一个命名的遥控器中提取的。

在任何情况下,git pull都会提取git fetch 没有标记为&#34;而不是合并&#34;。理想情况下,这只是一个提交哈希值,因为否则您的git pull正在调用git merge以便进行章鱼合并。这很少是你想要的 - 如果你不知道它是什么,你肯定不想要它! - 如果只涉及一个哈希ID,那么你会更快乐(因为它是案例)。

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

完成后,未能完成(在中间停止以获得用户的帮助),或者甚至没有尝试合并,git merge退出,现在git pull已完成。< / p>

结论

通过使用URL运行git pull,您已经要求其他Git向您发送其HEAD(可能是master)提交,以及所需的任何其他提交,然后合并该提交进入当前分支,无论您当前的分支是什么。通过使用网址而不是origin,您已停用了自己的Git {更新origin/master或任何其他origin/*名称。因此,如果需要合并或快进以引入他们的HEAD,并且未被禁止,则现在或者在合并失败的半完成状态下完成。

答案 1 :(得分:0)

pull命令用于在单个命令中进行 git fetch ,然后执行 git merge

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

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

答案 2 :(得分:0)

感谢您提出问题。

假设您已经拥有存储库的克隆副本,并且有许多开发人员在存储库上工作,最近在远程存储库中合并了一个pull请求,现在远程在forked / local存储库之前提交了1个提交。 现在,即使使用远程存储库保留本地/分叉存储库,我们也必须git pull远程,然后git push以保持本地和分叉甚至远程存储库。

有关详细信息,请仔细阅读:https://git-scm.com/docs/git-pull

答案 3 :(得分:0)

它是
的缩写     git pull <URL> HEAD


可以找到HEAD     cat .git/FETCH_HEAD

示例:

  cat .git/FETCH_HEAD
      b521bea1b4b336864462e