ANTIGRAVITY LABEN
記事一覧/Agents & Manager
Agents & Manager/2026-08-28中級

Git が追跡しているのにエージェントが読めないファイルは、どこで外れているか

エージェントのコード検索が返した2ファイルに対し、git grep は6ファイルを返しました。追跡済みのファイルが検索から静かに落ちる3つの経路を合成リポジトリと運用中のリポジトリで実測し、除外理由の特定手順と戻し方をまとめました。

ripgrep2コード検索gitignoreエージェント67トラブルシューティング31

エージェントに「この定数を使っている箇所を全部挙げてください」と頼んだところ、返ってきたのは2ファイルでした。念のため手元で git grep をかけると、6ファイル出てきます。

エージェントが手を抜いたわけではありませんでした。検索の既定が、残りの4ファイルを最初から走査対象に入れていなかっただけです。

Antigravity CLI 1.1.21(8月26日)でエージェントのコード検索用に ripgrep のバイナリが同梱されました。環境に入っているかどうかに左右されなくなったのは良い変更です。ただし同梱されたことで変わらないものもあります。ripgrep が既定で何を見ないか、という部分です。

見ていないファイルは、エージェントにとって存在しないファイルです。そこにある実装を知らないまま「該当箇所はこれで全部です」と答えます。私自身、この静かな欠落のほうが検索の遅さより重いと考えています。

6ファイル中2ファイルしか返らない状況を、手元で作る

最小の再現リポジトリを作りました。同じ定数 NEEDLE_TOKEN を6つのファイルに置き、そのうち3つは .gitignore にマッチする場所へ、1つは隠しディレクトリへ配置します。

mkdir -p src/generated src/legacy .config build
echo 'const NEEDLE_TOKEN = 1;' > src/app.ts
echo 'const NEEDLE_TOKEN = 2;' > src/generated/api-client.ts
echo 'const NEEDLE_TOKEN = 3;' > src/legacy/old.ts
echo 'const NEEDLE_TOKEN = 4;' > .config/settings.ts
echo 'const NEEDLE_TOKEN = 5;' > build/bundle.js
printf 'NEEDLE_TOKEN\x00binary\n'  > src/blob.bin
 
printf 'build/\n*.bin\nsrc/generated/\n' > .gitignore
 
# 生成物を「無視対象だが追跡はする」状態にする(実務でよくある形です)
git add -f src/generated/api-client.ts
git add -A -f && git commit -m init

git add -f を使っているのが肝です。生成コードやビルド済みクライアントを .gitignore に入れたまま、必要な1ファイルだけ強制的に追跡させる運用は珍しくありません。私の手元でも、生成した API クライアントを同じ形で抱えていた時期があります。

この状態で3つの検索を並べました。

git grep -l NEEDLE_TOKEN | wc -l    # 6
rg -l NEEDLE_TOKEN . | wc -l        # 2
rg -l -uuu NEEDLE_TOKEN . | wc -l   # 6

git grep は追跡済みの6ファイルすべてを返します。ripgrep の既定は src/app.tssrc/legacy/old.ts の2つだけでした。Git がバージョン管理している実コードのうち、4ファイルが検索の外にいます。

計測環境は ripgrep 13.0.0(Linux)です。同梱されたバイナリの版は手元の rg --version と一致するとは限りませんが、以下で扱う既定のフィルタはこの系統で共通して効きます。

外れる経路は3つあります

落ちた4ファイルの理由は、同じではありませんでした。

ファイル外れた理由戻すフラグ
build/bundle.js.gitignorebuild/--no-ignore
src/generated/api-client.ts.gitignoresrc/generated/(追跡済みでも除外)--no-ignore
.config/settings.ts隠しディレクトリ--hidden
src/blob.binNUL バイトを含むためバイナリ判定--binary または --text

段階的に足していくと、拾える数が2 → 4 → 5 → 6と増えます。

