从 git 历史记录中永久删除文件

Aks*_*nya 12 git github

假设我在 git 项目中完成了 5 次提交。

在提交 4 时,我不小心添加了credentials.json 文件并推送到存储库。
在提交 5 时,我删除了该文件并进行了提交,并将此更改推送到存储库。

目前该文件未显示在最新提交中。但是如果用户检查提交历史记录,他可以转到提交 4 并检查我的文件的内容。

如何从提交历史记录中永久删除该文件,以便该文件看起来从未添加到存储库中。

注意:-
我已经尝试过以下命令:-

git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch Credentials.json" \
  --prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

它不会引发任何错误,但该文件不会从历史记录中删除。

实际上该文件位于 /src 文件夹内。但奇怪的是,当我给出以下命令(包括完整路径)时:-

git filter-branch --force --index-filter   "git rm --cached --ignore-unmatch ~full-path/src/Credentials.json"   --prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

我收到错误:- ~full-path/src/Credentials.json 位于存储库外部。

是因为我已经在提交 5 中删除了我的文件吗?在这种情况下我能做什么?
从头开始创建新的存储库是唯一的选择吗?

Sim*_*mba 13

警告:在开始以下操作之前,请务必先备份原始存储库。


无需创建新的存储库。git filter-branch作品。

不要使用完整路径git filter-branch,使用相对路径 src/Credentials.json

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch src/Credentials.json" --prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

顺便说一句,bfg对于新手来说更容易使用。(bfg接受不带路径的文件名。)

bfg --delete-files Credentials.json
Run Code Online (Sandbox Code Playgroud)

参考


小智 8

@Simba 的答案有效,但您还需要随后强制推送git push origin --force --all

所以(1)

git filter-branch --force --index-filter "git rm -rf --cached --ignore-unmatch <relative_path_to_file>" --prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

然后(2)

git push origin --force --all
Run Code Online (Sandbox Code Playgroud)


nim*_*odm 7

假设没有人克隆存储库,您可以使用git rebase -i重写历史记录并删除文件。

使用git rebase -i <commit-hash-of-commit-3>。这将打开一个编辑器,其中包含从 commit-4 开始的提交列表。您可以选择删除提交(通过删除行并保存文件)、编辑它等。

为 commit-4 选择“编辑”。保存文件。您将返回 shell,文件已添加到 git 'index' 但尚未提交。

现在您可以git rm credentials.json删除文件并git commit --amend修改提交。(更新

终于git rebase --continue要完结了。您将返回 shell,该文件将不再是存储库的一部分。

如果您稍后添加了依赖于 Credentials.json 文件的提交,则您可能会在“继续”阶段收到错误。然后,Git 在有问题的提交处停止,您可以再次使用 git 命令(重置/添加)来修改提交并继续。