概要
git-aiはAIによるコード生成をフックし、対象行をGitのNotesへ記録することで、AIコーディング率を導出する仕組み。
既存のコードについて、AIが生成したものかどうかを推測で判定するのではなく、AIがコードを生成したときに「この差分はAIが書いた」と明示的に記録する。
gitの拡張なので、言語にとらわれず幅広いプロジェクトに導入できる。
Claude Code、Codex、Cursor、GitHub Copilot、GeminiなどメジャーなAIには対応している。
公式
仕組み
大まかな流れ。
- Cursor、Claude Code、GitHub CopilotなどのAIエージェントがファイルを編集する
- git-aiの
checkpointが呼ばれる - 編集前後の差分を見て、AI由来・人間由来を記録する
- コミット時に、その情報を Authorship Log としてまとめる
- そのログを Git Notes に保存する
-
git ai statsやgit ai blameで割合や行単位の由来を見る
導入
Next.jsでプロジェクトを立ち上げ、これにgit-aiを導入してみる。
npx create-next-app@latest learn-git-ai --yes
cd learn-git-ai
Macに導入するな以下のコマンド。
curl -sSL https://usegitai.com/install.sh | bash
以下のコマンドを実行し、versionが表示されたらOK。
git ai --version
自分はパスが通っておらず、バージョンが表示されなかったので、追加で以下を実行したところ、バージョンが表示されるようになった。
echo 'export PATH="$HOME/.git-ai/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
また、拡張機能のgit-aiが入っていない場合は手動でインストールする。
試してみる
差分確認
src/app/page.tsxについて、適当にgithub copilotに変更してもらう。
// これ以降全てgithub copilotが書いたコード
const menuItems = [
{ label: "ホーム", href: "#" },
{ label: "プロフィール", href: "#" },
{ label: "設定", href: "#" },
{ label: "ヘルプ", href: "#" },
{ label: "ログアウト", href: "#" },
];
export default function Home() {
return (
<div className="min-h-screen bg-zinc-50 dark:bg-zinc-900 flex items-center justify-center font-sans">
<div className="w-full max-w-sm bg-white dark:bg-zinc-800 rounded-2xl shadow-lg overflow-hidden">
<div className="px-6 py-8 border-b border-zinc-100 dark:border-zinc-700">
<h1 className="text-2xl font-bold text-zinc-800 dark:text-zinc-100">
メニュー
</h1>
<p className="text-sm text-zinc-500 dark:text-zinc-400 mt-1">
項目を選択してください
</p>
</div>
<nav>
<ul>
{menuItems.map((item, index) => (
<li key={index}>
<a
href={item.href}
className="flex items-center justify-between px-6 py-4 text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors border-b border-zinc-100 dark:border-zinc-700 last:border-none"
>
<span className="font-medium">{item.label}</span>
<span className="text-zinc-400">›</span>
</a>
</li>
))}
</ul>
</nav>
</div>
</div>
);
}
ターミナルで以下を実行する。
git ai status
結果は以下の通り。
you ········░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ai
0% untracked 21% 79%
52 secs ago +32 -6 Github-copilot gpt-5-mini
52 secs ago +5 -61 username
このように、どれくらいのコードをAIが実装したのかがわかる。
コミット後にAI生成割合を確認する
コミットをした後にgit ai statusを実行しても、先ほどのようなAI生成割合等を確認することはできない。
$ git ai status
No checkpoints recorded since last commit (80d6f22)
If you've made AI edits recently and don't see them here, you might need to install hooks:
git-ai install-hooks
確認するには以下のコマンドを使う。
git ai stats
結果
you ··░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ai
0% untracked 5% 95%
これは、
- 人間が書いたコード:0%
- AIが書いたコード:95%
- Git未追跡ファイル:5%
ということを表している。
注意すべき点は、この割合はプロジェクト全体についての説明ではないということ。git ai statsでは、直近のコミット(HEAD)のみが対象になっている。
複数のコミットや、ブランチ全体をみるには範囲の指定をする必要がある。
範囲の指定方法は以下の通り。
git ai stats <start>..<end>
startとendにはそれぞれcommitのIDを記入する。
現在のブランチの最初のコミットから最新のコミットまでを対象にしたい場合、以下のように書く。
git ai stats 4b825dc642cb6eb9a060e54bf8d69288fbee4904..HEAD
4b825dc642cb6eb9a060e54bf8d69288fbee4904は空のツリーを表す。
つまり上記のコマンドは、空の状態〜HEADまでを対象とする、ということ。
現在のブランチでmainブランチから増えた分を対象にしたいなら、以下のように書くこともできる。
git ai stats main..HEAD
ファイル単位で確認
以下のコマンドを実行することで、gitのblameでもAIが生成したコードかどうかを確認することができる。
git ai blame <ファイルパス>
src/app/page.tsxについて確認したい場合は、以下のコマンドを実行する。
git ai blame src/app/page.tsx
結果
80d6f224 (username 2026-05-28 19:55:32 +0900 1) // これ以降全てgithub copilotが書いたコード
80d6f224 (username 2026-05-28 19:55:32 +0900 2)
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 3) const menuItems = [
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 4) { label: "ホーム", href: "#" },
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 5) { label: "プロフィール", href: "#" },
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 6) { label: "設定", href: "#" },
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 7) { label: "ヘルプ", href: "#" },
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 8) { label: "ログアウト", href: "#" },
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 9) ];
^135f51b (username 2026-05-28 15:47:52 +0900 10)
^135f51b (username 2026-05-28 15:47:52 +0900 11) export default function Home() {
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 12) return (
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 13) <div className="min-h-screen bg-zinc-50 dark:bg-zinc-900 flex items-center justify-center font-sans">
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 14) <div className="w-full max-w-sm bg-white dark:bg-zinc-800 rounded-2xl shadow-lg overflow-hidden">
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 15) <div className="px-6 py-8 border-b border-zinc-100 dark:border-zinc-700">
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 16) <h1 className="text-2xl font-bold text-zinc-800 dark:text-zinc-100">
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 17) メニュー
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 18) </h1>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 19) <p className="text-sm text-zinc-500 dark:text-zinc-400 mt-1">
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 20) 項目を選択してください
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 21) </p>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 22) </div>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 23) <nav>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 24) <ul>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 25) {menuItems.map((item, index) => (
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 26) <li key={index}>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 27) <a
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 28) href={item.href}
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 29) className="flex items-center justify-between px-6 py-4 text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors border-b border-zinc-100 dark:border-zinc-700 last:border-none"
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 30) >
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 31) <span className="font-medium">{item.label}</span>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 32) <span className="text-zinc-400">›</span>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 33) </a>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 34) </li>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 35) ))}
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 36) </ul>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 37) </nav>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 38) </div>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 39) </div>
80d6f224 (github-copilot 2026-05-28 19:55:32 +0900 40) );
^135f51b (username 2026-05-28 15:47:52 +0900 41) }
config設定
生成物やテスト出力については対象外にすることができる。
.git-ai-ignoreファイルをルートに作成し、以下のように記述する。
.next/**
out/**
coverage/**
playwright-report/**
test-results/**
*.generated.*
