【问题标题】:Git interactive-rebase across multiple branches跨多个分支的 Git 交互式变基
【发布时间】:2026-02-08 12:00:02
【问题描述】:

我有一个 git 存储库,其中包含一些我希望删除的敏感内容的源文件(我不想删除该文件,只需修改其内容)。提交是在项目开发的早期(当时我们只有一个分支),但现在在 n 个其他分支中找到了它自己。

我可以运行任何 git-fu 来在所有分支中清理它吗?交互式变基一次只能对一个 Head 起作用。

我确实在 github 上找到了 this 命令:

git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch DotNet/src/ExternalLibs/GemBox/' \
--prune-empty --tag-name-filter cat -- --all

但它只适用于删除,而不适用于修改

A-B-C-**STUPID**-D-E-F
                    \
                     \-G-H-I
                          \-J-K

【问题讨论】:

  • 修改后的内容是不是也“敏感”了?
  • 该代码包含一个带有许可证密钥的测试项目的代码文件,我们想用 shim 替换它。我们可以用新的提交来修复测试

标签: git rebase git-rebase git-rewrite-history git-branch-sculpting


【解决方案1】:

假设修改后的内容也不是敏感的,那么这可能工作:在您要修改的提交处签出一个新分支,修改文件,然后使用非交互式变基,在先前未修改的提交之后保留所有内容的合并,返回到新的修改提交:

# Checkout a branch "fix" at the commit STUPID
git checkout -b fix STUPID

# Make your file changes...

# Amend STUPID
git add .
git commit --amend -m "REDACTED MWA-HA-HA!"

# Do the BIGGEST rebase that you'll probably ever do in your entire life!
git rebase --preserve-merges --onto fix STUPID master
# or `-p` for short
git rebase -p --onto fix STUPID master

# Verify that the only difference between master and master@{1}
# is the amended content:
git diff master@{1} master

一旦您确认master 在 rebase 之前和之后的唯一区别是修改后的内容,您可能希望通过使 reflog 过期并运行 @987654325 来清除旧提交的本地和远程存储库@:

git reflog expire --expire=now --all
git gc --prune=now

您可以阅读以下可能需要执行的任何其他清理步骤:

  1. Remove sensitive files and their commits from Git history
  2. GitHub: Remove sensitive data.

顺便说一句,请先在另一个本地克隆上测试变基,然后再在你拥有的唯一副本上尝试此操作...以防万一出错了。

哦,是的,我差点忘记了,如果您在 STUPID 处的修改导致与基于它的 rebase 的提交发生冲突,那么您需要在 rebase 期间修复这些冲突。

这个 1337 git-fu 由 Cupcake提供给你:自 2012 年以来在 git repos 上进行心脏直视手术; )

【讨论】:

  • 谢谢蛋糕。我首先做的(在发布之前)是:修复文件,提交,'git rebase -i HEAD~250',将修复提交移到 STUPID 之后,然后挤压。这适用于第一个分支,但随后给我带来了(当然很少)其他人的各种痛苦。明天哭着入睡后我会试试你的解决方法:)