我在我的存储库中有一些文件应该被忽略,我将它们添加到.gitignore,但是,当然,它们不会从我的存储库中删除。
所以我的问题是,是否有一个神奇的命令或脚本使用过滤器分支,可以重写我的历史,并轻松删除所有这些文件?或者只是一个创建提交并删除它们的命令?
我在我的存储库中有一些文件应该被忽略,我将它们添加到.gitignore,但是,当然,它们不会从我的存储库中删除。
所以我的问题是,是否有一个神奇的命令或脚本使用过滤器分支,可以重写我的历史,并轻松删除所有这些文件?或者只是一个创建提交并删除它们的命令?
当前回答
不管操作系统是什么,一个更简单的方法是
git rm -r --cached .
git add .
git commit -m "Drop files from .gitignore"
你基本上删除并重新添加所有文件,但是git add会忽略.gitignore中的文件。
使用——cached选项将文件保存在文件系统中,这样就不会从磁盘中删除文件。
注意: 有些人在评论中指出,你将失去所有文件的历史记录。我在MacOS上用git 2.27.0进行了测试,结果不是这样。如果你想检查发生了什么,在你提交之前检查你的git diff HEAD~1。
其他回答
不管操作系统是什么,一个更简单的方法是
git rm -r --cached .
git add .
git commit -m "Drop files from .gitignore"
你基本上删除并重新添加所有文件,但是git add会忽略.gitignore中的文件。
使用——cached选项将文件保存在文件系统中,这样就不会从磁盘中删除文件。
注意: 有些人在评论中指出,你将失去所有文件的历史记录。我在MacOS上用git 2.27.0进行了测试,结果不是这样。如果你想检查发生了什么,在你提交之前检查你的git diff HEAD~1。
如果你真的想要删除。gitignore文件的历史,首先将.gitignore保存在repo之外,例如/tmp/。Gitignore,然后跑
git filter-branch --force --index-filter \
"git ls-files -i -X /tmp/.gitignore | xargs -r git rm --cached --ignore-unmatch -rf" \
--prune-empty --tag-name-filter cat -- --all
注:
git filter-branch --index-filter runs in the .git directory I think, i.e. if you want to use a relative path you have to prepend one more ../ first. And apparently you cannot use ../.gitignore, the actual .gitignore file, that yields a "fatal: cannot use ../.gitignore as an exclude file" for some reason (maybe during a git filter-branch --index-filter the working directory is (considered) empty?) I was hoping to use something like git ls-files -iX <(git show $(git hash-object -w .gitignore)) instead to avoid copying .gitignore somewhere else, but that alone already returns an empty string (whereas cat <(git show $(git hash-object -w .gitignore)) indeed prints .gitignore's contents as expected), so I cannot use <(git show $GITIGNORE_HASH) in git filter-branch... If you actually only want to .gitignore-clean a specific branch, replace --all in the last line with its name. The --tag-name-filter cat might not work properly then, i.e. you'll probably not be able to directly transfer a single branch's tags properly
Git rm——cached -r。 以递归方式删除所有缓存
Git添加。 添加所有未包含在.gitignore中的文件
你将不得不提交一些在文件系统上没有真正删除的已删除文件
使用一个命令就可以了 Git rm——cached -r。&& git添加。
通过使用sed操作.gitignore语句的输出,我做了一个非常简单的解决方案:
Cat .gitignore | sed '/^#。* / d ' | sed ' / ^ \ s *美元/ d ' | sed ' s / ^ / git rm - r / | bash
解释:
打印.gitignore文件 从打印中删除所有注释 删除所有空行 在行首添加'git rm -r ' 执行每一行。
您可以手动从存储库中删除它们:
git rm --cached file1 file2 dir/file3
或者,如果你有很多文件:
git rm --cached `git ls-files -i -c --exclude-from=.gitignore`
但是这在Windows上的Git Bash中似乎不起作用。它产生一个错误消息。以下方法效果更好:
git ls-files -i -c --exclude-from=.gitignore | xargs git rm --cached
在Windows上的PowerShell工作得更好(处理路径和文件名中的空格):
git ls-files -i -c --exclude-from=.gitignore | %{git rm --cached $_}
关于在没有这些文件的情况下重写整个历史,我非常怀疑是否有自动的方法来做到这一点。 我们都知道改写历史不好,不是吗?:)