C#で特定のファイルorフォルダがgitignore対象かを判定する(単一ファイル編)
C#というかほとんどgitコマンドのtipsになってしまいますが、特定のファイル/フォルダが.gitignoreファイルによりgit管理対象外になっているかどうかは、「git check-ignore」コマンドを利用して以下のようなソースコードで調べることができます。
string GitExePath = @"C:\Program Files\Git\cmd\git.exe"; /// <summary> /// git check-ignoreコマンドでgitignore対象となっているか否かを調べる /// </summary> /// <param name="fsi">調べる対象のファイル(FileInfo)またはフォルダ(DirectoryInfo)</param> /// <returns>true:gitignore指定あり、false:gitignore指定なし、null:そもそもgit管理外</returns> bool? IsGitIgnored(FileSystemInfo fsi) { ProcessStartInfo psInfo = new ProcessStartInfo(GitExePath); psInfo.Arguments = "check-ignore -q \"" + fsi.FullName + "\""; psInfo.CreateNoWindow = true; psInfo.UseShellExecute = false; psInfo.WorkingDirectory = (fsi is FileInfo ? (fsi as FileInfo).DirectoryName : fsi.FullName); using (Process p = Process.Start(psInfo)) { p.WaitForExit(); if (p.ExitCode == 0) { return true; // gitignore対象 } if (p.ExitCode == 1) { return false; // gitignore対象ではない } if (p.ExitCode == 128) { return null; // そもそもgit管理外だったり等 } // gitコマンドの呼び出しに失敗した場合などは終了コードがさらに別(9009など)になる throw new Exception(); };
git check-ignoreコマンドはカレントディレクトリがgit管理下のディレクトリになっていないと「fatal: not a git repository (or any of the parent directories)」とエラーになってしまうので、WorkingDirectory(Process実行時のカレントディレクトリ)を指定して実行するようにしています。
なお、git check-ignoreコマンドは実行結果が返ってくるまでかなり待たされます(1回のコマンド実行におおむね数十mSec程度かかります)。
調べたいファイルの数が少なければこのソースのやり方でも実用上の問題はないでしょうが、たとえば特定のディレクトリ内の全ファイル/サブディレクトリの内容を一括で調べるのであれば 別のアプローチ をとるほうがよいでしょう。
→2019/02/02追記:続きの記事「C#で特定フォルダ内のgitignore対象ではないファイル/サブフォルダを一括で取得する - hnx8のブログ」を書きました。
→2019/02/02追記: 単一ファイルのgitignore判定処理を改善し、TresGrepに組み込みました。「「gitignore対象をSkip」フィルタ機能追加 - hnx8のブログ」にてソースコード例も公開しています。