Git忽略和修改过去

12
我最近才添加了一个`.gitignore`文件来忽略子目录中的一些特定数据文件。我真的希望能够回到过去并将它们从之前的提交/历史记录中删除。
这个很容易实现吗?我应该从哪里开始?

1
可能是如何永久删除存储在GIT中的文件?的重复问题。 - manojlds
这不是完全重复的;它有一个独特的解决方案。请看我的答案。 - cdhowie
5个回答

11

这将是一个两步过程:

引入.gitignore文件

为了使此方法起作用,早期提交必须包含您的.gitignore文件。所以,您需要:

  1. 检出根提交:git checkout -b temp $(git rev-list HEAD | tail -1)
  2. 添加.gitignore文件。
  3. git commit --amend
  4. 将所有现有分支变基到“temp”上。这可能会无缝进行,也可能会出现冲突,因此如果出现任何冲突,则需要调整。
  5. 检出您的工作分支并删除临时分支。

重写历史记录

现在,您可以通过此命令自动从所有分支中删除这些文件:

git filter-branch --tree-filter 'git clean -f -X' -- --all

这将重写所有分支以删除被忽略的文件。这可能需要一段时间,具体取决于您的存储库大小。


2
最后一个命令无法删除项目中的文件,是因为.gitignore会忽略已经添加到repo中的文件,但不会被git所忽略。 因此解决方案是:https://dev59.com/L3M_5IYBdhLWcg3w-4nw - Rick Love
@RickLove,运行filter-branch删除文件不就是这个意思吗? - fabspro
git filter-branch --tree-filter的文档中得知:新树将原样使用(新文件自动添加,消失的文件自动删除 - 既不受.gitignore文件的影响,也不受任何其他忽略规则的影响!)。 - kdb
@kdb 这就是 git clean -f -X 树过滤器脚本所处理的内容。 - cdhowie
@Alew,这是我能想象到的最无用的批评。它没有传达任何有关失败原因的信息。请提供您执行的确切步骤,并描述发生了什么,而不是您期望发生的情况。 - cdhowie
显示剩余3条评论

4
我刚刚完成了这个任务,参考了一些回答/评论,帮我解决了一些问题。但是还需要做一些修改。
我使用filter-branch命令在历史开始时引入了我的.gitignore文件,并将其应用于所有之前的提交记录。
这是命令:
git filter-branch --tree-filter 'git rm --cached -rf . >/dev/null ; cp ~/Desktop/new-gitignore .gitignore ; git add . ; git clean -d -X -f >/dev/null' -- --all

正如您所看到的,这里假定您的桌面上有一个想要的 .gitignore 文件的副本 (~/Desktop/new-gitignore).

我发现只有在我删除并重新添加所有文件 (git rm ..., git add .) 后,git clean 才会删除新的 .gitignore 告诉它忽略的所有文件。请注意,在清理后不必再次添加文件,因为 tree-filter 将一切都提交。

我在脚本中包含了 >/dev/null 以减少输出,但如果您想查看整个过程,可以安全地将其删除。


谢谢 - 运行得很好,尽管在历史的某个分支中有人放了一个不完整的 .gitignore。顺便说一下,现在 git 警告不要使用 git-filter-branch,而是使用 git filter-repo 等工具。我忽略了这个警告! - Dipstick

1
请参考从每个提交中删除文件部分。这正是你的情况。
但要小心,因为像每个历史重写一样,此功能会更改每个提交。因此,如果您有公共仓库,而某人可能已经基于它进行了一些工作-那将导致问题。

0

0

git filter-branch 是一种可能的解决方案。在使用它之前,请确保您理解其影响,因为更改是永久性的。您将无法轻松地将过滤后的分支与旧分支合并。

git filter-branch --index-filter 'git rm --cached --ignore-unmatch 文件名' HEAD

将文件名替换为您想要删除的特定文件。


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