git pull,git fetch + merge和git rebase之间的区别

时间:2017-09-24 17:22:26

标签: git git-merge git-rebase git-pull

我对git pullgit fetch + git mergegit rebase感到困惑。 他们似乎都做了相同的功能,然后他们之间的差异特别是在提交日志方面。

如果远程和本地分支都有变化,那么在所有三种情况下,其提交将首先出现。

3 个答案:

答案 0 :(得分:3)

正如您在问题中所暗示的那样,最令人困惑的部分是了解与远程仓库相比对本地仓库的影响,以及部分对使用远程仓库的其他人的影响。

首先,正如其他答案所示,git pullgit fetch + git merge完全相同。这两个命令都是从本地repo pull / fetching +从远程到本地repo的合并的角度出发的。这发生在您在本地远程检出本地分支的同一分支上。我先讨论那些,然后压扁和重新定位。

Git Pull / Git Fetch + Git Merge

假设您已在本地签出master,然后您将从远程提取master(除非您在这些命令上使用更高级的语法或标记)。让我们将远程分支称为origin/master

origin/master提取意味着您希望从origin/master获取新的提交,并更新origin/master的本地跟踪参考,以匹配遥控器上master的实际位置。如果master在本地和远程之间出现分歧,那么将会有来自主分支的提交,直到它们到达origin/master引用的当前位置。您最近未被推送的提交将位于可能不同的本地master分支上。

然后,当合并发生时,您基本上要求将origin/master合并到本地master分支中。如果执行常规合并命令,则会导致对本地master分支的新提交,该分支将origin/master中的所有最近更改提取到您的本地master分支。如果存在冲突,您将在提交之前先解决它们。但是,如果您尚未在本地提交任何内容,则合并只需快进到新的origin/master位置,而无需执行任何其他操作(您的master只会跳转到匹配{ {1}})。

此时,如果你在其他人向遥控器推送任何其他内容之前推送,那么你的新合并提交将被推送到你的单独提交(它们看起来像一个单独的,未命名的分支),以及原始的远程提交,加上最后的新合并提交。

挤压怎么样?

你确实问过这个问题,但如果你与--squash合并,那么它将添加合并提交,但删除其他本地提交,以便历史记录中没有额外的未命名分支。有些人更喜欢这个,因为它更干净",而有些人更喜欢看所有的历史记录(即代码分歧以及合并提交中的确切内容)。

衍合

当您进行rebase时,您基本上会进行所有本地提交,并将它们重播到远程主分支上,因此它们不会显示为单独的分支。这样可以保持当地历史的完整性,而不会显示代码分歧,这也是有些人更喜欢并认为它更加干净"。这与历史是否重要等无关。

如果我拿走了其他人,该怎么办?

如果其他人忍者犯了(嗯,刚刚犯了...),因为你抓了,那么你的推动就会失败。你可以使用origin/master,但是你会完全覆盖他们的提交,所以这通常是不赞成的,因为它会为其他人创造各种各样的问题。在这种情况下,如果每个人都同意他的提交应该先进行,那么你需要再次完成这个过程(如果没有冲突,那么这很容易),但总的来说,团队需要制定政策在这种类型的事情上,一旦团队变得足够大,通常会使用拉取请求和评论来以更有序的方式管理推送。

考虑这个

的另一种方式

通过将您当地的主分支机构视为与遥控器分开的一个分支,可能很容易理解发生了什么 - 这基本上是从Git的角度来看的。

事实上,在我看来,在你准备将某些东西合并到一个远程分支之前,你总是更好地在你自己的独立分支中工作。 Git让它变得如此简单,快速,轻松,拥有一个单独的分支,这就是我的工作。

答案 1 :(得分:2)

使用谷歌。 git pull = git fetch后跟git merge。谷歌搜索git pullhttps://git-scm.com/docs/git-pull

时首次点击
  

在默认模式下,git pull是git fetch的简写,后跟git merge FETCH_HEAD。

git rebase完全不同,与遥控器无关。同样,谷歌可以解决你的问题,但是一个简短的图解说明,当站在分支A上,然后在B之上重新定位(不同于站在A上,合并 B 进入< / strong> it):

c1-c2-c3<-A
 \-c4-c5<-B

变为

c1-c4-c5-c2-c3<-A
       ^
       B

我们在这里做的是对A(我们所在的)进行不同的提交并将它们应用于B的顶部,基本上去除了分支结构。永远不会有像“合并提交”那样的“rebase提交”。这与远程控制无关,除了git pull --rebase将获取然后在远程变更之上重新设置本地更改,而不是将远程变更合并到本地提交中。再次,google.com或git-scm.com/docs。

答案 2 :(得分:0)

来自git文档

  

git pull将来自远程存储库的更改合并到当前分支中。在默认模式下,git pullgit fetch的缩写,后跟git merge FETCH_HEAD

     

rebase在另一个基本提示之上重新提交提交。

所以你git rebase FETCH_HEAD编辑后可以fetch

所以,如果你有

(*) <-- HEAD
 |
(*) <-- commit B
 \   (*) <-- origin/master
  \  /
   (*) <-- commit A

如果您使用rebase,git将回退您的HEAD以提交A并应用按日期排序的所有提交

如果您使用merge,git会将两个分支合并为一个分支,在origin/head

的顶部应用您的提交