来源:http://jartto.wang/2018/12/11/git-rebase/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

使用 Git 已经好几年了,却始终只是熟悉一些常用的操作。对于 Git Rebase 却很少用到,直到这一次,不得不用。

一、起因

上线构建的过程中扫了一眼代码变更,突然发现,commit 提交竟然多达 62 次。我们来看看都提交了什么东西:

这里我们先不说 git 提交规范,就单纯这么多次无用的 commit 就很让人不舒服。可能很多人觉得无所谓,无非是多了一些提交纪录。

然而,并非如此,你可能听过破窗效应,编程也是如此!

二、导致问题

1.不利于代码 review
设想一下,你要做 code review ,结果一个很小的功能,提交了 60 多次,会不会有一些崩溃?

2.会造成分支污染
你的项目充满了无用的 commit 纪录,如果有一天线上出现了紧急问题,你需要回滚代码,却发现海量的 commit 需要一条条来看。

遵循项目规范才能提高团队协作效率,而不是随心所欲。

三、Rebase 场景一:如何合并多次提交纪录?

基于上面所说问题,我们不难想到:每一次功能开发, 对多个 commit 进行合并处理。

这时候就需要用到 git rebase 了。这个命令没有太难,不常用可能源于不熟悉,所以我们来通过示例学习一下。

1.我们来合并最近的 4 次提交纪录,执行:

git rebase -i HEAD~4

2.这时候,会自动进入 vi 编辑模式:

s cacc52da add: qrcode

s f072ef48 update: indexeddb hack

s 4e84901a feat: add indexedDB floder

s 8f33126c feat: add test2.js

# Rebase 5f2452b2..8f33126c onto 5f2452b2 (4 commands)

#

# Commands:

# p, pick = use commit

# r, reword = use commit, but edit the commit message

# e, edit = use commit, but stop for amending

# s, squash = use commit, but meld into previous commit

# f, fixup = like "squash", but discard this commit's log message

# x, exec = run command (the rest of the line) using shell

# d, drop = remove commit

#

# These lines can be re-ordered; they are executed from top to bottom.

#

# If you remove a line here THAT COMMIT WILL BE LOST.

#

# However, if you remove everything, the rebase will be aborted.

#

有几个命令需要注意一下:

  • p, pick = use commit

  • r, reword = use commit, but edit the commit message

  • e, edit = use commit, but stop for amending

  • s, squash = use commit, but meld into previous commit

  • f, fixup = like “squash”, but discard this commit’s log message

  • x, exec = run command (the rest of the line) using shell

  • d, drop = remove commit

按照如上命令来修改你的提交纪录:

s cacc52da add: qrcode

s f072ef48 update: indexeddb hack

s 4e84901a feat: add indexedDB floder

p 8f33126c feat: add test2.js

3.如果保存的时候,你碰到了这个错误:

error: cannot 'squash' without a previous commit

注意不要合并先前提交的东西,也就是已经提交远程分支的纪录。

4.如果你异常退出了 vi 窗口,不要紧张:

git rebase --edit-todo

这时候会一直处在这个编辑的模式里,我们可以回去继续编辑,修改完保存一下:

git rebase --continue

5.查看结果

git log

三次提交合并成了一次,减少了无用的提交信息。

四、Rebase 场景二:分支合并

1.我们先从 master 分支切出一个 dev 分支,进行开发:

git:(master) git checkout -b feature1

2.这时候,你的同事完成了一次 hotfix,并合并入了 master 分支,此时 master 已经领先于你的 feature1 分支了:

3.恰巧,我们想要同步 master 分支的改动,首先想到了 merge,执行:

git:(feature1) git merge master

图中绿色的点就是我们合并之后的结果,执行:

git:(feature1) git log

就会在记录里发现一些 merge 的信息,但是我们觉得这样污染了 commit 记录,想要保持一份干净的 commit,怎么办呢?这时候,git rebase 就派上用场了。

4.让我们来试试 git rebase ,先回退到同事 hotfix 后合并 master 的步骤:

5.使用 rebase 后来看看结果:

git:(feature1) git rebase master

这里补充一点:rebase 做了什么操作呢?

  • 首先,git 会把 feature1 分支里面的每个 commit 取消掉;

  • 其次,把上面的操作临时保存成 patch 文件,存在 .git/rebase 目录下

  • 然后,把 feature1 分支更新到最新的 master 分支;

  • 最后,把上面保存的 patch 文件应用到 feature1 分支上;

从 commit 记录我们可以看出来,feature1 分支是基于 hotfix 合并后的 master ,自然而然的成为了最领先的分支,而且没有 merge 的 commit 记录,是不是感觉很舒服了。

6.在 rebase 的过程中,也许会出现冲突 conflict。在这种情况,git 会停止 rebase 并会让你去解决冲突。在解决完冲突后,用 git add 命令去更新这些内容。

注意,你无需执行 git-commit,只要执行 continue

git rebase --continue

这样 git 会继续应用余下的 patch 补丁文件。

7.在任何时候,我们都可以用 --abort 参数来终止 rebase 的行动,并且分支会回到 rebase 开始前的状态。

git rebase —abort

五、更多 Rebase 的使用场景

git-rebase 存在的价值是:对一个分支做「变基」操作。

1.当我们在一个过时的分支上面开发的时候,执行 rebase 以此同步 master 分支最新变动;
2.假如我们要启动一个放置了很久的并行工作,现在有时间来继续这件事情,很显然这个分支已经落后了。这时候需要在最新的基准上面开始工作,所以 rebase 是最合适的选择。


六、为什么会是危险操作?

根据上文来看,git-rebase 很完美,解决了我们的两个问题:
1.合并 commit 记录,保持分支整洁;
2.相比 merge 来说会减少分支合并的记录;

如果你提交了代码到远程,提交前是这样的:

提交后远程分支变成了这样:

而此时你的同事也在 feature1 上开发,他的分支依然还是:

那么当他 pull 远程 master 的时候,就会有丢失提交纪录。这就是为什么我们经常听到有人说 git rebase 是一个危险命令,因为它改变了历史,我们应该谨慎使用。

除非你可以肯定该 feature1 分支只有你自己使用,否则请谨慎操作。

结论:只要你的分支上需要 rebase 的所有 commits 历史还没有被 push 过,就可以安全地使用 git-rebase来操作。

七、参考:

  • rebase

  • git-rebase 使用总结

  • git 中的 rebase操作

  • git-rebase vs git-merge 详解

    ·END·

 近期热文:

  • 致敬| 她永远地离开了,但我们依然每天收益于您的伟大发明!

  • 在生产中使用Java 11:需要了解的重要事项

  • 如何在到处是“雷”的系统中「明哲保身」?这是第一招

  • 可能是最全面的G1学习笔记

  • Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)

  • 想通关「限流」?只要这一篇

  • 面试题:如何求根号2

  • Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)

点击“阅读原文”,看本号其他精彩内容

