在git中,如何获取与pull不同,并且如何合并与rebase不同?

时间:2013-02-15 12:28:55

标签: git

我只是无法理解这一点。我一直在网上和书上阅读很多东西,但有些事情并没有留在我脑海里。有人可以给我以下虚拟版本:

  • git fetch vs pull
  • git merge vs rebase

4 个答案:

答案 0 :(得分:385)

fetch vs pull

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

pull会对您当地的分支执行fetchmerge次更改。

有什么区别? pull通过拉动分支的更改来更新本地分支。 fetch不会推进您的本地分支。

merge vs rebase

鉴于以下历史:

          C---D---E local
         /
    A---B---F---G remote

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

merge的效果将是:

          C---D---E local
         /         \
    A---B---F---G---H remote

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

rebase的效果将是:

                  C'--D'--E' local
                 /
    A---B---F---G remote

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

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

答案 1 :(得分:25)

获取与拉动

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

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


Merge vs Rebase

来自Atlassian SourceTree博客,Merge or Rebase

  

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

     

相比之下,变革通过重写来统一发展的路线   来自源分支的更改,以便它们显示为   目标分支 - 有效地假装那些提交   一直写在目的地分支之上。

另外,查看Learn Git Branching,这是一款刚刚发布到HackerNews(link to post)的精彩游戏,并教授了大量的分支和合并技巧。我相信这对此事非常有帮助。

答案 2 :(得分:8)

pull vs fetch

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


merge vs rebase

合并将按命令说明;合并当前分支和指定分支之间的差异(进入当前分支)。即命令git merge another_branch将合并another_branch放入当前分支。

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

然而,它并非没有陷阱!由于版本历史记录是“重写的”,因此只有在提交仅存在于本地git仓库中时才应执行此操作。即:从不如果您已将提交推送到远程仓库,则执行此操作。

this在线图书中关于变基的解释非常好,有易于理解的插图。


使用重新定位而非合并

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

git pull --rebase

将获取远程更改,然后重新绑定而不是合并。即从上次执行拉动时,它将重播所有本地提交。我发现这比使用合并进行正常拉动要清晰得多,这将通过合并创建额外的提交。

答案 3 :(得分:0)

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

Rebase - 在不创建新提交的情况下,将一个分支的更改重写到另一个分支。代码历史记录是简化的,线性的和可读的,但它不适用于拉取请求,因为您无法看到有人做出的微小更改。

在处理基于功能的工作流程时,或者如果我不熟悉rebase,我会使用git merge。但是,如果我想要一个更干净,线性的历史,那么git rebase更合适。有关详细信息,请务必查看this merge or rebase article