Tsuzura

Gitで変更を確認・保存・戻す

AIが変更したコードをGitで確認し、必要な差分だけをcommitへ保存し、状態に応じて戻す手順です。

AIにコード変更を任せると、短時間で複数のファイルが変わることがあります。変更前と変更後を分けて確認できなければ、必要な変更だけを履歴へ残せません。戻す操作を選び間違えると、残す予定だった編集まで失う可能性があります。

Gitは、ファイルの状態を比較し、確認した変更を履歴へ記録するために使います。Gitで管理する一まとまりのフォルダを「リポジトリ」、変更を履歴へ記録する操作と記録を「コミット」と呼びます。ただし、Gitが変更の正しさを判断するわけではありません。テスト、要件への適合、秘密情報の有無、データベースや外部サービスへの影響は別に確認します。

この記事では、既にGitで管理され、少なくとも一つのコミットがあるリポジトリを対象にします。Gitの導入、初回設定、ほかの場所にあるリポジトリへの送信(push)、プルリクエスト、マージは扱いません。読み終えると、一回のAI変更について、確認する、コミットする、戻す、作業を止める、のいずれかを状態に応じて選べます。

AIへ渡す変更内容がまだ一件に絞れていない場合は、先にAIに渡す実装タスクの切り方を確認してください。

Gitで変更を分ける理由

Gitを使う目的は、現在編集中の内容、次のコミットへ入れる内容、履歴へ記録済みの内容を分けることです。この区別があると、どの内容を確認したか、どこまで記録したか、どの状態へ戻そうとしているかを説明できます。

Gitのstatus公式資料は、記録済みの状態とステージの差、ステージと作業中ファイルの差、未追跡ファイルを別々に表示すると定義しています。diff公式資料も、比較する二つの状態によって表示内容が変わることを説明しています。

Gitが管理する三つの状態

最初に、この記事で使う三つの状態を区別します。

状態 この記事での意味 ここにあるだけで記録済みか
作業ツリー(working tree) 現在編集しているファイル いいえ
ステージ(stage / index) 次のコミットへ入れるために選んだ内容 いいえ
現在のコミット(current commit) 現在の比較元として履歴へ記録された内容 はい。手元のリポジトリには記録済み

ステージとインデックスは、この記事では同じものを指します。ステージは次のコミットへ入れる内容を準備する場所です。ステージへ移しただけでは、履歴への記録は終わっていません。

三つの状態と、基本の差分は次の関係です。

現在のコミット(HEAD)
        │  git diff --staged
ステージ(index)
        │  git diff
作業ツリー

HEADは、現在参照しているコミットを示します。通常は、現在のブランチの先端にあるコミットを示します。Gitのcommit公式資料では、-aやファイルの指定など、記録対象を変える指定を付けないコミットは、実行時点のインデックス内容を記録します。作業ツリーに残る未ステージ変更と未追跡ファイルは入りません。-mはコミットメッセージを指定するだけで、記録対象を変えません。

ブランチとGitが管理しないもの

ブランチ(branch)は、コミットを指す名前です。Gitのbranch公式資料では、新しいブランチの先端は、現在のHEADまたは指定したコミットを指すと説明されています。ブランチを作るだけでは、未コミット変更は記録されません。

この記事で実行するコマンドは、ほかの場所にあるリポジトリへコミットを送信しません。この手順だけでは、手元の別の端末やリモート側に複製は作られません。

Gitの履歴へ記録できるのは、リポジトリ内のファイル変更です。次の結果はGitだけでは管理できません。

  • テストが合格したか
  • 要件や設計に合っているか
  • データベースへ適用した変更
  • 外部APIへ送った要求
  • 送信済みのメールや通知
  • 公開済みの成果物と本番設定

後でGit上のコードを戻しても、これらは自動では戻りません。

コマンドを実行する前の約束

この記事のコマンドは、対象のリポジトリ内でターミナルから実行します。BRANCH_NAME、FILE_PATH、START_COMMIT、COMMIT_TO_REVERTは入力欄です。その文字列のまま貼り付けず、確認した実際の値へ置き換えます。

