Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

熟悉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 #1 from spencer-luo/feature
| |
| | 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
# 1. Create merge commit (保留历史)
git checkout main
git merge --no-ff feature # 创建合并提交

# 2. Squash and merge (压缩)
git checkout main
git merge --squash feature # 压缩成一个提交
git commit -m "Feature X"

# 3. Rebase and merge (变基)
git checkout feature
git rebase main # 变基到main
git checkout main
git merge feature # 快速前进合并

评论