Git pull vs fetch+merge,没有先取的情况下合并有什么意义?

Git pull vs fetch+merge,没有先取的情况下合并有什么意义?,git,git-merge,git-fetch,Git,Git Merge,Git Fetch,git pull是git获取,然后是git合并。但是,具体地说,为什么一个git合并时不先进行获取呢?i、 e.为什么可能将一个看似单一的操作分解为两个子操作?也许如果你出于某种原因在没有合并的情况下进行提取,然后你只是合并,因为你知道从哪里提取它存在问题?我看这已经被否决了,但作为一种哲学问题,我认为这是有道理的。这是一个很难回答的问题 git pull是git获取,然后是git合并 从技术上讲,这是一个git获取,然后是第二个git命令。您可以选择运行第二个命令。通常的两种方法是git合并或

git pull是git获取,然后是git合并。但是,具体地说,为什么一个git合并时不先进行获取呢?i、 e.为什么可能将一个看似单一的操作分解为两个子操作?

也许如果你出于某种原因在没有合并的情况下进行提取,然后你只是合并,因为你知道从哪里提取它存在问题?

我看这已经被否决了,但作为一种哲学问题,我认为这是有道理的。这是一个很难回答的问题

git pull是git获取,然后是git合并

从技术上讲,这是一个git获取,然后是第二个git命令。您可以选择运行第二个命令。通常的两种方法是git合并或git rebase。有时候,GitPull很少会以运行GitCheckout作为其第二个命令而告终,但这不是一个您可以通过选项选择的命令。如果在完全空的存储库中运行git pull,就会发生这种情况。我没有检查孤儿分支上发生了什么,但这也是git pull运行git checkout的合理位置,因为这与新的完全空的存储库中的情况相同

但是,为什么一个git合并时不先抓取呢

你为什么要写代码?为什么要这么做?从某种意义上说,答案只是因为我想。那为什么要合并呢?因为你想。但这只是把问题推到了另一个层面:你为什么要这么做?为什么要运行git merge

要回答这个问题,我们应该看看git merge可以做什么。从中的高级概述来看,运行git merge的结果是什么有四种可能性:

什么都没有:GitMerge说没有要合并的东西,或者我们给它的参数无效,或者有错误,等等。这可能不是我们想要运行git merge的原因,但这是一种可能性,所以我们必须将其保留在列表中

我们得到了Git所称的快进合并,实际上根本不是合并。那可能是我们想要的!也可能不是。这里我不想详细介绍,只想说快进合并实际上更像是签出我们在merge命令中命名的提交,并将分支名称向前拖动到这里

我们得到一个或多个合并冲突,合并在中间停止。这可能不是我们想要的,但它可能是实现我们真正想要的道路上的绊脚石

我们得到一个合并提交,它在其他方面与任何普通提交类似——一个新的提交,它添加到当前分支,只是它有一个额外的父提交。这意味着,当我们在存储库中查看历史时,请记住,存储库中的历史由存储库中的提交组成,我们在视图中会有一个分支,这样我们可以继续沿着该分支的主线进入过去,或者沿着合并的另一段进入过去

最后一个得到最终合并提交可能就是我们运行git merge的原因。事实上,如果我们想确保获得合并提交,即使git merge可以执行快进,我们也应该运行git merge-no ff

然而,有时候,我们想要的是快速前进。在这种情况下,我们应该只使用git merge-ff。如果无法进行快进,则会产生错误并导致合并失败,而不是生成合并提交

这仍然不能回答问题 与之前一样,这只是将问题推向了另一个层次:为什么我们想要或不想要合并提交?我们至少看到了合并提交是什么:历史上的一个分支。记住,当我们向前工作,进行新的提交时,Git向后工作。因此,当我们合并两个历史时,向后视图将一个历史拆分为两个

要了解为什么我们可能想要像这样分割历史,我们必须像Git那样向后思考。请记住,每次提交都会保存一个快照,因此,为了获得更改,我们必须将该快照与以前的某个快照进行比较。使用普通的非合并提交,这很容易:

...--P--C--...
这里C是父提交p的子提交。只有一种方法,从C返回到p。C中的更改是p中的快照和C中的快照之间的不同之处。这就是git show hash-of-C将向我们展示的内容,或者git log-p将向我们展示的内容

但是,在合并提交时,有两个父级:

...--P1
       \
        C--...
       /
...--P2
为了查看P1和C之间发生了什么,我们让Git比较这两个快照。为了查看P2和C之间发生了什么,我们让Git比较这两个快照。因此,如果我们希望能够看到这两组更改,我们需要记录两个父项

这是获得合并提交的一个可能动机,这反过来会激励我们运行git merge。现在让我们看另一个

Git如何找到提交 Git中的提交是有编号的,但编号看起来是随机的。它们实际上根本不是随机的:e ach数字是提交内容的加密校验和。这样,每一个都是唯一的。1 Git然后存储这些提交和其他内部Git对象,这些对象在。因此Git查找提交的方式是通过它的哈希ID。如果您在整个存储库中记住了每个哈希ID,那么您只需提供哈希ID即可恢复提交

问题是,没有人想记住散列ID。幸运的是,没有必要这样做。每个提交都已经存储了其父级或父级的哈希ID,因此我们和Git所需要的只是能够在某个提交链中存储最后一次提交的哈希ID。我们使用分支机构名称执行此操作:

变成:

...--G--H--I   <-- branch
我们添加了第二个分支名称branch2,它也指向提交H。然后我们在branch1上进行了两次新的提交,因此我们有:

          I--J   <-- branch1
         /
...--G--H   <-- branch2
          I--J   <-- branch1
         /
...--G--H
         \
          K--L   <-- branch2

从最后两个提交J和L开始向后看,这两个历史记录在提交H处合并。如果这看起来很重要或有利,那么,现在您开始理解Git了。要合并他们在本地已经拥有的东西,而不需要从远程获取?本地东西从何而来?例如,如果您创建了一个分支来处理特定功能,完成了它,并希望将该工作合并回主干中。您可以在不触碰遥控器的情况下完成这一切。您是否仍然需要从功能分支提取并从中合并?如果该分支已经在您的本地存储库中,则您不会;fetch用于从远程获取本地没有的任何更改:为什么这不是在没有fetch的情况下进行合并的有效原因?您已经从main获取了一些dev,您知道在获取之后main上的代码出现了问题,所以您在不进行另一次获取的情况下进行了合并。我为自己创建了一个别名git mff,它只运行git merge-ff。如果我正在做一些积极的开发工作,我倾向于运行git fetch,然后运行git mff,如果失败了,我知道我应该检查一下是否应该重新设置基址。这是一个快捷方式实际上看起来更好,但取决于我有多匆忙,我发现它有时是一个有用的快捷方式。git pull命令确实允许您传递-ff only标志,甚至在中配置它,但出于某种原因,我不喜欢这样做。我不能100%确定原因,但我可以指出一个相当可靠的原因:有时我以其他用户的身份运行,帮助其他人,或者登录到服务器,或者其他什么,但没有我的个人设置。在这种情况下,运行git mff就失败了,我记得我必须把它全部解释清楚。感谢您如此全面的回答。我真不敢相信它已经结束了,这个问题需要更加关注。没有更简单的方式来陈述它,而你提供的一般推理正是我们所需要的。。。从某种意义上说,这个问题和答案是对StackOverflow的滥用,它应该是关于一个特定技术问题的小答案,而不是关于生活意义问题的大哲学类型的答案,对于计算机软件来说,可能属于软件工程网站。答案很好,在其他任何地方都找不到。我注意到这个问题刚刚使我的SO声望提高了+10,尽管反对票阻止我再问一个SO问题。
...--G--H   <-- branch1
          I--J   <-- branch1
         /
...--G--H   <-- branch2
          I--J   <-- branch1
         /
...--G--H
         \
          K--L   <-- branch2