コマンドの意味、入力欄へ入れる値、現在いるリポジトリのいずれかが分からない場合は実行しません。AIに値を推測させず、リポジトリの管理者へ確認します。

AIへ依頼する前に確認する

AIへ依頼する前に、開始状態を記録します。この確認を後回しにすると、以前からあった変更とAIが加えた変更を、後の差分だけで確実に分けられない場合があります。Gitの差分が示すのは状態の違いであり、未コミット編集を誰が行ったかではないためです。

変更のない状態と開始コミットを記録する

最初に、現在のブランチと変更の有無を確認します。

git status --long --branch --untracked-files=all

出力は、主に次の見出しで状態を分けます。

出力の見出し 意味
Changes to be committed ステージにある変更
Changes not staged for commit 作業ツリーにある未ステージ変更
Untracked files Gitがまだ追跡していないファイル
nothing to commit, working tree clean 未コミット変更がない状態

未追跡とは、現在のインデックスに登録されていない状態です。過去のコミットに同じ場所や内容がないことまでは意味しません。変更、削除、ステージ済み、未追跡ファイルのいずれかが表示された場合は、AIへ依頼する前に止まります。既存変更の目的と担当者を確認し、保存するか、別の作業場所へ分けるかを決めます。分からない状態をAI変更へ混ぜません。

次に、開始コミットを記録します。

git rev-parse --verify HEAD

Gitのrev-parse公式資料では、このコマンドはHEADを検証し、現在のコミットを識別する値を出力します。出力された値はSTART_COMMITとして記録します。初回コミット前などHEADが存在しない場合は失敗するため、本記事の手順を続けず、リポジトリの準備を確認します。

現在のブランチ名も確認します。出力された値は、AIへ依頼する前の開始ブランチとして記録します。

git branch --show-current

何も表示されない場合は、ブランチを選ばず特定のコミットを直接参照する「detached HEAD」の可能性があります。その状態を自分で解決しようとせず、リポジトリの管理者へ確認します。

作業ブランチを用意する

未コミット変更がなければ、リポジトリの運用ルールに従って作業ブランチを用意します。BRANCH_NAMEは、運用ルールに合う実際の名前へ置き換えます。

git switch -c "BRANCH_NAME"

Gitのswitch公式資料では、-cはブランチの作成と切替を行い、作業ツリーとインデックスを対象ブランチに合わせます。未コミット変更がある状態から切り替えられる場合もありますが、既存変更を記録したことにはなりません。この記事では、変更の混在を避けるため、未コミット変更がない状態からブランチを作ります。切替後にgit branch --show-currentを再実行し、出力された値を作業ブランチとして記録します。

AIへ許可する操作を決める

AIへ依頼するときは、変更内容だけでなく、実行してよい操作も決めます。

  • 変更してよいファイルやディレクトリ
  • 実行してよいテストや静的解析
  • シェルコマンドを実行してよいか
  • ネットワークへ接続してよいか
  • ステージやコミットまで任せるか
  • データベース、外部API、本番環境へ接続してよいか

初めてこの手順を使う場合は、AIにはファイル変更と必要な確認までを任せ、ステージとコミットは人が行う方が状態を追いやすくなります。

OpenAIのCodex公式ガイドは、サンドボックスがCodexに可能な操作範囲を、承認方針が承認判断を必要とする地点を制御すると説明しています。同じ資料のバージョン管理の節は、変更のない状態と作業ブランチから始め、差分、小さなコミット、対象を絞った検証、人による差分確認を使うよう勧めています。これはCodex固有の仕組みと推奨です。他のAIツールでは、実際に利用できる権限制御を個別に確認します。

変更後に差分を確認する

AIの処理が終わったら、AIの説明だけで判断せず、Gitが示す状態を確認します。最初はstatusで対象を一覧し、その後に状態ごとの差分を読みます。

statusで変更の一覧を見る

git status --long --branch --untracked-files=all

