解决git重复提交历史记录 的问题
一、先止损:清理所有变基残留
先把之前卡住的变基、锁文件全部清理干净,避免影响后续操作:
# 1. 强制终止所有未完成的变基 git rebase --abort # 2. 确认回到正常状态(无 rebase 提示) git status二、备份所有关键分支(防止误操作丢代码)
先把当前的uat-backup等分支备份到远程,万无一失:
# 切换到当前分支 git checkout uat-backup # 新建最终备份分支 git checkout -b uat-backup-final # 推送到远程备份 git push origin uat-backup-final三、找到「无重复的干净基准提交」
找一个最早、没有任何重复提交的提交哈希(比如你之前变基的基准76035609,或更早的干净提交):
# 查看最近 100 个提交,找无重复的基准 git log --oneline --graph -100记下这个干净的提交哈希(例如:76035609)。
四、核心:构建「无重复提交」的新分支
我们基于干净基准创建新分支,只挑无重复的有效提交,跳过所有 100+ 重复提交:
步骤 1:基于干净基准创建新分支
# 切换到干净的基准提交 git checkout 76035609 # 创建新的干净分支(无任何重复提交) git checkout -b uat-clean步骤 2:批量挑选「有效、无重复」的提交
你有 100+ 重复提交,不要一个个手动 cherry-pick,用下面的方法批量过滤:
方法 A:快速跳过所有重复提交(最省事)
如果重复提交的提交信息 / 代码内容完全一致,直接用这个命令批量跳过重复:
# 从 uat-backup 分支中,只挑选「非重复的有效提交」到新分支 # 先拉取 uat-backup 的所有提交 git checkout uat-clean git cherry-pick --allow-empty --keep-redundant-commits $(git log --reverse --oneline uat-backup | grep -v "重复的提交信息关键词" | awk '{print $1}')- 把
"重复的提交信息关键词"换成你重复提交里的固定内容(比如XML规范在BL结点增加字段)。 - 这条命令会自动跳过所有包含该关键词的重复提交,只保留有效提交。
方案 1:用 Git Bash 执行命令(推荐,无需改代码)
这是最简单的方式,直接用 Git 自带的 Git Bash 终端(兼容所有 Linux 命令如
grep/awk):- 右键点击你的项目根目录(
E:/bookingcenter)→ 选择「Git Bash Here」; - 在弹出的 Git Bash 终端里,直接执行之前的批量筛选命令:
# 替换「重复的提交信息关键词」为你实际的重复关键词(比如XML规范) git checkout uat-clean git cherry-pick --allow-empty --keep-redundant-commits $(git log --reverse --oneline uat-backup | grep -v "重复的提交信息关键词" | awk '{print $1}')✅ 优势:完全兼容之前的命令,不用改任何语法,直接执行即可。
- 如果提示分支受保护! [remote rejected] uat -> uat (pre-receive hook declined) error: failed to push some refs to
方案 1:临时解除保护分支限制(需管理员权限)
如果你的账号有 GitLab 项目「管理员 / 维护者」权限,可临时解除限制后推送,推送完成后立即恢复保护:
步骤 1:登录 GitLab 项目后台
打开仓库地址:
https://enter(替换成你的实际地址),登录后进入:「Settings」→「Repository」→「Protected branches」(保护分支设置)。步骤 2:修改 uat 分支的保护规则
找到「uat」分支的保护规则,点击「Edit」;- 取消「Prevent force pushes」(禁止强制推送)的勾选;
- (可选)限制只有你的账号能强制推送(在「Allowed to force push」中添加你的账号);
- 点击「Save changes」保存。
步骤 3:执行强制推送(清理重复提交)
回到本地终端,重新执行推送命令:
git push origin uat --force-with-lease步骤 4:立即恢复保护规则(关键!)
推送完成后,回到 GitLab 保护分支设置页面,重新勾选「Prevent force pushes」,恢复受保护状态(避免分支被误操作)。
五、用新分支替换原 uat 分支(清理远程重复记录)
新分支已经没有 100+ 重复提交了,现在用它覆盖旧的uat分支:
# 1. 切换到原 uat 分支 git checkout uat # 2. 把 uat 分支重置为干净的新分支(覆盖本地历史) git reset --hard uat-clean # 3. 强制推送到远程 uat(彻底清理远程的所有重复提交) git push origin uat --force-with-lease六、最后:清理临时分支(可选)
确认远程 uat 已经干净、代码正常后,删除本地临时分支:
git branch -D uat-clean git branch -D uat-backup # 确认备份在 uat-backup-final 后再删关键注意事项(必看)
- 强制推送风险:
--force-with-lease是安全的强制推送,但推送后必须通知团队成员,让他们执行以下命令同步本地: git fetch origin git checkout uat git reset --hard origin/uat重复提交彻底消失:新分支只保留有效提交,100+ 重复提交会被完全跳过,远程历史彻底干净。
代码完整性:整个过程只跳过重复提交,不修改有效代码,功能不受影响。
一句话总结
不要再用
rebase硬扛 100+ 重复提交了!基于干净基准新建分支 → 跳过所有重复提交 → 强制覆盖远程 uat,这是最快、最稳的解决方式。
