【问题标题】:In git how is fetch different than pull and how is merge different than rebase?在 git 中,fetch 与 pull 有何不同,merge 与 rebase 有何不同?
【发布时间】:2013-01-31 10:22:05
【问题描述】:

我只是无法理解这一点。我在网上和书籍上阅读了很多,但有些东西并没有留在我的脑海中。谁能给我以下的虚拟版本:

  • git fetch 与 pull
  • git 合并与变基

【问题讨论】:

  • 我很同情提问者。文档和建议如此繁重,并且可能的工作流程排列如此庞大,以至于人们会感到非常困惑。一个人的头刚刚爆炸,一个人不知道该问什么,只是不是那么明显。
  • 为什么不选择 pestrella 的答案作为接受?
  • @Arashsoft 因为他自 2013 年以来就没有出现过

标签: git


【解决方案1】:

获取与拉取

fetch 将从远程* 分支下载任何更改,更新您的存储库数据,但保持本地* 分支不变。

pull 将执行fetch 和另外merge 对您本地分支的更改。

有什么区别? pull 使用来自拉取分支的更改更新您的本地分支。 fetch 不会推进您当地的分支机构。

合并与变基

鉴于以下历史:

C---D---E 本地 / A---B---F---G 遥控器

merge 将两个发展历史结合在一起。它通过在远程分支上分歧后重放本地分支上发生的更改来做到这一点,并将结果记录在新的提交中。此操作保留每个提交的祖先。

merge 的效果是:

C---D---E 本地 / \ A---B---F---G---H 遥控

rebase 将接受本地分支中存在的提交,并将它们重新应用到远程分支之上。此操作会重写本地提交的祖先。

rebase 的效果是:

C'--D'--E' 局部 / A---B---F---G 遥控器

有什么区别?merge 不会改变提交的祖先。一个rebase 重写本地提交的祖先。

* 此解释假定当前分支是本地分支,并且指定为fetchpullmergerebase 的参数的分支是远程分支。这是通常的情况。例如,pull 将从指定的 分支下载任何更改,更新您的存储库,merge 会将更改下载到当前 分支。

【讨论】:

  • 这是迄今为止最简单和最好的解释,无需深入讨论每种做法。谢谢!
  • 绝对黄金答案
  • 希望我能“收藏”这个答案。也许我会把它打印出来贴在墙上。
  • 我会说我在stackoverflow中得到的最好的答案,谢谢
  • 如果 fetch 只从远程分支下载更改并更新存储库数据,但保持本地分支不变,那么如果工作目录不显示/反映更改,那么获取的意义何在?我的问题最初是我如何查看其他人所做的更改然后决定是否要将它们合并到我的工作目录中(即尝试其他人的更改以确保它不会破坏我的工作)但我仍然迷茫怎么办?我是否应该只进行 pul 和实验/探索,如果有问题,进行硬重置?
【解决方案2】:

获取与拉取

Git fetch 只是更新你的 repo 数据,但是 git pull 基本上会执行 fetch 然后合并提取的分支

What is the difference between 'git pull' and 'git fetch'?


合并与变基

来自 Atlassian SourceTree 博客,Merge or Rebase

合并将两条发展路线结合在一起,同时保留 每个提交历史的祖先。

相比之下,变基通过重写统一了开发线 从源分支更改,以便它们显示为 目标分支——有效地假装那些提交是 一直写在目标分支的顶部。

另外,请查看Learn Git Branching,这是一款刚刚发布到 HackerNews (link to post) 的不错的游戏,它教授了很多分支和合并技巧。我相信这对这件事会有很大帮助。

【讨论】:

  • 感谢 Felips.. 所以如果我从远程获取我的主分支将不会有更新?听起来我应该做更多的 rebase 而不是 merga
  • rebase 与 merge 取决于您的意图,记住 rebase 会重写所有提交历史记录。是的,如果你只获取,主分支不会改变,你必须合并(或拉)它才能应用远程更改
  • git merge <remote>/<branch>。例如,如果你是 master 分支并且你的远程被命名为 origin,你可以做git merge origin/master
  • 所以听起来我应该总是做一个 git checkout master git fetch git diff origin/master git rebase origin master
【解决方案3】:

拉取 vs 获取

我的理解是,git pull 只是一个git fetch,后跟git merge。 IE。您从远程分支获取更改,然后将其合并到当前分支。


合并 vs 变基

合并将按照命令执行;合并当前分支和指定分支之间的差异(合并到当前分支中)。 IE。命令git merge another_branch 会将another_branch 合并到当前分支中。

变基的工作方式有点不同,而且很酷。假设您执行命令git rebase another_branch。 Git 会首先在当前分支和another_branch 之间找到最新的通用版本。 IE。分支分叉前的点。然后git会将这个分歧点移动到another_branch的头部。最后,自原始分歧点以来当前分支中的所有提交都从新分歧点重播。这创建了一个非常干净的历史记录,分支和合并更少。

然而,它并非没有陷阱!由于版本历史被“重写”,因此只有在提交仅存在于本地 git 存储库中时,才应执行此操作。也就是说:如果您已将提交推送到远程仓库,则永远不要这样做。

this在线书籍中关于变基的解释非常好,插图通俗易懂。


使用变基而不是合并拉动

我实际上经常使用 rebase,但通常它与 pull 结合使用:

git pull --rebase

将获取远程更改,然后变基而不是合并。 IE。它将重播您上次执行拉取时的所有本地提交。我发现这比使用合并进行普通拉取要干净得多,这将创建一个额外的合并提交。

【讨论】:

  • 因此,如果我正在工作并进行分支,并且我想在进行推送之前将其合并回主服务器。我应该结帐 master,然后做 rebase 修复?
  • 我仍然不理解合并与变基
  • 我认为pestrella的答案提供的插图非常清楚地显示了差异。另外,请查看:git-scm.com/book/en/Git-Branching-Rebasing - 它在解释它方面做得相当不错(与答案中的链接相同,但再次为懒惰的人提供)。
【解决方案4】:

合并 - HEAD 分支将生成一个新的提交,保留每个提交历史的祖先。如果合并提交是由多个在同一分支上并行工作的人进行的,那么历史可能会被污染。

Rebase - 将一个分支的更改重新写入另一个分支,而不创建新的提交。代码历史是简化的、线性的和可读的,但它不适用于拉取请求,因为你看不到有人做了什么细微的改变。

在处理基于功能的工作流或不熟悉 rebase 时,我会使用 git merge。但是,如果我想要一个更干净、线性的历史记录,那么git rebase 更合适。欲了解更多详情,请务必查看this merge or rebase article

【讨论】:

    猜你喜欢
    • 2019-02-06
    • 2018-03-05
    • 2017-03-28
    • 1970-01-01
    • 2011-09-11
    • 2011-03-22
    • 1970-01-01
    • 2020-08-24
    相关资源
    最近更新 更多