rg -l NEEDLE_TOKEN .            # 2
rg -l --no-ignore NEEDLE_TOKEN . # 4  (+ generated, + build)
rg -l -uu NEEDLE_TOKEN .         # 5  (+ .config)
rg -l -uuu NEEDLE_TOKEN .        # 6  (+ blob.bin)

2番目の行が、いちばん見落としやすい部分だと思います。ripgrep は対象ファイルが Git に追跡されているかどうかを見ません。.gitignore のパターンに当たるかどうかだけで判断します。git add -f で追跡させたファイルは、Git にとっては正規の管理対象で、ripgrep にとっては無視対象です。この2つの判断がずれていることに、私は実際に検索結果を突き合わせるまで気づきませんでした。

バイナリ判定にも、報告のされ方に差があります。ディレクトリを走査したときは黙って落ちますが、ファイルを直接指定したときだけ理由を教えてくれます。

rg NEEDLE_TOKEN src/blob.bin
# binary file matches (found "\0" byte around offset 12)

走査の途中で落ちたものは、この行すら出ません。「ヒットしませんでした」と「見ていません」が、出力の上では同じ顔をしています。

同じリポジトリでも、マシンによって範囲が変わります

ここから先が、共有しづらい種類の落とし穴です。ripgrep が尊重する除外規則は .gitignore だけではありません。

echo 'src/legacy/' >> .git/info/exclude
rg -l NEEDLE_TOKEN .    # src/app.ts だけになる

.git/info/exclude はリポジトリには入りません。手元のクローンにだけ存在するファイルです。グローバル設定の core.excludesFile も同じ挙動で、こちらはマシン単位で効きます。

つまり同じコミットを見ていても、開発者ごとにエージェントの検索範囲が違い得ます。個人開発でも、母艦とノートで設定が揃っていなければ同じことが起きます。「私の環境では見つかるのに」という報告が出たとき、疑う場所がひとつ増えます。

どのルールが外したのかは --debug が答えます

推測で当てにいく必要はありませんでした。--debug を付けると、除外の判断が1行ずつ出ます。

rg --debug --files . 2>&1 | grep "ignore::walk"

出力はこうなります。

ignoring ./build: Ignore(IgnoreMatch(Gitignore(Glob { from: Some("./.gitignore"),
  original: "build/", actual: "**/build", is_whitelist: false, is_only_dir: true })))
ignoring ./.config: Ignore(IgnoreMatch(Hidden))
ignoring ./src/blob.bin: Ignore(IgnoreMatch(Gitignore(Glob { from: Some("./.gitignore"),
  original: "*.bin", actual: "**/*.bin", is_whitelist: false, is_only_dir: false })))

from にどのファイルのパターンが効いたかが入り、隠しファイルは Hidden として区別されます。.git/info/exclude が犯人のときも from にそのパスが出ますので、共有されていない設定を突き止められます。

理由の内訳を数えたいときは、末尾を集計に回します。

rg --debug --files . 2>&1 | grep "ignore::walk" \
  | sed -E 's/.*IgnoreMatch\(([A-Za-z]+).*/\1/' | sort | uniq -c | sort -rn

戻し方は3通りで、常設にするなら .ignore です

一時的に範囲を広げるだけなら -uu-uuu で足ります。ただしエージェントに毎回フラグを付けさせるのは現実的ではありませんでした。指示文に書いても、別のセッションでは落ちます。

恒久的に救いたいファイルがあるなら、.ignore ファイルに否定パターンを置く方法が確実です。ripgrep は .ignore.gitignore より優先します。

printf '!src/generated/\n' > .ignore
rg -l NEEDLE_TOKEN .    # 3 になる(app / legacy / generated)

.ignore はリポジトリにコミットできますので、設定が共有されます。生成コードのうちエージェントに読ませたい範囲だけを、明示的に戻せます。

ただし .ignore!*.bin を書いても、バイナリ判定は外れませんでした。除外の層が2つあり、.ignore が効くのは無視規則の層だけだからです。バイナリを読ませたい場合は --binary を渡すしかありません。とはいえ、エージェントにバイナリを読ませたい場面はほとんどないはずですので、ここは外れたままで妥当だと考えています。

