优秀!原来华为是这样使用 git rebase的

原文:
使用git参与多人之间的合作开发大概有三年的时间 , 大多数场景下使用的git命令一只手多一点就能数的过来

  • git add
  • git commit
  • git push
  • git merge
  • git pull
  • git log
理论上来说 , 只要能合理管理项目分支 , 这几个命令已经足以应付所有的日常开发工作 。 但是如果我们偶尔看一下自己的git graph , 我的天呐 , 为什么会这么乱 。
鉴于分支管理的混乱(或者根本就没有进行过分支管理) , 我们经常遇到一些意想不到的问题 , 因此需要使用很多面生的git命令来解决我们的问题 , 比如说本文讲到的git rebase 。
git rebase 和 git merge 区别Git rebase 的中文名是变基 , 就是改变一次提交记录的base 。 在这一环节 , 我们不妨带着这样一个假设:git rebase ≈ git merge , 并用两种命令实现同一工作流来对比他们之间的异同 。
回想我们日常的工作流 , 假设a和b两人合作开发 , 三个分支:develop, develop_a, develop_b 。 两个人分别在develop_a和develop_b分支上进行日常开发 , 阶段性地合入到develop 。
那么从a的角度来看 , 可能的工作流是这样的:
(1)个人在develop_a分支上开发自己的功能
(2)在这期间其他人可能不断向develop合入新特性
(3)个人功能开发完毕后通过merge 的方式合入别人开发的功能
git merge
优秀!原来华为是这样使用 git rebase的文章插图
上图为日常merge 工作流 , 对应的git操作命令如下:
git checkout develop_a// 本地功能开发...git pull origin develop = git fetch origin develop + git merge develop复制代码git rebase同样走完这样一个工作流如果我们使用git rebase来实现 , 结果如下:
git rebase 之前 , 如图:
优秀!原来华为是这样使用 git rebase的文章插图
git rebase 之中 , 如图:
优秀!原来华为是这样使用 git rebase的文章插图
git rebase 之后 , 如图:
优秀!原来华为是这样使用 git rebase的文章插图
git rebase 操作对应命令如下:
git checkout develop_a// 本地功能开发...git fetch origin developgit rebase developgit checkout developgit merge develop_agit br -d develop_a 复制代码由此可见 , git rebase 和git merge的异同之处如下:
(1)两者都可以用于本地代码合并
(2)git merge 保留真实的用户提交记录 , 且 在merge时会生成一个新的提交
(3)git rebase 会改写历史提交记录 , 这里的改写不仅限于树的结构 , 树上的节点的commit id也会别改写 , 因此图3和图4用e'代表图2的e' , 收益是可以保证提交记录非常清爽
如何使用git rebase -i 修改历史提交记录git rebase -i , 中文名叫交互式变基 。 意思就是在变基的过程中是可以 掺入用户交互 的 , 通过交互过程我们可以主动改写历史提交记录 , 包括修改、合并和删除等 。 我们以上面使用rebase后得到的提交记录为例 , 来进行历史提交记录的修改 , 在修改之前 , 提交记录是这个样子的 。
优秀!原来华为是这样使用 git rebase的文章插图
使用git rebase -i 修改历史提交的过程主要包含三步:
(1)列出一个提交记录的范围 , 并指出你在这个范围内需要对哪些记录进行什么样的修改
(2)以次执行上述的修改 , 如果遇到冲突需要解决
(3)完成rebase 操作
以上面截图中的提交记录为例 , 来对历史提交的commit msg进行修改 , 操作步骤如下:
// 查看最近6次提交记录 , 选择对哪一条记录进行修改git rebase -i HEAD~6复制代码
优秀!原来华为是这样使用 git rebase的文章插图
执行完上述命令后 , 会以vim的方式打开一个文件 , 文件中显示了最近6次的提交信息 , 从上到下 , 由远到近 。
从下面的注释可以看到 , 我们分别把每一行前面的pick修改成r, s, d的方式就可以实现对历史记录的修改 , 合并和删除 。
首先我们尝试修改提交信息 , 把第二行前面的pick改成r , 保存退出 。 当前页面关闭的同时会打开一个新的页面 , 让你对选中的提交信息进行编辑 。
优秀!原来华为是这样使用 git rebase的文章插图
编辑完信息之后保存退出 , 就完成了对历史提交记录的修改 。 通过观察下图可以发现 , develop_a的提交记录中的commit msg 仍然是feat_c , 但是develop 分支中对应的提交记录 , commit msg 已经变成了feat: c-update. 。