Git 从历史记录中删除某些提交,但保留他们的更改

Git remove certain commits from history, but keep their changes

场景如下:

我已将 PHP CMS 更新到新版本。在这样做时,指南建议在用新文件替换旧文件之前保留旧文件。是的,这很愚蠢,因为我可以使用 Git 进行时间旅行。我没有。

我做了什么:

  1. 将某些包含源文件的文件夹重命名为 "old_whatever"。这些文件夹总共包含几千个文件。
  2. 提交更改。
  3. 粘贴新文件夹。我们现在有两倍的几千个文件。
  4. 提交更改。
  5. 更新 CMS。
  6. 删除旧文件夹。
  7. 提交更改。

砰。现在,git 有一些非常大的提交,因为所有文件实际上都被复制了。我不需要将这些步骤载入历史。我确实想保持事物的当前状态,所以:我想保持文件结构与第 7 步完全相同。我想转储第 2 步和第 4 步。

额外信息:步骤1和步骤7的文件差异最多只有1%或2%左右。但是由于我采取的步骤,Git 我认为所有这些都是新文件。

当我现在尝试将提交推送到远程时,推送的更改突然从几百 MB 增加到 3.54 GB。

你想在这里实现的是一个交互式的rebase。你会告诉Git"I want to rewrite my history between commit x and commit z"。然后 git 将向您显示一个文本文件,就像一个脚本,您可以编辑它以指示您希望对每次提交执行的操作(更新其消息、删除它、与之前的提交合并等)。然后,当你完成后,保存文件,让奇迹发生。

基本命令是:

git rebase -i

我强烈建议研究此命令的工作原理,并可能在另一个存储库上执行一些测试以更好地理解。当您将管理此命令时,您将了解它的强大功能。这完全符合您当前的需求。

文档:https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History

祝你好运;)

注意:"merge" 一些提交到 1 的操作被命名为 "Squashing Commits"