追跡済みファイルだけを確実に見たいなら、git grep を併走させるのがいちばん素直です。追跡状況そのものを基準にしますので、.gitignore の書き方に左右されません。

差分は1行で確かめられます

範囲がずれているかどうかは、毎回この1行で分かります。

comm -23 <(git ls-files -z | tr '\0' '\n' | sort) \
         <(rg --files | sed 's|^\./||' | sort)

Git が追跡していて ripgrep が見ていないファイルが並びます。何も出なければ範囲は一致しています。

git ls-files をそのまま使わず -z を経由しているのには理由があります。この記事を書いているリポジトリには src/app/[locale]/HomeClient.tsx があり、git ls-files はこれをクォートとエスケープ付きで出力します。素朴に比較すると存在しない差分が1件生まれました。core.quotePath=false を付けても解消しません(実測しました)。-z で区切りを NUL にすれば、そのまま比較できます。

運用中の当サイトのリポジトリで実行した結果です。

項目実測値
git 追跡ファイル数2,264
rg --files が返した数2,252
差分12(.gitignore.npmrc・各カテゴリの .gitkeep 10個)
除外理由の内訳すべて Hidden

このリポジトリでは node_modules を置いていない状態で測ったため、.gitignore 由来の欠落は出ませんでした。落ちたのは隠しファイルだけで、検索語を含まないものばかりです。実害はありません。ただし生成コードを追跡している構成なら、先ほどの合成リポジトリと同じことが起きます。

フラグを足す負担も測りました。2,252ファイル規模で、既定が20ms、-uu が17ms、-uuu が20ms、git grep が20msです。この規模では差は誤差の範囲でした。範囲を広げるかどうかを速度で決める段階ではない、という結論になります。

検索が遅いことには気づけます。検索が見ていないことには気づけません。私はこの差分を出す1行を、ビルドやテストと同じ検証手順の中に置いています。埋め込みターミナルから同じコマンドを走らせる形については、Antigravity 2.10.0 の埋め込みターミナルで検証ループを組むにまとめています。

検索の経路そのものが切り替わってしまう問題は、/codesearch が ripgrep を使えない環境での実測で別途扱いました。除外パターンの書き方が意図どおり効いているかを確かめる手順は、.antigravityignore が効いていないときに疑う4か所にあります。

エージェントへ渡す範囲を、速度と引き換えにどこまで広げるかという話に踏み込みたい方は、読み取り専用になった .git をエージェントへどう渡すかで、履歴の受け渡しを 38 秒から 0.4 秒へ縮めた過程を書いています。

まずは手元のリポジトリで、先ほどの comm の1行を実行してみてください。何行出るかで、エージェントが今どこまで見えているのかが分かります。ここまでお付き合いいただき、ありがとうございました。

シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Agents & Manager2026-04-09
Antigravity のエージェントが指示通りに動かない・タスクを誤解する時の対処法
Antigravity のエージェントが指示を正しく理解せず、意図と違う動作をしてしまう問題の原因と対処法を解説。agents.md の設計、タスクの粒度、コンテキスト管理など実践的な改善方法を紹介します。
Agents & Manager2026-04-08
Antigravity AgentKit 2.0 の実行時エラーを診断する—tool_call失敗・無限ループ・コンテキスト超過への対処
AgentKit 2.0でエージェントを本番運用する際に発生するランタイムエラーを完全解説。tool_call失敗の診断・無限ループの防止・コンテキストウィンドウ超過の対策・並列エージェントの同期エラーまで実装コード付きで解決します。
Agents & Manager2026-08-16
Canary 継続配信になった Android 17 で、エージェントには「報告しない条件」から先に渡しました
Android 17 が Developer Preview をやめて Canary の継続配信に切り替わり、検証の締め切りが自分の側に移りました。更新を追う担当をエージェントへ渡すにあたり、報告の条件ではなく沈黙の条件から設計した記録です。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →