AIにデジタル商品のレビューを頼む前に、Gitで追跡中のファイルだけを渡した

AIにデジタル商品のレビューを頼む前に、Gitで追跡中のファイルだけを渡した

AIに納品前のテンプレートを読ませるとき、フォルダをそのままZIPにするのは少し怖いです。商品説明、配布用ファイル、作業中の.envが同じ場所にあることは珍しくありません。今回は販売物でも実在の鍵でもない合成見本で、AIレビューに渡すファイルをGitの追跡対象だけに絞れるか試しました。確認の起点は、Gitの追跡対象。

前回のPythonスクリプトの依存ライセンスを調べた記録では、配布するスクリプトに何が入るかを依存関係から確認しました。今回は依存関係より手前、AIへ渡すアーカイブの入口を扱います。

フォルダ全体ではなく、Gitの記録を使う

Gitの.gitignoreは、まだ追跡していないファイルを無視するための設定です。すでに追跡対象へ入ったファイルを、あとから.gitignoreに書いてもGitは外しません。そこで、配布してよいと決めてindexへ入れたファイルの一覧を出すgit ls-filesを、アーカイブの入力にしました。

今回の見本の構成は次のとおりです。.envはローカルに残しても、追跡対象へ入れない限りアーカイブに渡りません。

作業フォルダ
  ├─ Gitの追跡対象 ──> review-package.tar.gz ──> AIレビュー
  └─ .env(無視) ──> ローカルに残す
用語この見本での意味
追跡対象Gitのindexに記録され、git ls-filesで列挙されるファイルです。
index次のコミットに入れる候補をGitが管理する場所です。
ステージファイルをindexへ追加する操作です。
無視ファイル.gitignoreの規則で、未追跡のままGitが通常の追加候補から外すファイルです。
アーカイブレビュー用に複数ファイルを1つへまとめたtar.gzです。

合成見本を作り、追跡対象を列挙する

一時ディレクトリにREADME.md、納品用のチェックリスト、無視する.envを置きました。ここで使うAPI_TOKENは検査用の文字列で、実在の鍵ではありません。

work="$TMPDIR/ai-review-tracked-files-demo"
rm -rf "$work"
mkdir -p "$work/deliverable"
cd "$work"
git init -q
git config user.name 'Demo Writer'
git config user.email '[email protected]'
printf '.env\nreview-package.tar.gz\n' > .gitignore
printf '# 作業テンプレート\n\n購入者向けの説明です。\n' > README.md
printf '確認項目: 納品前に入力値を見直す\n' > deliverable/checklist.md
printf 'API_TOKEN=demo-only-not-a-real-token\n' > .env
git add .gitignore README.md deliverable/checklist.md
git commit -qm 'add deliverable files'
git ls-files

実行結果は3ファイルでした。.envはありません。

.gitignore
README.md
deliverable/checklist.md

この一覧をそのままtarへ渡します。--nullを付けるのは、ファイル名に空白があっても区切りを曖昧にしないためです。

git ls-files -z | tar --null --files-from=- -czf review-package.tar.gz
tar -tzf review-package.tar.gz

実行結果です。

.gitignore
README.md
deliverable/checklist.md

作成直後の一覧で、アーカイブに.envが混ざらないことを確かめられます。AIへ渡す前にこの出力を見るだけでも、フォルダを丸ごと圧縮したときより判断しやすくなります。

.gitignoreだけでは防げなかった

ここで、.gitignoreだけでは防げない場合を確かめます。.envが無視されていても、git add -f .envで一度ステージすると、追跡対象の一覧へ入ります。無視規則は、すでにindexへ入ったファイルを取り消しません。

git add -f .env
git ls-files | grep -E '(^|/)(\.env|.*\.(pem|key))$'

実行結果は.envでした。

.env

この状態で追跡対象だけをアーカイブしても、.envは含まれます。今回はコミット前だったので、indexからだけ外しました。ローカルの.env自体は残ります。

git rm --cached .env
if git ls-files | grep -E '(^|/)(\.env|.*\.(pem|key))$'; then
  printf '秘密候補が追跡対象に残っています\n'
  exit 1
else
  printf '秘密候補は追跡対象にありません\n'
fi

実行結果です。

rm '.env'
秘密候補は追跡対象にありません

今回の見本で分かったのは、無視規則を置いても、.envが強制的に追加されると追跡対象の一覧に入ってしまうことです。AIへ送る直前の検査は、.gitignoreの存在確認ではなく、追跡対象の実際の一覧で行うほうが確実です。

今回の状態確認方法直し方
.envが誤ってステージ済みgit ls-filesで.envが出るgit rm --cached .envでindexから外し、検査を再実行します。

レビュー用アーカイブを渡す前の小さな約束

個人で作るデジタル商品は、制作中の設定と購入者へ渡すものが同じリポジトリに並びがちです。だから私は、AIへレビューを頼むときに「無視ファイルを置いたか」ではなく、「今アーカイブに入る一覧は何か」を見たいと思いました。

この方法にも限界はあります。.env以外の秘密らしい名前、たとえば.env.localやサービス固有の設定ファイルは上の正規表現に出ません。商品ごとに、渡してよいファイルをコミットする前に決めること、そしてAIへ送る直前にアーカイブ内容を列挙することを組み合わせます。AIレビューの依頼文にも、アーカイブ外のファイルは根拠にしないと書いておくとよいです。

参照した一次情報

  • git-ls-files Documentation: --cachedがGitのindexにある追跡対象を表示すること、-zと除外規則の仕様を確認しました。
  • gitignore Documentation: .gitignoreが意図的に未追跡のファイルを無視し、すでに追跡中のファイルには効かないことを確認しました。
この記事をシェア