次を一件ずつ確認します。

  • 変更されたファイル
  • 削除されたファイル
  • ステージ済みのファイル
  • 未追跡ファイル
  • 現在のブランチ

statusは変更内容や変更理由を表示しません。対象外のファイル、大量の削除、意図不明の生成ファイルがある場合は、ステージやコミットへ進まずに止めます。

状態に合わせて差分を切り替える

一つのgit diffだけで全変更を確認することはできません。確認したい状態に合わせてコマンドを分けます。FILE_PATHは、statusに表示された実際のファイルまたはディレクトリの場所へ置き換えます。

確認するもの コマンド 表示されるもの これだけでは見えないもの
作業ツリーとステージの差 git diff -- "FILE_PATH" 未ステージの変更 ステージ済み、未追跡、コミット済みの変更
ステージと現在のコミットの差 git diff --staged -- "FILE_PATH" 次のコミットへ入る変更 未ステージ、未追跡、既にコミットした変更
開始コミットと現在のHEADの差 git diff START_COMMIT HEAD -- "FILE_PATH" 二つのコミットが持つファイル内容の差 作業ツリーとステージに残る未コミット変更

未追跡ファイルの内容は、通常のgit diffには表示されません。ファイルを直接開き、内容と必要性を確認します。引数なしのgit diffが空でも、変更がないとは限りません。ステージ済みの変更、未追跡ファイル、既にコミットされた変更は別に確認します。

diffの表示を読む

diffでは、主に次の記号を確認します。

表示 意味
---と+++ 比較する前後のファイル
@@ 変更箇所の位置
行頭の- 比較元から削除された行
行頭の+ 比較先へ追加された行
記号のない行 変更箇所の前後にある文脈

表示が一画面に収まらない場合、Gitがページャーを開くことがあります。読み終えたらqを押して閉じます。ファイル名、追加、削除、変更箇所を説明できなければ、次へ進みません。

AIがコミット済みの場合

AIへコミットを許可した場合は、まず現在いるブランチが開始時に想定したブランチか確認します。

git branch --show-current
git diff START_COMMIT HEAD

この差分が示すのは、START_COMMITと現在のHEADが持つファイル内容の違いです。変更時刻、変更者、二つのコミットの祖先関係までは証明しません。コミットメッセージやAIの作業報告だけで採否を決めず、statusで未コミット変更も確認します。

開始コミットを記録していなかった場合や、作業開始前から変更があった場合は、AIの変更だけを確実に分けられないことがあります。そのまま戻す操作へ進まず、履歴と担当者を確認します。

ここで作業を止める

Gitの状態や変更の影響を説明できないときは、保存や復元の操作を追加せずに止めます。止めることは、残す変更を失わないための判断です。

Gitの状態を説明できない

次の状態では、ステージ、コミット、restore、revertへ進みません。

  • 作業開始前から未コミット変更がある
  • merge、rebase、revertなどの競合中である
  • detached HEADである
  • AIへ許可していないファイルが変わっている
  • 大量の削除や意図不明の生成ファイルがある
  • 開始コミットが分からず、AIが既にコミットしている
  • statusとdiffを見ても残る変更を説明できない

現在の状態、実行したコマンド、AIへ渡した範囲を保存し、リポジトリの管理者へ確認します。状態不明のまま破壊的なコマンドを試しません。

秘密情報が含まれている

パスワード、トークン、APIキー、認証情報などを見つけた場合は、AIへの追加送信、ステージ、コミット、pushを止めます。既にコミットした場合も、まずその秘密情報を発行したサービスで失効または更新します。

Gitのgitignore公式資料では、.gitignoreが対象にするのは、意図的に未追跡とするファイルです。既にGitが追跡しているファイルには作用せず、過去のコミットから内容を消すこともありません。

GitHubの秘密情報除去ガイドは、秘密情報の場合は、履歴除去より先に失効または更新するよう説明しています。履歴書換えはコミットの識別値、共同作業者のcloneやfork、プルリクエスト、署名などへ影響します。本記事では履歴書換えコマンドを案内しません。組織のセキュリティ窓口とリポジトリ管理者へ引き渡します。

