繁体   English   中英

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

[英]Difference between git pull, git fetch+merge and git rebase

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

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

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

首先,正如其他答案所示, 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将直接跳转到匹配origin/master )。

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

挤压怎么样?

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

垫底

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

如果有人在我拿走后做了什么怎么办?

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

另一种思考方式

通过将您的本地主分支视为远程的独立分支,可能很容易理解发生了什么 - 这基本上是从Git的角度来看的。

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

使用一些谷歌。 git pull = git fetch然后是git merge google git pull时首先点击: https ://git-scm.com/docs/git-pull:

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

git rebase完全不同,与遥控器无关。 再一次,google可以解决你的问题,但是一个简短的图形解释,当站在分支A上,然后在B之上重新定位(这是不同的,然后站在A上,并将B 合并 其中):

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。

从git文档

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

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

所以你可以在fetch ed之后执行git rebase FETCH_HEAD

所以,如果你有

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

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

如果你使用merge ,git会将两个分支合并为一个分支,在origin/head的顶部应用你的提交

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM