内容简介:我们在日常开发中使用 Git 做分支合并的时候有两种方式:merge 和 rebase。merge 是最常用的,rebase 使用的没有 merge 这么多,那么 rebase 和 merge 有什么区别呢?什么时候使用 rebase?使用 rebase 的时候有什么注意事项呢?接下来我来介绍下这三个问题。首先我们先了解下 merge 和 rebase 的运行机制有什么不同。假设我们有两个分支(master 和 feature)。feature 是基于 master 的 C1 节点建立的分支,然后开发人员分
我们在日常开发中使用 Git 做分支合并的时候有两种方式:merge 和 rebase。merge 是最常用的,rebase 使用的没有 merge 这么多,那么 rebase 和 merge 有什么区别呢?什么时候使用 rebase?使用 rebase 的时候有什么注意事项呢?接下来我来介绍下这三个问题。
基础
首先我们先了解下 merge 和 rebase 的运行机制有什么不同。假设我们有两个分支(master 和 feature)。feature 是基于 master 的 C1 节点建立的分支,然后开发人员分别在两个分支各自开发:
merge
现在我们想要把 feature 分支开发的内容合并到 master,使用 merge 命令:
$ git checkout master $ git merge feature
Git 会把 C2 和 C3 的内容合并一下产生一个新的修改 C4,把 C4 提交到 master 分支。那么 master 就有了所有最新的代码(红色是 master 分支线,蓝色是 feature 分支线)。
rebase
我们回到还是未合并之前的状态,看看使用 rebase 合并会有什么效果。使用 rebase 有两种用法,先看第一种:
$ git checkout master $ git rebase feature
Git 把 C2 备份成 C2',删除 C2,然后把 C2' 追加到 C3 后面,把 master 指向 C2'。看图上红线,成为了新的 master,这条线上同样有所有的最新代码,起到的作用也是合并了两个分支。那么和 merge 有什么区别呢?就是历史时间线的区别。merge 保留了你所有的操作记录,而 rebase 把提交的修改节点变成了线性的时间线。如果分支 merge 很多的话,时间线会错综复杂,这个时候 rebase 的好处就出现了,对人肉追溯比较友好。
我们再看下合并两个分支 rebase 的第二种用法:
$ git checkout feature $ git rebase master $ git checkout master $ git merge feature
前两条命令我们先在 feature 上 rebase on master,产生的效果和第一种方法类似,只是把 feature 分支的改动追加到了 master 分支后面(红色是 master 分支线,蓝色是 feature 分支线)。
后两条命令是把 feature 分支 merge 到 master 分支。由于 Git 发现不需要合并代码,只需要移动头指针就可以了,所以快速移动(fast forward)头指针到最前面,master 分支这时就有所有最新代码,同样起到了合并分支的作用。
那么第一种和第二种有什么区别呢?直观的看就是时间线上 C2,C3 顺序的区别,对于我们合并分支最终的意图是没有什么区别的。
注意点
如果你是一人开发,且只有本地仓库,那么上面 rebase 用哪种问题都不会太大。但是如果你是多人协作且有远程仓库,那么区别就巨大了。因为你合并完分支之后还需要 push 到远程仓库供别人使用,当你使用第一种方法后,C2 被放到了 C3 后面,你本地的 master 时间线变成了 C1 - C3 - C2',而远程仓库 master 的时间线是 C1 - C2。虽然 C2 和 C2' 是一样的,但是两者时间线历史完全不一样了,Git 认为你这是两个不一样的分支,不允许你 push。这个时候只能用 $ git push --force 强迫提交,用本地的 master 覆盖远程仓库的 master。但是 master 分支别人还在用啊,他们也需要同步 master 分支。但是别人本地的 master 分支并不知道你 rebase 过了远程仓库的 master,所以当他们 pull master 的时候,变成了如下时间线:
其他人本地的 master 时间线上会出现两个 C2(C2 和 C2'),然后如果这人把上图的 master 再 push 到远程仓库,会带上上图所有的历史,多来几次以后整个仓库就没有办法看了。而第二种 rebase 的方法是把新的 commit 不断的追加到 master 后面,只要所有人在往 master 上合并代码的时候都遵循第二种方法,那么就不会产生极其混乱的时间线。
什么时候使用
按我们上面看到的,在现实的开发过程中,严格禁止在公共分支上 rebase on 其他分支(譬如不允许在 master 分支上直接运行 git rebase branchname)。使用 merge 是最保险的合并分支方式,如果你对时间线清晰度要求不是那么高的话。但是如果你对时间线的清晰程度有比较高的要求,那么在合并分支的时候按第二种方法 rebase 就能帮助形成清晰的线性时间线,但是 rebase 的坏处是丢失了一部分提交操作历史。
同步分支
除了合并不同分支这种情况,还有一个十分常见的情况,多人在同一个分支上开发,如何保证同一条分支具有清晰的时间线。我们假设有三个人在开发 feature 分支,通常开发习惯是:
- checkout feature 分支到本地。
- 开发,并把开发的内容提交到本地 feature。
- 使用 pull 把远程仓库中的 feature 和本地 feature 同步(pull 的默认方式是把远程的代码和本地代码做 merge 操作)。
- push 同步完的 feature 分支到远程仓库。
按上述步骤,我们看下时间线示意图:
先是第1,第2步
用户1执行3,4步
用户2执行3,4步
用户3执行3,4步
因为 pull 默认是通过 merge 远程仓库和本地仓库实现同步的,所以每次 pull 都会多出一个提交记录。但是我们可以通过指定参数来指定 pull 的时候使用 rebase 策略: $ git pull --rebase 。让我们看下每次执行第3步的时候使用 pull rebase 那么会是什么样子。
用户1执行3,4步
用户2执行3,4步
用户3执行3,4步
通过图示我们看到,如果使用 pull 的 rebase 模式,那么多人协作同一个分支也可以做到时间线清晰。最后再通过之前提到的 rebase 方式把 feature 合并到 master 分支上。那么整个开发过程时间线就呈现出清晰的时间线。
总结
- 和远程仓库同步当前分支的时候使用 pull --rebase 的方式。
- 合并分支的使用 feature rebase on master,master merge feature 的方式。
以上所述就是小编给大家介绍的《如何使用Git Rebase》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- RecyclerView使用指南(一)—— 基本使用
- 如何使用Meteorjs使用URL参数
- 使用 defer 还是不使用 defer?
- 使用 Typescript 加强 Vuex 使用体验
- [译] 何时使用 Rust?何时使用 Go?
- UDP协议的正确使用场合(谨慎使用)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Is Parallel Programming Hard, And, If So, What Can You Do About
Paul E. McKenney
The purpose of this book is to help you understand how to program shared-memory parallel machines without risking your sanity.1 By describing the algorithms and designs that have worked well in the pa......一起来看看 《Is Parallel Programming Hard, And, If So, What Can You Do About 》 这本书的介绍吧!
MD5 加密
MD5 加密工具
UNIX 时间戳转换
UNIX 时间戳转换