为什么没有参数的 git pull 产生的结果与 git pull origin <分支名称>不同,其中<分支名称>是当前活动分支?

  • 本文关键字:分支 pull git 不同 其中 活动 参数 结果 origin git
  • 更新时间 :
  • 英文 :


我从git pull文档中了解到

$ git pull

$ git pull origin master

应该产生相同的结果,假设当前分支是master。然而,在前一种情况下,我拉下了一个物体,而在后一种情况中,我又拉下了更多的物体(今天超过100个)。很明显,这两个命令不是同义词,那么在我建立新的票证分支之前,确保我有master的最新副本的正确形式是什么?谢谢

其中一些只是原始git pull的总体设计较差,现在必须保留它以实现向后兼容性。

这里要知道的是git pull的意思是:1

  1. 运行git fetch;那么
  2. 运行第二个Git命令

您(通常)可以选择第二个Git命令:rebase或merge。在看到git fetch获取的内容之前,您必须决定使用哪个,我认为这是一个相当大的缺陷,也是避免git pull的原因2您还可以选择git pull传递给git fetch步骤的参数(如果有的话):

  • 如果指定远程(origin)和分支名称(master,在git pull origin master中),则git pull将运行git fetch origin master

  • 如果没有同时指定远程名称和分支名称,则git pull会查看branch.branch.remotebranch.branch.merge,其中branch是当前分支。这两者都必须设置(此时您也必须在某个分支上,这样branch才有意义)。Git然后从第一个设置传递给定的远程名称。

然后我们必须转到git fetch文档,看看它remote和(如果存在)分支名称或refspec参数做了什么remote非常简单:例如,它设置URL的来源;如果remote是来源,您的Git会查找git config --get remote.origin.url的结果,以了解如何联系其他Git。

refspec的论点是事情变得非常奇怪的地方:

  • 带有norefspec参数的fetch使用默认值,来自remote.remote.fetchorigin的标准是+refs/heads/*:refs/remotes/origin/*。这个refspec意味着获得所有分支找到的所有提交,并将其重命名为我的远程跟踪origin/*名称。但是,您可以使用单分支克隆或其他一些非常不寻常的配置,在这些配置中会发生不同的情况。

  • 带有refspec参数的fetch会导致Git查找与refspec匹配的名称。在这里,事情是复杂的。refspec有一个通用形式,其中有一个可选的强制标志、一个部分、一个冒号和一个目标部件。源和目标可以包含*通配符(有某些限制;具体限制取决于您的Git版本)。它们可以是完全限定的引用,从refs开始,也可以让Git执行gitrevisions文档中描述的某些匹配操作。

如果我们避免涵盖所有可能性,只集中使用一个简单的分支名称作为refspec,我们会发现git fetch处理这一问题的方法是:

  1. 将它将获取的限制为任何提交和其他对象,这些对象需要与其他Git中给定分支名称指向的提交同步。也就是说,如果他们的Git的名称为master,意思是commit defb9a3...,那么在git fetch完成时,你的Git将确保你的存储库中有这个提交,以及所有需要的父对象和任何其他需要的对象。但是,如果他们的Git有其他需要更新其他远程跟踪名称的提交和对象,你的Git就不会接受这些。

  2. 然后,它像往常一样提取并将相应的信息写入.git/FETCH_HEADgit pull可以在那里看到它

  3. 在Git1.8.2及更高版本中,它会机会主义地更新远程跟踪名称(在本例中为origin/master)。它通过从配置中读取remote.origin.fetch行来完成此操作。在旧版本的Git中,步骤3不会出现。

这是一种冗长但相当精确的说法,即默认情况下git fetch origin会提取所有分支,但git fetch origin master只提取它们的主这个简短版本有很多可能的特殊例外,但它们相对罕见。


1在不远的过去,git pull是一个shell脚本,你可以阅读它,看看它在哪里运行git fetch。这让事情变得更清楚了。现在它是一个庞大的C程序。它仍然完全一样工作吗?好吧,我们可以希望bug得到修复,所以,可能不会完全相同。但总体行为应该保持不变。

2如果git fetch获取了一些您不想重新建立基础或合并的东西,这并不是说您不能恢复。这是因为运行多个命令比较容易,只要合适,就在中间插入git log。那么就不需要从小型灾难中恢复。


哪个更好

这是一个没有答案的问题,真的。这就像问巧克力冰淇淋是否比草莓味道更好,或者西兰花或花椰菜是否是更好的蔬菜3它们是不同的,一个是否对你更好对于一个特定的目的取决于你和目的。

然而,我们可以注意到,如果您现在让git fetch获取所有,那么稍后的git fetch通常会更少地获取。如果您现在将git fetch限制为仅其master,并且以后还需要从其dev提交,并且必须运行git fetch origin dev,那么您最好运行一个包含所有内容的git fetch origin

如果您计划使用n远程跟踪名称,其中n>1,一个简单的git fetch,它可以获得一切,非常方便。


3然而,很明显,在所有十字花科蔬菜中,球芽甘蓝是最差的。

最新更新