AIの修正だけ戻したい|Gitで自分の変更を残す練習

AIの修正だけ戻したい|Gitで自分の変更を残す練習を説明する図。操作画面ではありません。 個人開発・公開

AIにコードの修正を頼んだあと、「色は元に戻したい。でも、自分で書いた見出しは残したい」となったら、ファイル全体を戻す前に差分を確認します。同じファイルの一部だけなら git restore -p、コミット済みの変更を打ち消すなら git revert が候補です。

ただし、Gitは「誰が書いたか」を自動で判別して戻してくれるわけではありません。残す変更を自分で選ぶ必要があります。この記事では、見出しと色が一緒に変わったHTMLを使い、必要な変更だけを残すところまで練習します。

今回の検証はLinux・Git 2.52.0で実施しました。自分の編集とAIの編集が混ざる場面を、架空のHTMLに変更を加えて再現しています。実際の制作物でAIが起こした不具合の報告ではありません。操作はmacOS・Linuxのターミナル、WindowsならGit Bashを想定します。

先に、自分の変更がどの状態にあるかを確認する

作業中のプロジェクトで困っている場合は、AIによる追加編集を止め、エディタの未保存ファイルを保存します。そのうえで、戻そうとしているファイルをプロジェクト外へコピーしてください。Gitが追跡していない新しいファイルも、必要なら一緒にコピーします。

次の表は行き先を選ぶためのものです。取り消しコマンドは各節の条件を確認してから使います。

いまの状態 先に見るもの この記事での操作
未コミット。残す変更と戻す変更が混在 git diff 変更のまとまりごとに選ぶ
git add済み git diff --staged ステージから外して再確認する
コミット済み git logとgit show 対象コミットをrevertする
pushして共有済み 対象コミットと共有先の運用 打ち消すコミットを追加して共有する
新規ファイルに??が付いている ファイルを開いて中身を確認 未追跡ファイルとして別に扱う

以降は本番のプロジェクトではなく、空の練習フォルダで進めます。まだ初回コミットがない場合は、先にGitの準備とコードを保存する手順も確認してください。今回の練習自体にGitHubアカウントは不要です。

準備:1枚のHTMLをGitに記録する

Git、テキストエディタ、ブラウザを用意します。ターミナルで、既存のプロジェクトの外に新しいフォルダを作ります。同名のフォルダがある場合は、別の名前にしてください。

git --version
mkdir git-undo-practice
cd git-undo-practice
git init -b main