個人情報や契約上の機密情報が含まれる場合も、自己判断で履歴だけを書き換えません。情報管理、セキュリティ、プライバシーの担当者へ連絡します。

Git外の変更がある

AIがデータベース、外部API、本番環境、メールや通知へ作用した場合は、Gitの差分確認と別に影響範囲を確認します。公開候補と復旧方法は本番公開前の確認へ、バックアップ、復旧、運用担当はWebサービスの最低限の運用設計へ引き渡します。

保存する内容を選んでコミットする

停止条件に当てはまらないことを確認してから、今回の目的に必要な内容だけをステージします。ステージへ入れた後に、次のコミットへ入る差分をもう一度確認します。

必要なファイルまたは差分だけをステージする

ファイル全体を選ぶ場合は、FILE_PATHを実際の場所へ置き換えます。

git add -- "FILE_PATH"

同じファイルの一部だけを選ぶ場合は、差分のまとまりごとに確認します。差分のまとまり(hunk)は、Gitが一つの確認単位として表示する連続部分です。

git add -p -- "FILE_PATH"

Gitのadd公式資料は、作業ツリーの内容をインデックスへ反映し、--patchで差分のまとまりごとにステージできると説明しています。対話中は、主に次を使います。

入力 動作
y 表示中のまとまりをステージする
n 表示中のまとまりをステージしない
q 残りの選択を止める。既に選んだ内容はステージに残る
? 利用できる入力の説明を表示する

どれを選ぶか説明できない場合はqで止めます。差分を分けられることと、変更が動作上独立していることは別です。関連するコードとテスト、同時に必要な設定を不自然に分断しません。

未追跡ファイルは、内容と作成理由を確認してから、場所を明示してステージします。対象を確認しないまま全体をステージする操作は、この記事の基本手順に含めません。

ステージ済み差分を再確認する

git diff --staged

次を確認します。

  • 今回の目的に必要な変更だけか
  • 対象外のファイルや無関係な整形が入っていないか
  • 秘密情報、個人情報、認証情報が含まれていないか
  • 削除や権限変更が意図どおりか
  • 必要なテストや確認を実行したか

秘密情報、対象外変更、説明できない削除を見つけた場合は、コミットせず「ここで作業を止める」へ戻ります。テスト方法が決まっていない場合は、テストの種類と選び方で変更のリスクに合う確認方法を決めます。テストに合格しても、ステージ済み差分の確認は省略しません。

コミットして残りを確認する

ステージ済み差分と確認結果を受け入れたら、WRITE_CHANGE_PURPOSE_HEREを実際の変更目的へ置き換えてコミットします。

git commit -m "WRITE_CHANGE_PURPOSE_HERE"

この記事では、ステージ以外の対象を自動追加する-a、ファイル指定、--interactive、--patchなど、記録対象を変える指定を使いません。

コミット後に、残っている変更と結果のコミットを確認します。

git status --long --branch --untracked-files=all
git rev-parse --verify HEAD

statusに変更が残っていれば、その内容は今のコミットへ入っていません。未追跡ファイルも自動保存されません。残した理由を説明できない場合は、次のAI変更へ進みません。

状態に合わせて戻す

「戻す」という言葉だけでは、どこを変える操作か分かりません。現在の状態と、残したい内容を先に確認します。

現在の状態 選ぶ操作 残る内容 失う可能性がある内容
ステージだけを解除したい git restore --staged -- "FILE_PATH" 作業ツリーの編集 ステージ上の選択状態
未コミット編集を破棄したい git restore -- "FILE_PATH" インデックスにある内容 作業ツリーの未コミット編集
コミットを履歴上で打ち消したい git revert --no-edit COMMIT_TO_REVERT 元コミットと履歴 競合時は追加判断が必要
未追跡ファイルを扱いたい 内容を確認して個別に判断 選んだファイル git restoreでは削除されない

