【问题标题】:git fetch + git merge origin/master vs git pull origin/mastergit fetch + git merge origin/master vs git pull origin/master
【发布时间】:2020-07-27 09:16:00
【问题描述】:

我认为 git pull 就像 git fetch + git merge。在 branchA 中,我总是先执行 git fetch,然后执行 git merge origin/master。但是今天,在一个分支A中,我尝试了 git pull origin/master 并没有用,但是做一个 git pull origin master 工作。有什么想法吗?

另外一个问题,如果更新的origin/master和master的在线版本是一样的,为什么还要有origin/master呢,总是用一直更新的在线版本发布不是更方便吗?我们从负担到总是被 git 抓取?

【问题讨论】:

标签: git git-merge git-pull git-fetch


【解决方案1】:

我认为 git pull 就像一个 git fetch + git merge。

是的。但是,git pull 使用的语法与几乎所有其他 Git 命令使用的语法都不匹配。这是由于历史原因:git pull 早于 Git 1.5 之前和 1.6 之后的 Git 版本之间的许多改进。 (请注意,Git 现在是 2.26 版本,所以这是真正的古老历史,可以追溯到 2005 年左右。人们今天仍在使用的最古老的 Git 版本似乎在 1.7 版本范围内——但是当你运行 git pull ,您正在回到石器时代之前的恐龙 Git 1.5 时代。)

[但是]我尝试了git pull origin/master,但它不起作用[而]git pull origin master 起作用

这是因为这是 git pull 的特殊语法。

仔细阅读the git pull documentation 以了解异常情况(其中有很多),但一般来说,您传递给git pullgit pull 的大多数参数都会传递给git fetch。就像你不会跑一样:

git fetch origin/master      # wrong

你不能跑

git pull origin/master       # also wrong: this runs git fetch origin/master

但是,您可以运行:

git fetch origin master

这里origin 是一个remotemaster 是一个refspec(请参阅the git fetch documentation 了解更多关于remote 和refspecs 的信息)。这特别限制了您的 git fetch 操作以仅获取在其 master 上的新提交,以便更新您的 origin/master1

提取完成后,pull 运行 merge,或者如果您指定,rebase,在某些分支头提交上。2这里的一般想法 -回到我提到的那个 pre-Git-1.6 的历史——在从其他 Git 获取一些提交之后,你现在希望将这些提交合并到你的当前分支中。

有一段时间,在早期的 Git 中,remote 的整个概念不存在,因此没有远程跟踪名称:根本没有 origin,因此没有origin/master。因此,立即合并他们的提交很重要,以免您的 Git 运行垃圾收集过程并删除您获得的新提交。

在后 1.6 时代(即从 2006 年左右开始)收集提交并让它们在那里放置一段时间是安全的,当你查看它们时,想想它们,甚至暂时完全忽略它们。 remote 名称 origin 引入了 remote-tracking 名称,例如 origin/master,它可以无限期地保留这些提交。不再需要疯狂地将这些提交推送到 您自己的 分支之一,以防止它们被删除。

底线是:如果您觉得git pull 方便,请使用它。如果没有,不要。请记住,如果您使用参数,您将使用的参数是唯一的。它只是 git fetch 的组合,加上立即第二个命令将一些获取的提交合并到 当前 em> 分支。我发现这个 in 很方便,大多数时候:我喜欢先inspect 获取的提交。 如果您不使用 git pull,您将使用远程跟踪名称命名传入的提交,例如 origin/master,但如果您使用 git pull,您不能git pull 命令本身中使用这些名称,因为它与这些名称不存在的古代兼容。


1这种git fetch 将在任何现代Git 中更新您的origin/master,但在1.8.4 之前的Git 版本中,它将使origin/master 未更新。

2选择作为合并或变基参数的提交是来自您在命令行上特别命名的引用(如果您命名的话)的提交。否则,选择作为参数的(单个)提交是与当前分支的 upstream 设置对应的提交。

在某些极端情况下,git pull 会运行除合并或变基以外的其他命令作为其第二个命令。这些特殊情况中最有趣的是拉入一个完全空的存储库:在这里,git mergegit rebase 都不会做任何事情,所以git pull 基本上只是运行git checkout。这种特殊情况显然在任何给定的存储库中只发生一次。

【讨论】:

  • 如果我执行git pull,它只会将git fetch(更新我的origin/x)和git merge origin/master 到我的分支。另一方面,如果我做git pull origin master,它将git fetch(仅更新我的origin/master)和git mergeorigin/master 到我的分支。这些假设是否正确?
  • @user33276346:没有其他参数——即,以git pull 运行——你的 Git 将查找当前分支的 上游设置。你在哪个分支?它的上游是什么?将其分解为多个部分——例如,origin/master 变为 origin master——第一部分为您提供git fetch 的遥控器。将它们重新组合在一起,它们会为您提供后续git merge 的远程跟踪名称。 git pull 运行的 fetch 将是“无限”的 fetch,更新 origin/*
  • 但是,如果有额外的参数——例如,git pull origin master——你的 Git 将运行git fetch origin master,这是一个有限的获取,只会更新你的origin/master。然后你的 Git 将运行相当于 git merge origin/master.
  • 所以,如果你是自己的feature/two,其上游是origin/feature/twogit pull 将更新origin/* 并与更新后的origin/feature/two 合并,但git pull origin master将更新 origin/master 并与更新后的 origin/master 合并。
  • (有关早于 1.8.4 等的旧 Git 版本的所有注意事项,请参见上文。)
猜你喜欢
  • 2017-10-20
  • 2011-02-22
  • 2014-03-12
  • 2012-01-31
  • 2012-05-22
  • 2013-02-08
  • 2014-02-27
相关资源
最近更新 更多