我想删除所有既不是" 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
答案 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次提交,并不重要。)