ステージだけを解除する

ステージから外し、作業ツリーの編集を残す場合は、FILE_PATHを実際の場所へ置き換えます。

git restore --staged -- "FILE_PATH"

Gitのrestore公式資料では、--stagedを指定するとインデックスが復元対象になります。実行後はstatusと引数なしのdiffを確認し、編集が作業ツリーへ残っていることを確かめます。

未コミット編集を破棄する

次のコマンドは、確認なしに作業ツリーの編集を失う操作です。FILE_PATHの未コミット編集を破棄すると決め、直前の差分を確認した場合だけ実行します。

git diff -- "FILE_PATH"
git restore -- "FILE_PATH"

これはステージ解除ではありません。--stagedを付けない場合、作業ツリーがインデックスの内容へ復元され、未コミット編集を失います。常にHEADへ戻るとも限りません。対象の場所とステージの状態を説明できない場合や、残すか迷う内容がある場合は実行しません。

コミットを打ち消す

コミット済みの変更を履歴から消さず、逆方向の変更を新しいコミットとして記録する場合はrevertを使えます。COMMIT_TO_REVERTは、打ち消すと決めたコミットの識別値へ置き換えます。--no-editは既定のメッセージを使い、エディタを開かない指定です。

git revert --no-edit COMMIT_TO_REVERT

Gitのrevert公式資料は、過去のコミットの効果を逆にする新しいコミットを作る操作として定義しています。開始前に、未コミット変更がないことをstatusで確認します。

競合が表示された場合は、解決を推測しません。次のコマンドで進行中のrevertを中止し、開始前の状態へ戻してから、リポジトリの管理者へ確認します。

git revert --abort

revertが打ち消すのは、Gitへ記録されたファイル変更です。データベース、外部API、送信済み通知、公開済み成果物は別に復旧します。

通常手順に含めない操作

この記事では、次の操作を実行手順に含めません。

  • コミットを指定するgit reset
  • git reset --hard
  • git clean
  • force push
  • rebaseによる履歴書換え

Gitのreset公式資料では、resetは指定方法とモードによりHEAD、インデックス、作業ツリーへの作用が変わります。--hardは追跡中ファイルの変更を破棄し、追跡中ファイルを書き込む妨げになる未追跡ファイルやディレクトリを削除する場合があります。一つの安全な取り消し操作として使えないため、必要になったら影響範囲を理解する担当者へ引き渡します。

AIと人の確認範囲を分ける

AIはGitの状態取得と整理を補助できます。しかし、変更を採用するか、編集を失う操作を実行するか、秘密情報事故へどう対応するかは人が判断します。

AIへ任せられる補助 人が確認して決めること
statusとdiffの取得 取得対象と出力に秘密情報がないか
変更ファイルと差分の要約 変更が今回の目的に必要か
実行したコマンドと結果の整理 テストとレビューの結果を受け入れるか
ステージ候補の提案 実際にステージする内容
restoreやrevert候補の提示 編集を失う操作とコミットの打消しを実行するか
未確認事項の一覧化 停止、上位判断への引き渡し、秘密情報への対応

diffには秘密情報や個人情報が含まれることがあります。本記事の安全ルールとして、外部のAIへdiffを渡す前に、送信してよい情報かを人が確認します。

OpenAIのCodex公式ガイドが説明するサンドボックスと承認方針は、Codexが実行できる操作を制限する仕組みです。変更内容の正しさ、要件への適合、セキュリティ、テスト結果を保証するものではありません。AI生成コードを採用してよいか判断する手順は、AI生成コードをレビューするで扱います。

一回の変更を完了する

一回のAI変更を終える前に、開始点、確認した差分、保存または復元した結果、残る事項を記録します。

次へ進む条件

次の条件をすべて確認します。

  • 開始ブランチ、作業ブランチ、開始コミットを記録した
  • 変更後のstatusを確認した
  • 未ステージ、ステージ済み、コミット済みのうち該当する差分を確認した
  • 未追跡ファイルを確認した
  • 必要なテストと確認を実行した
  • 秘密情報と対象外変更がないと確認した
  • コミットした内容、または戻した内容を説明できる
  • statusに残る変更を説明できる
  • Git外の影響があれば別の復旧手順へ渡した

