Git 笔记:将一段旧历史压缩成一个提交

Git 笔记:将一段旧历史压缩成一个提交

一、当前 Git 图(按你给的顺序)

现在历史是:git log --oneline --graph --decorate --all

复制代码
c7a62a0
7cda46d
3340514
418ec0d
81ca762
a66af0e
fdacbcc
18ab314
9c815a8
25f8409
721bef7
6fb7708
c8ea573
76e802e

你要压缩的是这一段:

复制代码
9c815a8
25f8409
721bef7
6fb7708

也就是说:

  • 18ab314 要保留
  • c8ea573 也要保留
  • 中间这 4 个提交压缩成 1 个新的提交

二、压缩完成后应该长什么样

压缩后,Git 图应该变成:

复制代码
c7a62a0
7cda46d
3340514
418ec0d
81ca762
a66af0e
fdacbcc
18ab314
<新的压缩提交>
c8ea573
76e802e

这意味着:

  • 原来的 9c815a8 / 25f8409 / 721bef7 / 6fb7708 不再单独出现
  • 它们被一个新提交替代
  • 18ab314 以及更上面的提交都继续保留

三、核心思路

这次压缩其实不是普通 merge,而是:

  1. 先取这 4 个提交里最老的那个提交的父提交
  2. 再取这 4 个提交里最新的那个提交
  3. 在最新提交上建立临时分支
  4. 用 git reset --soft 把这 4 个提交的所有变化重新打成 1 个提交
  5. 再把主分支上它后面的提交重新接回去

四、关键边界

这次要压缩的是:

复制代码
6fb7708
721bef7
25f8409
9c815a8

注意 Git 图里是:

  • 上面新
  • 下面旧

所以这 4 个提交中:

  • 最旧的是:6fb7708
  • 最新的是:9c815a8

而 6fb7708 的父提交是:

  • c8ea573

所以我们实际上要压缩的是:

复制代码
(c8ea573, 9c815a8]

五、完整操作步骤

第 1 步:确认当前工作区干净

复制代码
git switch master
git status

要求:

  • 工作区必须干净
  • 否则不要继续

第 2 步:先做备份

复制代码
git branch backup/master-before-4commit-squash
git tag backup-before-4commit-squash-2026-04-18

作用:

  • 给当前 master 做一个安全快照
  • 失败时可以一键恢复

第 3 步:从最新提交 9c815a8 建临时分支

复制代码
git switch -c squash-4commits 9c815a8

第 4 步:把这 4 个提交压成一个提交

复制代码
git reset --soft c8ea573
git commit -m "squash: consolidate commits from 6fb7708 through 9c815a8"

git reset --soft c8ea573

作用:

  • 把当前分支指针回退到 c8ea573
  • 但保留 index 和工作区的改动

结果就是:

Git 会把:

复制代码
6fb7708
721bef7
25f8409
9c815a8

这些提交带来的全部变化,重新视为"一次待提交改动"。

git commit -m "..."

作用:

  • 把刚才这批改动一次性重新提交
  • 所以原来那 4 个提交,就被压成了 1 个新提交

压缩后,这条临时分支会变成:

复制代码
<新的压缩提交>
c8ea573
76e802e

七、把主线后续提交重新接上

此时主分支 master 还是原来的样子:

复制代码
c7a62a0
7cda46d
3340514
418ec0d
81ca762
a66af0e
fdacbcc
18ab314
9c815a8
25f8409
721bef7
6fb7708
c8ea573
76e802e

而你想保留的是:

  • 18ab314 以及它上面的所有提交

所以接下来:

第 5 步:切回 master

复制代码
git switch master

第 6 步:把 9c815a8 之后的提交重新挂到新提交后面

复制代码
git rebase --onto squash-4commits 9c815a8 master

在这里:

  • newbase = squash-4commits
  • upstream = 9c815a8
  • branch = master

它的意思是:

把 master 上 在 9c815a8 之后 的所有提交:

18ab314

fdacbcc

a66af0e

81ca762

418ec0d

3340514

7cda46d

c7a62a0

重新接到:

  • squash-4commits 的新压缩提交后面

八、压缩后的最终结构

执行完成后,Git 图会变成:

复制代码
c7a62a0
7cda46d
3340514
418ec0d
81ca762
a66af0e
fdacbcc
18ab314
<新的压缩提交>
c8ea573
76e802e

九、如何验证是否成功

复制代码
git log --oneline --graph --decorate --all

预期:

  • 原来那 4 个提交不再单独出现
  • 被 1 个新提交替代
  • 后续正式提交还在

2. 对比压缩前后的最终代码内容

如果你做过备份:

复制代码
git diff --stat backup/master-before-4commit-squash..master

结果解释

  • 没有输出
    • 说明只是历史被整理
    • 最终代码没变
  • 有输出
    • 说明代码内容变化了
    • 需要进一步检查

示例

复制代码
git图
749b23b
90c2825
9cdeda3
c607b90
f21189b
b7a89aa
27f5580
557a79f
98ce32b
压缩四次提交为一个提交
c607b90
f21189b
b7a89aa
27f5580
结果
749b23b
90c2825
9cdeda3
<新的压缩提交>
557a79f
98ce32b



git switch master
git status

git branch backup/master-before-4commit-squash
git tag backup-before-4commit-squash

git switch -c squash-4commits c607b90
git reset --soft 557a79f
git commit -m "squash: consolidate commits from 27f5580 through c607b90"

git switch master
git rebase --onto squash-4commits c607b90 master

git log --oneline --graph --decorate --all
git diff --stat backup/master-before-4commit-squash..master
相关推荐
SelectDB11 小时前
秒级弹性、最高降本 70%:SelectDB Serverless 如何重塑云数仓资源效率
大数据·后端·云原生
WhoAmI11 小时前
MapReduce框架原理解析一:InputFormat
大数据·hadoop
WhoAmI11 小时前
MapReduce框架原理解析三:OutputFormat
大数据·hadoop
WhoAmI12 小时前
MapReduce框架原理解析二:Shuffle
大数据·hadoop
大大大大晴天1 天前
Hudi技术内幕:Key Generation原理与实践
大数据
Elasticsearch2 天前
3个信号、2个环境变量、0个采集器:使用 Python 和 Elastic 的托管 OTLP 端点实现 OpenTelemetry
elasticsearch
Elasticsearch4 天前
如何通过 Claude Code 来写入 CSV 数据到 Elasticsearch
elasticsearch
得物技术5 天前
从埋点需求到规则资产:Hermes Agent 重构得物数仓工作流
大数据·llm·ai编程
久美子5 天前
AI驱动数仓建设的Harness工程实践——本体建模、知识分层与上下文工程
大数据