Github中pull request的三种合并方式
熟悉Github的同学都知道,Github的项目发起分支的合并请求时,会有三种合并方式可供选择:
- Merge pull request(
Create a merge commit,创建合并提交)。
- Squash and merge(压缩合并)。
- Rebase and merge(变基合并)。
那你知道这三种合并方式的区别?本文将详细讲解这部分的知识。
1. 案例说明
为了更详细的描述他们之间的区别,这里举个实际的项目案例进行说明。假设有个测试项目Project,有main和feature两个分支,两个分支的操作如下:
Commit操作
1 2 3
| main分支: A — B — C feature分支(从B分叉): D — E — F
|
合并之前的Commit历史
1 2 3 4
| main分支 A -> B -> C feature分支 A -> B -> D -> E -> F
|
2. Merge pull request
2.1. 工作方式
1 2
| git checkout main git merge feature-branch
|
- 创建一个新的”合并提交”(merge commit)
- 保留分支的所有原始提交记录
- 在历史中清晰显示分支的合并点
2.2. 适用场景
- 团队协作开发
- 需要保留完整历史记录
- 开源项目通常使用这种方式
2.3. 示例结果
2.3.1. log graph
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| git log --graph
* commit c21e30adc80f7871e054ef5cabbacf2c6dbefc94 (HEAD -> main, origin/main) |\ Merge: 26ed2ce 5589288 | | Author: Spencer.Luo <spencer.luo@foxmail.com> | | Date: Wed Jan 7 09:57:39 2026 +0800 | | | | Merge pull request | | | | Add D E F | | | * commit 5589288c90accff11053b7b5a15d1417fc02dec3 (origin/feature, feature) | | Author: Spencer <spencer.luo@foxmail.com> | | Date: Wed Jan 7 09:44:58 2026 +0800 | | | | F | | | * commit 8898199e1a81947e7afa70381a26c3cee149cc51 | | Author: Spencer <spencer.luo@foxmail.com> | | Date: Wed Jan 7 09:44:25 2026 +0800 | | | | E | | | * commit 2b5a7d5c9fee60d02643e222c132629cfd16b6c1 | | Author: Spencer <spencer.luo@foxmail.com> | | Date: Wed Jan 7 09:44:10 2026 +0800 | | | | D | | * | commit 26ed2ce92acca37a71d0482c05611d546a2f307a |/ Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 09:45:39 2026 +0800 | | C | * commit 44acdc392398020909d91ce6e088dd08ba3d19d1 | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 09:43:10 2026 +0800 | | B | * commit e8e92d1233f00f28f880722b004cb9f39d6f0d0f Author: Spencer <spencer.luo@foxmail.com> Date:
|
2.3.2. Github页面的Commits记录
Github(main分支)页面点击Commits按钮看到的提交记录,是按照commit的提交时间进行排序的。
1
| A -> B -> D -> E -> F -> C -> "Merge pull request"
|
3. Squash and merge
3.1. 工作方式
- 将分支上的多个提交压缩成一个提交
- 将这个单一提交合并到主分支
- 删除分支的原始提交历史
3.2. 优点
- 保持主线历史简洁干净
- 每个功能对应一个清晰的提交
- 便于代码审查和回滚
3.3. 缺点
3.4. 示例结果
3.4.1. log graph
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| git log --graph
* commit 6aafda5fac27e2e76fca0d206396ab588097e45c (HEAD -> main, origin/main) | Author: Spencer.Luo <spencer.luo@foxmail.com> | Date: Wed Jan 7 10:42:33 2026 +0800 | | Add D E F (#1) | | * D | | * E | | * F | * commit d9e84ca4abe8e352161dcabaadc01e97cb478d5f | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 10:37:20 2026 +0800 | | C | * commit f6912d95b74e80c7e1c338f05ade56cb4dce5c6e | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 10:35:22 2026 +0800 | | B | * commit 3d579e78044687012e15f6e061f363ec6a846eb8 Author: Spencer <spencer.luo@foxmail.com> Date: Wed Jan 7 10:35:05 2026 +0800
A
|
3.4.2. Github页面的Commits记录
Github(main分支)页面点击Commits按钮看到的提交记录,feature分支的三次commit被合并成了一次。
1
| A -> B -> C -> "Add D E F"
|
4. Rebase and merge
4.1. 工作方式
1 2 3 4
| git checkout feature-branch git rebase main git checkout main git merge feature-branch
|
- 将分支的提交”重新播放”在主分支的最新提交之后
- 创建线性的历史(没有合并提交)
4.2. 优点
4.3. 缺点
- 重写了提交历史(新的提交哈希)
- 可能对协作有影响(如果分支已被共享)
4.4. 示例结果
4.4.1. log graph
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| git log --graph
* commit 371c7bb78ca9a40c73b266c6cc52afc8441febd6 (HEAD -> main, origin/main) | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 11:00:47 2026 +0800 | | F | * commit b49fd102bf6dfa07cda6346da8d788848221ee4a | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 10:59:51 2026 +0800 | | E | * commit a5bcc12a3ff3c046b328f86c52af59ea6efe9a1e | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 10:59:39 2026 +0800 | | D | * commit 59866f85e44b79da38a618cc01b1a96d090be1b6 | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 11:00:16 2026 +0800 | | C | * commit 11b7caec95f88461ac3fc20104a374de9595bec6 | Author: Spencer <spencer.luo@foxmail.com> | Date: Wed Jan 7 10:58:00 2026 +0800 | | B | * commit f40d659c1a25c78c6a45e9f82e69cce0395f5e44 Author: Spencer <spencer.luo@foxmail.com> Date: Wed Jan 7 10:57:49 2026 +0800
A
|
4.4.2. Github页面的Commits记录
Github(main分支)页面点击Commits按钮看到的提交记录,是按照commit的提交时间进行排序的。
1
| A -> B -> C -> D -> E -> F
|
5. 对比总结
5.1. 特点说明
| 特性 |
Create a merge commit |
Squash and merge |
Rebase and merge |
| 历史记录 |
保留完整分支历史 |
压缩为单个提交 |
线性历史 |
| 提交哈希 |
保留原哈希 |
新哈希 |
新哈希(rebase后) |
| 合并提交 |
有 |
有 |
无 |
| 历史清晰度 |
显示分支结构 |
非常简洁 |
完全线性 |
| 适合场景 |
团队协作、开源项目 |
功能开发、保持整洁 |
个人开发、维护线性历史 |
5.2. 对比示意图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 原始结构: D — E — F (feature) / A — B — C (main)
合并后: 1. Create merge commit: A — B — C — G |\ D E F (保留原结构)
2. Squash and merge: A — B — C — G(压缩的D+E+F)
3. Rebase and merge: A — B — C — D' — E' — F' (线性)
|
5.3. 实际Git命令对应关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| git checkout main git merge --no-ff feature
git checkout main git merge --squash feature git commit -m "Feature X"
git checkout feature git rebase main git checkout main git merge feature
|