我正在使用this question的答案将存储库的克隆剥离到我想要保留的文件列表中。假设我想删除目录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
,我如何删除所有这三个东西?
答案 0 :(得分: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)
答案 1 :(得分:3)
要回答澄清中添加的实际问题:您尝试使用bash的 \ textglob 删除src
中的所有内容,main
git index-filter
}。这不起作用,因为索引过滤器命令是由shell执行而不是,而是由sh
通过eval
执行(请参阅/usr/lib/git-core/git-filter-branch:327
)。
git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch $(ls -xd src/!(main))" --prune-empty -- --all
答案 2 :(得分:0)
感叹号在Bash的语法中用于history expansion,这是导致混淆的原因。您必须使用反斜杠或单引号将其转义:
git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ↩
src/\!(main)" --prune-empty -- --all