1

我想删除 git 存储库历史记录中既不是“foo”也不是“bar”的所有文件。鉴于这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

4

3 回答 3

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

最后一张特别好看。只需删除所有内容并恢复您想要的内容。:)

于 2014-07-13T22:31:32.937 回答
2

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

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

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

于 2016-04-06T15:02:17.303 回答
0

直接的问题是sh 不支持!(foo|bar)zsh 特定的语法 [Edit: or bash with extglobturn on]。每个过滤器eval都由实现的 shell 脚本运行git-filter-branchsh通常是普通的)。

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

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

于 2014-07-13T22:19:39.607 回答