一つでも説明できない項目があれば、次のAI変更へ進みません。

Git変更記録

次の空欄を、一回の変更ごとに残します。これはGitの公式書式ではなく、開始点と判断を混ぜないための本記事の記録形式です。

開始ブランチはAIへ依頼する前、作業ブランチは切替後にgit branch --show-currentで取得します。開始コミットと結果のコミットはgit rev-parse --verify HEADで取得します。開始コミットは変更前、結果のコミットはコミットまたはrevertの後に取得します。

各欄では、次の値を区別します。

  • なし: 確認した結果、対象が存在しない
  • 該当なし: 今回の判断ではその項目を使わない
  • 未確認: まだ確認していない。次へ進まず、確認担当と期限を決める

コミットもrevertもしなかった場合、結果のコミットは該当なしとします。テストを実行していない場合、テスト結果は未確認です。Git外へ作用していないと確認できた場合、その影響はなしとします。分からない場合は未確認として停止します。

# Git変更記録

- 作業内容:
- 開始ブランチ:
- 作業ブランチ:
- 開始コミット:
- 開始時の状態: [変更なし / 停止]
- 変更ファイル: [一覧 / なし / 未確認]
- 削除ファイル: [一覧 / なし / 未確認]
- 未追跡ファイル: [一覧 / なし / 未確認]
- 未ステージ差分: [確認済み / なし / 未確認]
- ステージ済み差分: [確認済み / 該当なし / 未確認]
- 開始コミットと現在のHEADの差: [確認済み / 該当なし / 未確認]
- テスト・確認結果の参照先: [参照先 / 未確認]
- 判断: [コミット / 戻す / 停止]
- 結果のコミット: [識別値 / 該当なし / 未確認]
- statusに残る変更と理由: [内容 / なし / 未確認]
- 秘密情報・対象外変更: [なし / 停止 / 未確認]
- Git外の影響と引き渡し先: [内容 / なし / 未確認]
- 次へ進めるか: [進む / 停止]

この記録で一回の変更を閉じてから、次のAI依頼へ進みます。Gitで記録できたことと、コードを採用してよいことは別です。次はテスト結果と要件、設計、セキュリティ、依存関係を基に変更をレビューします。

出典

  • Git - git-status Documentation — 作業ツリー、インデックス、HEAD、未追跡ファイルの状態表示。Git 2.53.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-diff Documentation — 作業ツリー、インデックス、HEAD、コミット間の差分。Git 2.55.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-add Documentation — インデックスへの追加とpatch単位のステージ。Git 2.54.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-commit Documentation — インデックスからコミットを作る通常動作と、オプションによる対象変更。Git 2.55.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-branch Documentation — ブランチの先端と現在のブランチ。Git 2.51.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-switch Documentation — ブランチの作成・切替と作業ツリー、インデックス。Git 2.55.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-restore Documentation — 作業ツリーとインデックスの復元先。Git 2.55.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-revert Documentation — コミットの効果を打ち消す新しいコミット。Git 2.54.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-reset Documentation — モードごとのHEAD、インデックス、作業ツリーへの作用。Git 2.54.0のマニュアル更新を2026年8月20日に確認。
  • Git - gitignore Documentation — 未追跡ファイルに対するignore pattern。Git 2.55.0のマニュアル更新を2026年8月20日に確認。
  • Git - git-rev-parse Documentation — HEADの検証と現在のコミットの識別値。Git 2.52.0のマニュアル更新を2026年8月20日に確認。
  • GitHub Docs: Removing sensitive data from a repository — 秘密情報の失効・更新と履歴書換えの副作用。2026年8月20日に確認。
  • OpenAI: Agent approvals & security — Codexのサンドボックス、承認方針、バージョン管理の推奨。2026年8月20日に確認。