エディタでこのフォルダを開き、次をindex.htmlとしてUTF-8で保存します。後の差分を分けやすくするため、改行はこのままにします。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Gitの取り消し練習</title>
  <style>
    :root { --accent: #176b54; }
    * { box-sizing: border-box; }
    body { margin: 0; padding: 48px 20px; background: #eef3ef; color: #20392f; font-family: sans-serif; }
    main { max-width: 660px; margin: auto; padding: 32px; background: white; border-top: 12px solid var(--accent); border-radius: 12px; }
    small { color: var(--accent); font-weight: bold; }
    h1 { font-size: clamp(25px, 5vw, 36px); line-height: 1.5; }
    p { line-height: 1.9; }
    .badge { display: inline-block; padding: 10px 16px; background: var(--accent); color: white; border-radius: 8px; }
  </style>
</head>
<body>
  <main>
    <small>GIT PRACTICE / 架空サンプル</small>
    <h1>公開前の練習ページ</h1>
    <p>この見出しの変更は残し、色の変更だけを戻す練習です。</p>
    <p class="badge">コードの差分と画面を確認</p>
  </main>
</body>
</html>

index.htmlをブラウザで開くと、緑の帯と「公開前の練習ページ」という見出しが表示されます。これを戻り先として記録します。次の名前・メールはこの練習フォルダだけに設定される架空の値です。自分の制作物を公開する際は、実際に使うコミット名と公開してよいメールアドレスに設定してください。

git config user.name "Practice User"
git config user.email "practice@example.invalid"
git add -- index.html
git commit -m "Create practice page"
git status --short

最後のコマンドで何も表示されなければ、この練習フォルダに未コミットの変更はありません。

練習1:見出しを残し、色の変更だけを戻す

残す変更と、取り消す変更を作る

index.htmlの2か所を編集して保存します。まだgit addはしません。

  • 残したい編集:公開前の練習ページを僕の制作ノートへ変更。
  • 取り消したい編集:--accent: #176b54を--accent: #d64d25へ変更。

「自分で変えた見出しは残したいが、追加された色の変更は採用しない」という場面の再現です。ブラウザを更新すると、見出しも帯の色も変わっています。

部分的に戻す前の実サンプル。見出しは僕の制作ノート、帯とラベルはオレンジ色
今回のHTMLをChromiumで表示した実画面。ここから色だけを戻します。

取り消す前の状態を残すため、ファイルを1階層上へコピーします。同名のバックアップがある場合は、上書きせず別名にしてください。

cp index.html ../index-before-restore.html
git status --short
git diff -- index.html

git status --shortには、左に空白がある M index.htmlが出ます。未ステージの変更がある、という意味です。git diffでは色と見出しの変更が表示されます。

-    :root { --accent: #176b54; }
+    :root { --accent: #d64d25; }

-    <h1>公開前の練習ページ</h1>
+    <h1>僕の制作ノート</h1>

上は差分の変更行を抜粋したものです。-が比較元の行、+が変更後の行を示します。どちらを残すかを、ここで確認します。

git restore -pで、戻すまとまりを選ぶ

git restore -p -- index.html

-pは、差分をまとまりごとに見ながら選ぶための指定です。このまとまりを「hunk(ハンク)」と呼びます。今回のHTMLでは、色と見出しが離れた位置にあるので、2つに分かれて表示されました。

  1. 色の差分が出たら、yを入力してEnter。色の変更を取り消します。
  2. 見出しの差分が出たら、nを入力してEnter。見出しの変更は残します。

ここでのyは「この変更を採用する」ではなく、「この変更を捨てて戻す」です。実際の画面にはDiscard this hunk from worktreeと出ました。自分のファイルでは表示順が違うこともあるため、「最初はy」と暗記せず、表示された行を読んで選びます。

判断できないときはqで残りの選択を終了できます。ただし、その前にyで戻した部分まで自動で取り消されるわけではありません。必要なら、先ほどのコピーから内容を確認します。

成功したかは、差分と画面の両方で確認する

git diff -- index.html

差分に見出しの変更だけが残れば、意図した選別ができています。ブラウザを更新し、「僕の制作ノート」のまま色が緑へ戻ったことも確認します。

git restore -p実行後の実サンプル。僕の制作ノートという見出しを残したまま帯とラベルが緑色へ戻っている
実行後。色は戻り、残したかった見出しの編集はそのままです。390px幅でも同じ状態を確認しました。

今回は残したい部分と戻したい部分が別のまとまりでした。同じ行や近い位置に混ざって一つに表示された場合は、yでまとめて捨てずに中止し、エディタで必要な箇所だけ直す方法を選べます。Gitには分割などの対話操作もありますが、区切れない変更を無理に選ばないことが大切です。

見出しの変更を採用し、次の練習の戻り先にします。

git add -- index.html
git diff --staged -- index.html
git commit -m "Keep heading change"
git status --short

これで「緑色・僕の制作ノート」という状態がコミットされました。最後に何も表示されないことを確認してください。

練習2:git add済みだと、restoreしても戻らない?

もう一度、#176b54を#d64d25へ変えて保存します。今度は色の変更をステージします。

git add -- index.html
git status --short
git diff -- index.html
git diff --staged -- index.html

git status --shortはM index.htmlとなり、Mが左側へ移ります。git diffには何も出ず、git diff --stagedには色の変更が出ます。変更が消えたのではなく、比較する場所が変わったためです。

コマンド 比べる場所
git diff ステージと作業中のファイル
git diff --staged 最新コミット(HEAD)とステージ
git diff HEAD 最新コミットと作業中のファイル。追跡済みの変更をまとめて見る

この状態で次を実行しても、今回の色は緑に戻りませんでした。

git restore -- index.html

オプションなしのrestoreは、通常、ステージの内容を作業中のファイルへ戻します。ステージにもオレンジ色の内容が入っているためです。「常に最新コミットへ戻る」と考えると、ここで迷います。

今回の色変更を捨てるには、まずステージから外します。この1行では、作業中のファイルの色は変わりません。

git restore --staged -- index.html
git diff -- index.html

差分が色の変更だけで、捨ててよいことを確認できたら、ファイルを戻します。

git restore -- index.html
git status --short

何も表示されず、画面が緑色へ戻れば完了です。今回はこのファイルの未コミット変更をすべて捨てています。残したい編集も混ざっていたら、ステージを外した後に練習1のgit restore -pで選びます。ステージと作業中のファイルで内容が違う場合は、両方の差分を保存・確認してから進めてください。

比較元と復元元の指定は、Git公式のdiff解説とrestore解説でも確認できます。

練習3:コミット済みなら、打ち消すコミットを作る

今度は色をオレンジへ変えて保存したあと、コミットまで進めます。見出しは「僕の制作ノート」のままです。

git add -- index.html
git commit -m "Try orange accent"
git status --short
git log --oneline -3
git show HEAD -- index.html

HEADは現在の最新コミットを指します。ここでは、直前に作ったTry orange accentの変更が色だけであることを確認します。未コミットの変更がなく、これを打ち消してよければ次を実行します。

git revert --no-edit HEAD
git log --oneline -3
git status --short

--no-editは、コミットメッセージ編集用のエディタを開かずに進める指定です。ログの先頭にRevert "Try orange accent"というコミットが増え、元のTry orange accentも残ります。画面では色が緑へ戻り、見出しは維持されます。

今回のように色だけが一つのコミットになっていれば、取り消す対象も明確です。同じコミットに、残したい機能と不要な変更が混ざっていた場合、コミット全体のrevertは目的に合いません。その場合は必要な箇所を編集し、修正コミットとして記録する方法を検討します。

push済みでも、元の履歴を残して共有する

すでに共有したコミットを取り消したい場合も、対象を確認してrevertコミットを追加する方法が使えます。最新とは限らないため、実際の作業ではgit log --onelineで対象のコミットIDを調べ、git showで中身を確認します。

abc1234は例です。自分の履歴にある、取り消したいコミットIDへ置き換えます。取り消し前は未コミットの変更を解消し、進行中のマージなどがない状態で行います。git status --shortに何か出たら、その内容を先に確認してください。

git status --short
git log --oneline -5
git show abc1234 --

表示されたコミット全体を打ち消してよいと確認できたら、同じコミットIDを指定して実行します。

git revert --no-edit abc1234

revert後も画面やテストを確認し、通常のpushまたはPull Requestで共有します。保護されたブランチでは、そのリポジトリの手順に従います。今回の検証では、一時フォルダに作った共有先と別のcloneを使い、revertを通常のpushで送り、受け手がgit pull --ff-onlyで取り込めることを確認しました。GitHub上の実プロジェクトは変更していません。

元のコミットは履歴に残ります。つまり、revertは履歴から秘密情報を消す方法ではありません。また、コードを戻すだけでは、データベース更新や送信済みメールなど、外部で起きた処理までは戻りません。仕組みの詳細はGit公式のrevert解説を参照してください。

止まったときに確認する場所

git diffが空なのに、変更が残っている

まずgit diff --stagedを確認します。すでにコミット済みならgit logとgit showです。エディタで未保存の場合、Gitはまだディスクへ保存されていない内容を見られません。

??の新しいファイルが消えない

??は、まだGitが追跡していないファイルです。通常のgit diffには内容が出ず、git restoreでコミット前の状態へ戻すこともできません。ファイルを開いて確認し、残す・別フォルダへ退避する・不要なら削除する、のどれかを選びます。今回の練習では、新しく作ったメモファイルがrestore後も残ることを確認しています。

revertでCONFLICTになった

対象コミットの後に同じ場所が変更されていると、自動では打ち消せない場合があります。git statusで対象ファイルを確認します。判断できず、いったんrevert前へ戻したい場合は、進行中のrevertを中止します。

git status
git revert --abort
git status

今回の検証では、色を続けて2回変えた後、古い変更をrevertして競合を発生させました。--abort後は、revert開始前の内容とコミットへ戻ることを確認しています。中止前に競合ファイルへ手で加えた解決案も残したい場合は、別にコピーしてください。

fatal: not a git repositoryが出る

ターミナルで開いているフォルダが違う可能性があります。今回ならgit-undo-practiceへ移動します。実プロジェクトで場所が分からないまま、新しくgit initし直して解決しようとしないでください。

次からは、AIへ依頼する前に戻り先を分ける

変更が混ざる前なら、取り消しをもっと選びやすくできます。自分の変更を確認してコミットし、AIには一つの目的に絞って依頼します。作業後は未ステージとステージ済みの差分を両方確認し、動作を見てから次のコミットへ進めます。

例えば、次のように頼めます。これは権限を強制する設定ではなく、作業範囲を伝える依頼文です。結果の差分は別に確認します。

まずgit statusと差分を読み、既存の変更があれば説明してください。
今回の変更はindex.htmlの色だけです。見出しは変更しないでください。
編集後は変更した行と、ブラウザで確認した結果を説明してください。
コミットとpushは、まだ実行しないでください。

ブランチを作るだけでは、未コミットの編集がコミットとして保存されるわけではありません。「別ブランチにしたから何でも戻せる」と考えず、依頼前にどの変更を記録したかを確認します。

コードを戻せたら、見た目の崩れの原因を調べる作業へ進めます。Chrome DevToolsでCSSと通信を確認する手順は、修正前後を見比べるときにも使えます。AIへの依頼の進め方はClaude CodeをVS Codeで使う入門へまとめています。

差分の記号は分かっても、変更されたHTMLやCSSの意味を読むのが難しい場合は、基礎を順番に学ぶ方法もあります。HTML・CSSの入門書を目的で選ぶ記事では、制作を進めたい場合と、基本を整理したい場合を分けています。紹介しているのはHTML・CSSの本なので、Gitの学習用として選ぶものではありません。

今回確認した範囲は、追跡済みのHTML1ファイルの部分復元、ステージの解除、通常コミットのrevert、ローカルの共有先への反映、競合時の中止です。マージコミットのrevertや本番デプロイの巻き戻しは、この記事の手順には含めていません。

タイトルとURLをコピーしました