Git如何压缩分支起始点后的所有提交并保留原有提交信息
分支分叉点后所有提交Squash压缩方案
问题原因
之前使用固定提交数回退(HEAD~1)的方式存在计数误差:遇到合并提交、多分叉提交场景时,无法准确识别分叉基点位置,要么漏压提交,要么误将需要保留的基线提交纳入压缩范围。
正确实现逻辑
核心是先自动定位分支分叉的共同祖先节点(即需要保留不动的最后一个基线提交,对应示例中的70d79f9),再执行软重置收集改动与提交信息,无需手动计数提交数量:
- 自动计算分叉基点:通过
git merge-base命令获取当前分支与基线分支的最近共同祖先,完全避免手动找commit id、数提交数的误差 - 软重置到分叉基点:该操作会将基点之后所有提交的代码改动全部保留在暂存区,不会丢失任何修改
- 自动收集所有待压缩提交的说明信息:按提交时间正序拉取所有原提交的message,去重后作为新提交的说明内容
- 生成新的压缩提交,不修改基线及更早的提交记录
可直接使用的脚本
# 拉取全量远端最新提交信息 git fetch --all --quiet # 定位当前分支与对应基线的分叉点,示例基线为origin/dev,可根据实际场景替换为main等目标分支 BASE_COMMIT=$(git merge-base HEAD origin/dev) # 收集分叉点后所有提交的说明信息,按时间正序排列、自动去重 SQUASH_MSG=$(git log --pretty=format:"%s%n%b" --reverse ${BASE_COMMIT}..HEAD | awk 'NF{$1=$1};!NF||!seen[$0]++') # 软重置到分叉基点,所有待压缩改动保留在暂存区 git reset --soft ${BASE_COMMIT} # 生成压缩后的新提交,保留所有原提交说明 git commit --quiet --no-verify -m "Squashed commits after fork point" -m "${SQUASH_MSG}"
效果说明
执行完成后,提交历史与预期完全一致:
- 分叉基点(示例中
70d79f9)及更早的提交完全不受影响 - 基点之后的所有提交(包括合并提交、分叉子分支上的提交)全部压缩为单个新提交
- 所有原提交的说明信息完整保留在新提交的message中
注意事项
- 执行操作前请先暂存(
git stash)本地未提交的零散改动,避免无关改动被带入压缩提交 - 若需要将压缩后的提交推送到远端,使用
git push --force-with-lease执行安全强推,避免覆盖其他协作者的提交 - 若基线分支不是origin/dev,只需替换脚本中
git merge-base命令里的分支名即可,无需修改其他逻辑
内容的提问来源于stack exchange,提问作者alper
相关产品推荐
相关产品推荐

