在一个分支中撤消一个文件的所有历史记录

时间:2018-04-25 17:32:29

标签: git

我在git中创建了一个git功能分支,并完成了几个已推送到同一分支上的远程存储库的提交。在我的开发早期,我将敏感数据添加到已提交和推送的文件中。我不想从分支和历史记录中删除此文件,我只想从文件和远程存储库中删除该分支中的所有历史更改。

基本上我想让它好像我从未在源代码树中的一个文件中对分支中的任何提交进行任何更改,但保留所有其他更改。

我可以使用git filter-branch构造吗?我如何确保更改也从远程分支中删除?

1 个答案:

答案 0 :(得分:1)

您可以使用git filter-branch执行此操作。最简单的方法是使用tree-filter。 (您可以通过设置index-filter来获得更好的性能,但这对于此操作来说似乎更难,并且对于小型回购tree-filter应该没问题。)

 git filter-branch --tree-filter 'if test -f path/to/file; then git checkout master -- path/to/file; fi' -- --all

更新 - 我刚刚意识到我只回答了你的一半问题。

  

如何确保更改也会从远程分支中删除?

你最终不得不强行推动所有受影响的分支机构。这显然是历史重写,因此您需要与拥有回购副本的任何其他人协调。

理想情况下,在您开始之前,您希望他们将所有工作推向原点,然后丢弃他们的克隆;然后你做重写;然后每个人都克隆了。如果您不能这样做,那么您可以将其视为“上游rebase”(请参阅​​git rebae文档),但要意识到这意味着每个人仍然拥有敏感信息的副本。

事实上,如果其他人可能已经访问过遥控器,您也可以将回购中的所有敏感信息视为已泄露。对不起,但你不能破坏瓶子。

但是假设您仍然想要尝试消除信息的副本,那么问题是重写历史记录不足以从repos'数据库中删除数据。所以信息目前存在于

1)您当地的回购

2)遥控器

3)克隆遥控器的任何人的本地

你无法真正控制(3) - 这就是为什么你可能只需要考虑被泄露的信息。一般来说,处理(2)最简单的方法是删除并重新创建仓库(虽然取决于托管远程的方式,但您可能还有其他选择)。

你有更多选项(1),但最简单的方法是更换本地仓库,即重新克隆它。例如,在您完成本地历史记录重写

之后
cd ..
git clone file://localhost/path/to/rewritten/repo clean_repo

然后从clean_repo

重建所有内容