彻底搞懂 Git-Rebase相关推荐

  1. 这一次彻底搞懂 Git Rebase

    使用 Git 已经好几年了,却始终只是熟悉一些常用的操作.对于 Git Rebase 却很少用到,直到这一次,不得不用. 一.起因 上线构建的过程中扫了一眼代码变更,突然发现, commit 提交竟然 ...

  2. 20分钟教你搞懂Git!

    Git 是最流行的版本管理工具,也是程序员必备的技能之一.本文就来教你 20 分钟搞懂 Git! 以下为译文: 尽管每天你都会用到Git,但也有可能搞不懂它的工作原理.为什么Git可以管理版本?基本命 ...

  3. 20 分钟教你搞懂 Git!

    Git 是最流行的版本管理工具,也是程序员必备的技能之一.本文就来教你 20 分钟搞懂 Git! 以下为译文: 尽管每天你都会用到Git,但也有可能搞不懂它的工作原理.为什么Git可以管理版本?基本命 ...

  4. 一天彻底搞懂 Git 《Git 原理详解及实用指南》

    我是扔物线,Android 开发者,开源贡献者,在 GitHub 上有 4.9k followers 和 7.8k stars ,个人的 Android 开源库 MaterialEditText 被全 ...

  5. 好文推荐,15 分钟教你搞懂 Git!

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 译者丨Alex https://www.tutorialdocs.com/article/how- ...

  6. 一文搞懂本地和远程分支代码回退git reset

    最近痴迷于git flow,打算对之前大部分人一提起就害怕的代码回退--git reset来进行一个实践,也算是一篇操作总结,想直接看结论的可以拉到文末,如有纰漏,欢迎大佬们指正补充. git进阶之路 ...

  7. Git学习总结(24)——彻底搞懂 Git-Rebase

    使用 Git 已经好几年了,却始终只是熟悉一些常用的操作.对于 Git Rebase 却很少用到,直到这一次,不得不用. 一.起因 上线构建的过程中扫了一眼代码变更,突然发现,commit 提交竟然多 ...

  8. 一文带你读懂Git中的rebase与fast-forward

    在项目开发的过程中,git作为版本管理工具重要性不言而喻.平常大家肯定会使用merge命令来合并分支.然而merge来合并分支有个缺点,就是当分支太多,合并太多,那么提交记录的图谱看起来就非常丑. 以 ...

  9. git rebase 变基

    概念 变基(Rebase)也是合代码的一种手段. 变基与合并(Merge)不同的是,他可以修改历史,使用rebase来代替merge合代码的话,得到的历史记录是一条直线提交历史,无分叉,很漂亮. 然而 ...

  10. 从git commit号码 revert_git revert amp; git rebase amp; commit 分支图

    今天学了几个git技巧,分享下: 问题一:上线后的代码出现问题,如何回滚代码? 代码合入master之后,上线发现有问题,其他同事也等待上线,怎么办? 使用git revert .参考 How to ...

最新文章

  1. javascript组件_是的,JavaScript运行Swift。 无论如何都要构建您的组件库。
  2. Maven最全教程,看了必懂
  3. 【干货】mysql建表语句注释
  4. 计算几何 - XOJ 1171 线段求交
  5. HDU 3641 Treasure Hunting(阶乘素因子分解+二分)
  6. 企业云桌面-01-安装第1台域控制器和第1台DNS服务器-011-DC01
  7. 神技能!在上司靠近座位时,用人脸识别技术及时屏幕切换
  8. 单片机定时器实验报告C语言,51单片机定时器实验报告.doc
  9. 移动通信基础(5)信道估计
  10. vi/vim显示行号
  11. Linux管道通信多次读写,linux进程通信之(二):管道的读与写
  12. 动态修改 DHTML Gantt甘特图皮肤样式
  13. elasticsearch-analysis-ik中文分词插件安装及配置Ik自定义词典+拼音分词
  14. 深入理解JVM4:内存结构篇(方法区)
  15. 关于*.ttf *.otf * .ttc等字体格式转换成我们想要的css文件
  16. 在虚拟机安装中Docker及一些基础命令
  17. R155附录5 Part A
  18. 大数据学习之路(转载)
  19. windows文件读取 xxe_XXE任意文件读取(当xml解析内容有输出时)
  20. 《阿猫阿狗2》和《芝麻开门》的相似之处

热门文章

  1. 内网渗透测试:隐藏通讯隧道技术(上)
  2. python3 读写中文文件
  3. linux snap 沙盒化软件包格式 简介
  4. python3 类字符串名实例化对象
  5. excel 打开显示安装office自定义项 安装期间出错
  6. 添加RichEdit控件导致MFC对话框程序无法执行的解决方法
  7. Ubuntu快速截图
  8. python股票编程规范_Python 编程规范梳理
  9. php javabean对象,Struts2 bean标签:创建并示例化一个JavaBean对象
  10. java中路径中参数化_Azure数据工厂:参数化文件夹和文件路径