如何使用git filter-branch从我的仓库中删除一个文件?(“你需要从工作树的顶层运行此命令”)

3
根据git文档,我可以这样从我的repo历史记录中删除文件:
git filter-branch --tree-filter 'rm -rf filename' HEAD

我尝试过这个,但出现了错误:
You need to run this command from the toplevel of the working tree.

所以,我尝试了这个,并得到了相同的错误:

git filter-branch --index-filter 'rm -f  /dist/bikeMap.html' HEAD

在查看了多个stackoverflow问题后,我也尝试了

git filter-branch --index-filter 'rm -f  /dist/bikeMap.html' master..HEAD
git filter-branch --tree-filter 'rm -f  /dist/bikeMap.html' --all
git filter-branch --tree-filter 'rm -f  /dist/bikeMap.html' --  --all
git filter-branch --tree-filter 'rm -f  /dist/bikeMap.html' master

等等。所有的都显示相同的错误。

git status 显示如下:

On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean

我的git版本是2.11.0

编辑:我现在也尝试过:

git filter-branch --index-filter "git rm --cached --ignore-unmatch dist/bikeMap.html" HEAD
git filter-branch --index-filter "git rm --cached --ignore-unmatch dist/bikeMap.html" -- HEAD
git filter-branch -f --index-filter 'git rm --cached --quiet --force "dist/bikeMap.html"' --prune-empty -- HEAD
git filter-branch -f --index-filter 'git rm --cached --quiet --force dist/bikeMap.html' --prune-empty -- HEAD
git filter-branch -f --index-filter 'git rm --cached --quiet --force dist/bikeMap.html' --prune-empty -- master
git filter-branch -f --index-filter 'git rm --cached --quiet --force dist/bikeMap.html' --prune-empty master
git filter-branch -f --index-filter 'git rm --cached --quiet --force /dist/bikeMap.html' --prune-empty master
git filter-branch -f --index-filter 'git rm --cached --quiet --force /dist/bikeMap.html' --prune-empty HEAD

同样的错误。

编辑:进展!

git filter-branch --index-filter 'git rm --cached --quiet --force dist/bikeMap.html' --prune-empty

导致错误。
Rewrite 419e8702fd8a5fe9ddad59a0fd7ff008edffdeab (1/47) (0 seconds passed, remaining 0 predicted)    
fatal: pathspec 'dist/bikeMap.html' did not match any files
index filter failed: git rm --cached --quiet --force dist/bikeMap.html

如果我运行ls dist/bikeMap.html,我会得到:
dist/bikeMap.html

所以,它确实存在。 如何使用git filter-branch从我们的仓库中删除文件?

你是在裸仓库中运行它吗? - VonC
此外,如果您的文件不在每个提交中,请考虑使用--ignore-unmatch - Romain Valeri
@VonC 在这个上下文中,“bare”是什么意思? - Caleb Jay
一个没有文件、工作树,只有 .git 内容的仓库。 - VonC
嗯,它肯定有文件。 - Caleb Jay
1个回答

3

要使用--tree-filter,请将您的rm命令从使用/dist/bikeMap.html更改为使用dist/bikeMap.html,即删除前导斜杠。

要使用--index-filter,请将您的命令更改为git rm --cached --ignore-unmatch dist/bikeMap.html,即使用带有额外选项的git rm(并删除前导斜杠)。

(索引过滤器会快得多。如果您只想从所有具有该一个命名文件的提交中删除一个具名文件,请使用带有git rm --cached --ignore-unmatch的索引过滤器。)


正确。在这种情况下,应该使用 --index-filter,因为它更快。以下命令应该可以工作:git filter-branch -f --index-filter 'git rm --cached --quiet --force "filename"' --prune-empty -- HEAD - Romain Warnan
哎呀,我一定是完全不理解git filter-branch的工作原理,这仍然没有起作用。我已经将所有尝试添加到“编辑”下的问题中了。 - Caleb Jay
1
保留“--”,在其后列出您想要filter-branch处理的所有分支和标签名称,或者使用“--all”。使用“HEAD”表示“当前分支名称(仅)”。随意使用“--prune-empty”;如果您没有在之前的filter-branch之后进行清理,请使用“-f”。如果您有必须指向新副本的注释标记,则添加“--tag-name-filter cat”。最后,请记住,filter-branch会复制提交:它将大致使您的存储库大小加倍,因为所有具有该文件的原始提交仍然存在。他们[继续] - torek
一旦所有引用名称(分支、标签、远程跟踪名称等)不再引用原始提交,它们就仅变为“未引用的”(未使用)。最终,在克隆过滤后的仓库时或立即被丢弃。只有这样,该文件才真正消失。 - torek
错误是由于省略了 --ignore-unmatch 导致的。如果在要复制的提交中没有要删除的文件,即使使用了 --forcegit rm 也会出错,除非您设置了 --ignore-unmatch 标志(此时 -f 标志无意义,但不是错误的)。 - torek

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