git拉什么 做?

问题描述 投票:1回答:3

我工作的新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>究竟会做什么?

git github version-control git-pull
3个回答
2
投票

TL;DR

由于你的Git对命名遥控器一无所知,Git只是向其他Git询问了它的建议 - 特别是它的HEAD是什么。然后你的Git将它用于获取和合并步骤。

换句话说,这相当于:

git pull <url> HEAD

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

Long

正如其他两位回答者所说,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步骤的refspecs。 (请注意,remote-or-repository之后的每个非选项参数都是refspec,但通常在命令行中放置多个是不明智的。)

如果省略这两个名称,git pull将运行带有remote和refspec参数的git fetch。所以现在我们需要看一下git fetch用它的remote-or-repository和refspec参数做什么。

What git fetch fetches

你或你的git pull将运行git fetch

  • 没有命名的remote-or-repository而且没有refspecs;要么
  • 一个名为remote-or-repository且没有refspecs;要么
  • 一个名为remote-or-repository和一个或多个refspecs。

在第一种情况下,git fetch根据您当前的分支(它运行相当于git config --get branch.branch.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。或者,你说“给我你的分支bra”,他们的Git给你一个哈希ID与他们的refs/heads/bra,你的Git写给.git/FETCH_HEAD。在任何一种情况下,任何远程跟踪名称都没有任何反应。没有命名的遥控器,因此无法更新正确的远程跟踪名称。

尽管如此,你的Git总是将它提取的所有内容写入.git/FETCH_HEAD,无论是否更新像origin/masterorigin/develop这样的名字。这部分是一个古老的向后兼容性的东西 - 除了git pull仍然使用它,我们马上就会看到。

What the git merge run by git pull merges

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

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

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

在任何情况下,git pull提取任何git fetch没有标记为“不合并”。理想情况下,这只是一个提交哈希,因为否则你的git pull正在调用git merge以便进行章鱼合并。这很少是你想要的 - 如果你不知道它是什么,你肯定不想要它! - 如果只涉及一个哈希ID,那么你会更高兴(就像这里的情况一样)。

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

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

Conclusion

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


0
投票

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

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

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


0
投票

谢谢你的提问。

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

有关更多详细信息,请查看:https://git-scm.com/docs/git-pull

© www.soinside.com 2019 - 2024. All rights reserved.