.git
ファイルを含むすべてのパスを除いて、すべてのgitサブモジュールを除外しながら、フォルダ内のすべてのディレクトリを再帰的に見つけようとします。どうすればいいですか?
説明する:
.git
ファイルは各サブモジュールフォルダのルートディレクトリにあります。このサブモジュールフォルダはどこにでも含めることができます。
テストケース
$ mkdir Test
$ cd Test
$ mkdir a
$ mkdir b
$ mkdir c
$ cd a
$ mkdir .git
$ cd ..
$ cd b
$ touch .git
$ cd ..
$ cd c
$ mkdir c1
$ mkdir c2
$ cd..
$ find . -type d \( \( ! -name . -exec [ -e {}/.git ] \; -prune \) -o \( \( \
-name .git\
-o -name .vscode\
-o -name node_modules\
-o -name Image\
-o -name Rendered\
-o -name iNotebook\
-o -name GeneratedTest\
-o -name GeneratedOutput\
\) -prune \) -o -print \) | sort
期待されるパフォーマンス
.
./a
./c
./c/c1
./c/c2
答え1
find
タスクもテストなので、以下を使用してテストを追加できます-exec
。
find . \( -exec [ -f {}/.git ] \; -prune \) -o \( -name .git -prune \) -o -print
これは3つのワークセットに適用されます。
-exec [ -f {}/.git ] \; -prune
次の名前のファイルを含むディレクトリのクリーンアップ.git
-name .git -prune
指定されたディレクトリをクリーンアップします.git
(したがって、コマンドは.git
リポジトリのホームディレクトリ内で検索されません)。-print
上記で取り込まれていない内容を印刷します。
ディレクトリのみを一致させるには、-type d
before-print
または(ファイル処理時間を節約するため)を追加します。
find . -type d \( \( -exec [ -f {}/.git ] \; -prune \) -o \( -name .git -prune \) -o -print \)
.
find
これは、次のディレクトリ以外でこのコマンドを実行するときにも機能します。
find /some/other/path -type d \( \( -exec [ -f {}/.git ] \; -prune \) -o \( -name .git -prune \) -o -print \)
答え2
再帰を作成できますfind
。
スクリプトファイルに次の行を追加します。
#!/bin/bash
if [ ! -f "$1"/.git ]; then
echo "$1"
find "$1" -mindepth 1 -type d -prune -exec "$0" {} \;
fi
ファイル名をとして指定しましたが、findifnotgit
問題ありません。その後、実行可能にします。
chmod u+x findifnotgit
次に、引数として実行したいパスを使用して実行します。
./findifnotgit .
-->.
現在のディレクトリの場合
または
./findifnotgit /path/to/search/
説明する:
if [ ! -f "$1"/.git ]; then ... fi
.git
$1
現在のフォルダ()にファイルがない場合にのみ、次のコマンドを実行します。-mindepth 1
findが私たちが始めたフォルダを見つけることができないようにオプションが必要です。これにより、無限ループが生成されます。-prune
findがディレクトリに降りるのを防ぐ必要があります。私たちは内部で直接やります-exec
。-exec "$0" {}
$0
見つかった内容と同じスクリプトが呼び出されます。
答え3
.gitまたは.hgリポジトリの内部を見ないようにfindを指示する方法は次のとおりです。
find . \( -iname '.git' -o -iname '.hg' \) -prune -false -o -iname '*thing-i-am-looking for*'
答え4
少し汚れたスクリプトですが、ファイルは含まれていないすべてのディレクトリを見つけます.git
。
#!/bin/bash
# find dirs that contain *.git files and store in array
exclude_dirs=($(find . -type f -iname ".git" | xargs -i dirname {}))
# set up the base command
command="find . -type d"
# loop over each element in array by index
for i in $(seq 0 $(expr ${#exclude_dirs[@]} - 1)); do
command="${command} -not -path ${exclude_dirs[$i]}"
done
# run the find
eval ${command}
編集する:
構文エラーを修正し、*.git
次に更新しました。.git
編集2:
はい、それは間違っています。すみません。編集しましたが、実際に動作します。