内容简介:我们在日常开发中使用 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协议的正确使用场合(谨慎使用)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
OKR:源于英特尔和谷歌的目标管理利器
(美) 保罗R.尼文(Paul R. Niven)、本•拉莫尔特(Ben Lamorte) / 况阳 / 机械工业出版社 / 2017-8-1 / 59.00元
内在动机驱动,而非绩效考核驱动 尤其适用快速扩张和转型期组织 谷歌、英特尔、领英、推特、星佳等硅谷知名企业成功的法宝 OKR(目标与关键结果法)是一套严密的思考框架和持续的纪律要求,旨在确保员工紧密协作,把精力聚焦在能促进组织成长的、可衡量的贡献上。 如何更好地将OKR集成到企业现有的绩效评估体系中? 如何确保OKR由高管团队来领导,而不仅仅是HR、IT或财务等职能部......一起来看看 《OKR:源于英特尔和谷歌的目标管理利器》 这本书的介绍吧!