通过删除所有文件来重写git存储库历史记录,但是" foo"和" bar"

时间:2014-07-13 21:57:03

标签: git bash git-filter-branch git-rewrite-history

我想删除所有既不是" foo"也不是" bar"在git存储库历史记录中。鉴于rm -rf !(foo|bar)用于删除当前目录中既不是" foo"也不是" bar"。我提出了以下想法:

$ git filter-branch --tree-filter 'rm -rf !(foo|bar)' --prune-empty HEAD

然而,这产生了以下错误,我真的不明白它为什么不起作用。

Rewrite 75c1ec1ef083338ca2e88db9cc6107c1630d91e9 (1/871)~/libexec/git-core/git-filter-branch: 1: eval: Syntax error: "(" unexpected

3 个答案:

答案 0 :(得分:2)

请参阅https://stackoverflow.com/a/19957874/1870481

使用

--tree-filter 'bash preserve-only.sh foo bar'

preserve-only.sh

IFS=':'
GLOBIGNORE="$*"
rm -rf *

或使用

--index-filter \
'git rm --cached -r -q -- . ; git reset -q $GIT_COMMIT -- foo bar' \
 --prune-empty

最后一个特别好。 Juste删除所有内容并恢复您想要的内容。 :)

答案 1 :(得分:2)

我使用以下代码完成了这项工作:

git filter-branch -f --tree-filter "bash -O extglob -c 'rm -rf ./path/to/!(FILENAME_TO_KEEP)'" HEAD

具体来说,将-O extglob传递给bash允许您使用感叹号语法。

答案 2 :(得分:0)

当前的问题是,!(foo|bar)是特定于zsh的语法[编辑:或打开extglob的bash],sh不支持。每个过滤器都由eval运行,该脚本实现git-filter-branch(通常为sh}。

当然,您可以直接调用zsh(或打开extglob的bash命令)来运行命令。或者你可以通过他们的(坏)名称删除不需要的文件,而不是没有好名字。

(要删除带有filter-branch的文件,使用--index-filter要快得多,这不需要检查每次提交并重新提交。但这是内部优化,只有871次提交,并不重要。)