跨多个分支进行Git交互式变基

6
我有一个 git 仓库,其中包含一些敏感内容的源文件,我希望删除它们(我不想删除该文件,只是修改其内容)。此提交是项目开发早期(当时我们只有一个分支)完成的,但现在已经存在于其他 n 个分支中。
是否有任何 git 技巧可以在所有分支中清除它?交互式 rebase 只能一次处理一个 Head。
我在 GitHub 上找到了这个命令:
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

修订后的内容难道也不是“敏感”的吗? - user456814
代码包含一个测试项目的代码文件和一个许可证密钥,我们想要用一个shim替换它。我们可以通过一个新的提交来修复这些测试。 - Jon Bates
1个回答

3
假设修改后的内容也不敏感,那么这可能有效:在您想要修改的提交处检出一个新分支,修改文件,然后使用一个非交互式合并,将先前未修改的提交后的所有东西保留合并到新的修改提交上:
# 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之前和之后的唯一区别是修改后的内容,您可能希望通过过期reflog并运行git gc来清除旧的提交,从而清除本地和远程repos中的旧提交:

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

您可以在以下链接中了解可能需要执行的任何其他清理步骤:

  1. 从Git历史记录中删除敏感文件及其提交
  2. GitHub:删除敏感数据

顺便说一句,在您尝试对唯一的存储库副本进行此操作之前,请先在另一个本地克隆上测试rebase,以防万一出现问题。

哦,是的,我差点忘了,如果您在STUPID处进行的修改与正在重新基于其上的提交发生冲突,则需要在rebase过程中解决这些冲突。

这些1337 git-fu由Cupcake为您呈现:自2012年以来在git存储库上执行开放心脏手术 ;)


谢谢,小蛋糕。在发帖之前,我做的第一件事是:修复文件,提交,'git rebase -i HEAD~250',将 fixup 提交移动到 STUPID 之后,并压缩。这对于第一个分支起作用,但对于其他(虽然很少但仍有)来说则带来了各种痛苦。我会在明天尝试您的解决方法,在哭完之后入睡:) - Jon Bates

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接