2

I am using the answer to this question to strip a clone of a repository to a list of files I want to keep in a spin off of this project. Say I want to strip all but directory src/main and its sub-directories. Because I will have multiple files and directories, I use --index-filter instead of --subdirectory-filter.

I thought the following should work:

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

But all I get is

-bash: !: event not found

I tried all sorts of different paths instead of src/!(main). I always get exactly that error message. It seems to be a bash problem, because that line also doesn't enter my command line history?


That is to say, if I have top level files A, and B, and subdirectory C/D, how can I remove all but these three things?

4

3 に答える 3

4

!!これはコマンド履歴のリコールに使用されるため、問題です。引用符の内側では、前に円記号を付けても効果がないため、\! 引用符の外側にする必要があります。エコーを使用したいくつかの例を使用して説明できます。

/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のextglobsrcを使用して、内以外のすべてを削除しようとしmainていgit index-filterます。index-filterコマンドはシェルではなく、viaによって実行されるためsh、これは機能しませんeval(を参照/usr/lib/git-core/git-filter-branch:327)。

これを行うときにgitにextglobを有効にするように指示することはできませんが、シェルにextglobを展開させてから、次の場所に渡すことindex-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 に答える