开发者学堂课程【Git 从入门到进阶:Git 的十年变化(七)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1194/detail/18121
Git 的十年变化(七)
内容介绍
一、git rebase 的使用
二、特性分支和主干间解决冲突的方法
三、交互式 -- rebase
四、其他几种常见指令及内容
五、黄金法则
一、Git rebase 的使用
Git rebase 可以整合不同分支间的变更还可以重建提交历史,熟练掌握 git rebase 的使用技巧有助于提升研发效率和工程质量基于主干分支指向的C1创建了一个特性分支,在特性分支上新增了 C2、C3、C4 三个提交
同时,主干分支上又合入了其他的提交,如果要将主干分支上新引入的这些变更也整合进特性分支大家通常会选用 Merge 或 Rebase 。
Merge 和 Rebase 都具备整合分之间变更能力,二者实现手段大不相同。在特性分支上执行 git merge master 时, git 会以我方、对方以及双方最近公共祖先对应的快照执行三路合并生成新快照。
并基于此快照创建一个连接特性分支和主干的合并节点,随后调整特性分支的指向。
git merge 总是在向前推进并提交历史,并不影响提交的原始状态,而 git rebase 整合变更的方式是对提交的历史进行重写。在特性分支上执行 git rebase master 时, git 会从双方的最近公共祖先开始,将特性分支上每个提交对应的变更暂存起来,然后以主干分支指向的提交作为新起点,将暂存的变更按照顺序一一还原成新提交,
rebase 完成后,特性分支的起始点就像是从 C1 迁移到 C6 。
无论 merge 还是 rebase 特性分支最终所指向的快照完全相同。Git merge 通过三路合并生成的 C7 与 git rebase 重建出的 C4` 所对应的代码内容完全相同。
二、特性分支与主干之间解决冲突的方法
开发者发起从特性分支到主干的 pull request 希望通过评审后,将特性分支合入主干,但是因为主干分支也合入了新提交,
在 pull reques 中显示,特性分支和主干间存在冲突而无法合并,通常有两种方法解决问题:
(1)将主干分支 merge 到特性分支,并在合并时解决冲突,这样做特性分支中会引入一个合并提交,包含为解决冲突所做的修改。
(2)将特性分支 rebase 到主干的最新提交,并在 rebase 的过程中解决冲突。
使用 merge 会在特性分支中引入新提交,增加代码评审者的负担,使用 rebase 则不会。
在复杂的多人协同开发场景下,随着项目迭代的不断推进和工程复杂度的日益提高, rebase 往往会助力生成相对清爽的提交历史,进而方便追溯工程的演进历史和缺陷排查。
三、交互式---- rebase
Git rebase 会将特性分支上的提交按照原有的顺序一一搬移到新起点,而借助交互式 rebase ,可以参与 git 提交搬移的过程,从而实现提交的重排、压缩、拆分、丢弃等操作。在 git rebase 命令后追加 -i 参数,即可触发交互式 rebase 。
在特性分支上执行 git rebase -i master 时, git 会唤醒编辑器,并预加载一个文档,文档的上半部分是本次待操作的提交列表,通常被称为 TODO list 。
下半部分是交互式 rebase 中支持指令的说明文档,通过编辑文档中的 TODO list 可以定制和编排 git 搬移提交的方式,列表中每个提交默认被赋予 pick 指令。
四、其他几种常见的指令及内容
1. Reword 表示选用对应提交,但在搬移时候停下来,让用户修改提交信息。
2. Squash 表示选用该提交,但将其变更压缩到上一个提交中,不生成单独提交。
3. Drop 表示舍弃该提交以及相应的变更。
交互式 rebase 被广泛应用在不期望重设基线但又需要休整提交历史的场景中。如在特性分支上开发一段时间后,发现最近六个提交有些错误,只需要基于提交 C0 执行伪变基,可以编排 TODO list 对 C1-C6 进行调整。 TODO list 可以混用多个指令来实现更复杂的编排能力。
有交互式 rebase 存在,在开发过程中可以更聚焦于实现代码逻辑和业务功能。即使在开发中引入了相对混乱的提交历史,可以在之后进行专门的调整和修饰,让其变得逻辑清晰,方便他人进行评审。
Git rebase 在重设基线和修复历史的过程中,会产生新的提交替换老提交。
五、黄金法则
千万不要使用 rebase 处理已经被其他协作者引用的提交。
在创建提交时,可以使用 git commit--fixup 或者 git commit--squash 的方式对提交进行额外的标记,通过提交的信息中追加 fixup! 或者 squash! 前缀的方式对 rebase 指令进行预编排!在交互式 rebase 中增加 --autosquash 参数即可识别这些标记物并自动完成 TODO list 的组装。