2

我正在使用这个问题的答案将存储库的克隆剥离到我想要保留在该项目的衍生文件中的文件列表中。假设我想剥离除目录src/main及其子目录之外的所有内容。因为我将有多个文件和目录,所以我使用--index-filter而不是--subdirectory-filter.

我认为以下应该有效:

git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ↩
  src/!(main)" --prune-empty -- --all

但我得到的只是

-bash: !: event not found

我尝试了各种不同的路径而不是src/!(main). 我总是得到确切的错误信息。这似乎是一个 bash 问题,因为该行也没有进入我的命令行历史记录?


也就是说,如果我有顶级文件A,和B,和子目录C/D,我怎么能删除除了这三个东西之外的所有东西?

4

3 回答 3

4

这 !是问题所在,因为它用于命令历史调用。在引号内,在前面加上反斜杠也无济于事,所以\! 必须是外引号。可以使用一些带有 echo 的示例来说明:

/home/user1> echo "src/!(main)"
-bash: !: event not found
/home/user1> echo "src/\!(main)"
src/\!(main)
/home/user1> echo "src/"\!"(main)"
src/!(main)
于 2012-09-24T12:43:29.327 回答
3

要回答澄清中添加的实际问题:您正在尝试使用 bash的extglob来删除. 这不起作用,因为 index-filter 命令不是由您的 shell 执行的,而是由via (请参阅 参考资料)执行的。srcmaingit index-filtersheval/usr/lib/git-core/git-filter-branch:327

这样做时你不能告诉 git 启用extglob,但你可以让你的 shell在将它传递给之前扩展extglobindex-filter

git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch $(ls -xd src/!(main))" --prune-empty -- --all
于 2013-04-03T11:09:43.113 回答
0

Bash 的语法中使用感叹号来进行历史扩展,这就是造成混乱的原因。您必须使用反斜杠或单引号对其进行转义:

git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ↩
  src/\!(main)" --prune-empty -- --all
于 2012-09-24T12:15:56.470 回答