git:清理 git 历史记录并仅在 master 中保留合并的提交

Posted

技术标签:

【中文标题】git:清理 git 历史记录并仅在 master 中保留合并的提交【英文标题】:git: Clean git history and keep only merged commits in master 【发布时间】:2021-12-26 07:35:10 【问题描述】:

在我们的 git 存储库中,我们有一个压缩合并所有提交的策略。最近有一个策略更新,一些更改与他们的本地提交详细信息合并到 master 中。有没有办法可以重写历史记录以仅保留合并的提交并删除所有本地提交。

例如,当前历史看起来像

但我想把它转换成

我尝试了rebase -i -p HEAD~3,只选择了合并的提交。我压缩/修复了所有其他本地提交,但失败了。

提前致谢。

【问题讨论】:

这能回答你的问题吗? Git: How to convert an existing `merge` to a `merge --squash`? 【参考方案1】:

在问题开始之前创建一个新分支(“添加测试文件”),cherry-pick 麻烦的合并提交到它上面,指定-m 1。精心挑选的提交将是正常的提交,因此您最终会得到您所追求的简单直接的历史记录。


我会演示。我们现在的情况很像你:

*   11ef397 (HEAD -> main) Merge branch 'br2'
|\  
| * 4d41b17 (br2) f
| * 0486755 e
* |   1283b7e Merge branch 'br'
|\ \  
| |/  
|/|   
| * 85df598 (br) d
| * c7a4077 c
* | 5e70afb b
|/  
* 47258d5 a

现在我将从b开始创建一个新分支:

% git switch -c newmain 5e70afb

精选的来了:

% git cherry-pick -m 1 1283b7e
% git cherry-pick -m 1 11ef397

就是这样。 newmain 分支包含您想要的历史记录。

为了完整起见,让我们抹去我们的足迹。我们将删除原来的main,将newmain重命名为main。我还将删除brbr2,我之前合并它们时忘记删除它们:

% git branch -D main
% git branch -M main
% git branch -D br
% git branch -D br2

这就是剩下的;没有其他提交:

* 339747e (HEAD -> main) Merge branch 'br2'
* 530f9d2 Merge branch 'br'
* 5e70afb b
* 47258d5 a

这正是你所要求的。


(警告:我们刚刚改写了历史。为了将其推送到远程,我们将不得不使用武力,并且必须提前警告所有合作者,以便他们准备好扔掉现有的本地人和之后重新克隆。)

【讨论】:

【参考方案2】:

IMO,更好的解决方案是使用git push -f

# create a new branch with current commits
git branch tmp-branch

# reset main branch to last good commit
git reset --hard <last-good-commit>

# redo merge with --squash option
git merge tmp-branch --squash

# force update to remote
git push -f origin main

【讨论】:

以上是关于git:清理 git 历史记录并仅在 master 中保留合并的提交的主要内容,如果未能解决你的问题,请参考以下文章

同步上游的提交时,如何在 Git 中清理提交历史?

如何执行 git revert 并删除合并历史记录?

# Git 大文件清理

合并后的 Git 分支和提交历史记录

Git之清除历史记录操作

在 Git 日志中仅显示一个分支的历史记录