これまでは、コードを書いてコミットし、pull requestを作成する理想的な流れを見てきました。でも実際には、ファイルを追加し忘れたり、コミットメッセージを打ち間違えたり、作業の方向を間違えたりすることもあります。この記事では、IDEの機能を使ってよくある問題に対処する方法を見ていきます。

例と画面キャプチャはJetBrains IDEのものです。操作名や場所はお使いのバージョンによって異なる場合があります。練習には専用の学習用リポジトリを使ってください。実際のプロジェクトでは、そのプロジェクトのブランチ、コミット、変更の送信に関するルールに従いましょう。

プロジェクトでClaude Codeを使うとき、保存された履歴があれば以前の状態に戻せます。ただし、Gitはキー入力のたびに記録するわけではありません。コミットしていない変更は失われることがあります。取り消す前に、ブランチと対象ファイル、必要なコピーがあるかを確認してください。

Rollback - ローカル変更を取り消す

場面: ファイルを変更したものの、変更内容がすべて間違っていたと分かり、直近のコミットの状態にすぐ戻したい場合です。

"Rollback - ローカル変更を取り消す"セクションの図

Rollbackを使います:

  1. 左側のパネルでCommitタブを開きます。
  2. 一覧から取り消したい変更済みファイルを探します(複数選択もできます)。
  3. 右クリックしてRollbackを選びます(または、丸い矢印のアイコンをクリックします)。

IDEは選択したローカル変更が失われることを警告します。まずdiffを確認し、必要な変更を保存してください。本当に破棄したい変更だけRollbackを確定し、その後結果を確認します。これはコミットしていない作業の削除であり、バックアップではありません。

ご注意ください

Rollbackの前に、エージェントが加えた変更と同じファイルにあった以前の変更を切り分けてください。Rollbackは選択したファイルを直近のコミット(HEAD)の状態に戻し、ステージ済み・未ステージの変更をどちらも破棄します。これはフラグなしのgit restoreとは異なります。git restoreはインデックスから内容を取り出し、作業ツリーのファイルだけを変更します。

Amend - 直近のコミットに変更を加える

場面: Commitをクリックした直後に、大事なファイル(更新したテストなど)を含め忘れた、またはメッセージを打ち間違えたことに気づきました。コミットをまだ公開していなければ、Amendを使えます。特にすでに共有された履歴では、別の修正コミットを作る方法も適切です。

"Amend - 直近のコミットに変更を加える"セクションの図

未公開のコミットを補うには、Amend(補足・修正)機能を使います:

  1. Commitウィンドウで、追加し忘れたファイルを修正し、そのファイルにチェックを入れます。
  2. Commit MessageパネルでAmendチェックボックス(または歯車アイコン -> Amend Commit)を見つけて選択します。
  3. IDEに前のコミットメッセージが表示されます。必要なら編集してください。
  4. Commitをクリックします。

Amendは前のコミットを置き換える新しいコミットを作成するため、識別子も変わります。古いオブジェクトをその場で編集するわけではありません。前のコミットをすでにpushしていて、ほかの人も使っている場合は、通常は別の修正を作るほうがよいでしょう。

この機能の詳細は、JetBrains公式チュートリアルをご覧ください。

Undo Commit

場面: コミットを作成したものの、Pushでまだ送信していないうちに、急ぎすぎたと気づきました。コミットを履歴から取り除きつつ、変更自体はエディターに残して作業を続けたい場合です。

Undo Commit機能を使います:

  1. 下部のGit -> Logタブを開きます。
  2. 共通グラフの一番上ではなく、現在のブランチ(HEAD)の直近のコミットを見つけて、コンテキストメニューを開きます。
  3. Undo Commitを選択します。
"Undo Commit"セクションの図

変更リスト(通常はDefault Changelist)を選び、OKをクリックします。コミットは履歴から消え、ファイルは変更済みの状態でCommitウィンドウに戻ります。変更は失われないので、そのまま作業を続けられます。

Reset - ブランチの移動とファイルの状態

Reset Current Branch to Here...は、ブランチの参照先を選択したコミットへ移動する強力な機能です。状況によって、直近の操作を穏やかに取り消すことも、壊れたコードをまとめて消し去ることもできます。

ケースA - 直近のローカルコミットを取り消す

Pushする前にローカルでいくつかコミットを作り、ブランチで進めてきた作業が間違いだったと気づいた場合です。

  1. Git -> Logタブを開きます。
  2. 戻りたい直近の正常なコミット(誤った一連のコミットより前のもの)を見つけます。
  3. 右クリックしてReset Current Branch to Here...を選択します。

ケースB - サーバー上の状態に戻す

リモートブランチを基準に、追跡対象のファイルを復元したい場合です。まず必要なローカル作業を保存し、Fetchを実行してください。origin/mainラベルが示すのは最後に取得した時点の状態で、サーバーの最新状態を常に反映しているわけではありません。競合を伴う操作の途中なら、先に解決して完了するか、操作を取り消してください。Hardを万能な解決策として使わないでください。

  1. Git -> Logを開きます。
  2. リモートブランチのマーカーを見つけます。通常は紫色のラベルが付いたコミットで、origin/main(またはorigin/ブランチ名)と表示されます。これはサーバー上のコードについて、最後に確認できた状態です。
  3. そのコミットを右クリックしてReset Current Branch to Here...を選びます。
Reset Current Branchウィンドウ

Resetのモード

Resetウィンドウでは、よく考えてモードを選んでください。どのモードでも現在のブランチは選択したコミットへ移動しますが、インデックスと作業ツリーの扱いが異なります:

  • Softは作業ツリーとインデックスを保持します。Mixedは作業ツリーを保持しつつ、インデックスを選択したコミットの状態に戻すため、差分は未ステージのまま残ります。どちらもファイルの内容を使って作業を続けられますが、異なるモードです。
  • Hardはインデックスと追跡対象ファイルを選択したコミットの状態に戻し、コミットしていない変更を破棄します。通常の無関係なuntrackedファイルは残ることがありますが、復元を妨げるパスは削除される場合があります。コミットがすべての保存先から直ちに消えるわけではありませんが、後から作業を救出できると期待しないでください。

push後にすること

場面: pushした後で、初めて間違いに気づきました。

コミットがサーバーに届くと、プロジェクトの共有履歴の一部になります。この履歴を書き換えようとすると(ResetやAmendを使うなど)、同僚に大きな問題を起こすことがあります。同僚がすでに変更をダウンロードし、その上で作業を始めているかもしれません。

安全で適切な方法: 間違いを直す新しいコミットを作り、通常のpushで送信します。これは一般的なやり方です。問題のあるコードの後に分かりやすい修正コミットが続く直線的な履歴なら、プロジェクトの変化をチーム全員が追いやすくなります。

IDEにはRevert Commitという専用機能もあります。Git -> Logで問題のあるコミットを右クリックし、Revert Commitを選ぶと、IDEは元の変更と正反対の変更を行う新しいコミットを作成します(たとえば、追加した行を削除します)。

"push後にすること"セクションの図

Revertは、公開済みの変更を新しいコミットで取り消すときに便利です。コードにも文章にも使えますが、その後の変更と競合する場合があります。競合を解決したら、結果を確認してください。依存関係が複雑な場合は、別の修正コミットのほうが分かりやすいこともあります。

Stash / Shelve - 変更を一時退避する

場面: 新機能のコードを書いていて、ファイルが赤や青で表示されています。そこへチームリーダーから"作業を止めて、mainブランチのバグをすぐ直して"と頼まれました。未完了で競合する変更があるため、mainに切り替えられません。プロジェクトのルール上、一時的なローカルコミットが可能な場合もありますが、今はコミットしたくないなら作業を退避できます。

作業を一時的に仮想の箱へしまう方法があります。GitではStashと呼び、IDEには別の機能としてShelve(棚に置く)があります。

  1. Commitウィンドウを開き、変更したファイルを選びます。
  2. Shelve Changes...を選択します。この手順はShelve用で、Git Stashは別に実行します。
  3. 分かりやすい名前を付けて、Shelveをクリックします。
"Stash / Shelve - 変更を一時退避する"セクションの図

Shelveした後、残っているファイルを確認してください。必要な変更がすべて退避されたでしょうか。これでmainに切り替え、バグを修正して、プロジェクトのルールに沿って結果を保存できます。次に作業ブランチへ戻り、Shelfを開いてUnshelveを選びます。

Git Stashの場合は、専用のstash一覧から必要なエントリーを復元してください。Shelveとは別の保存先です。通常のstashでは、追加オプションなしだと新しいuntrackedファイルは含まれません。ブランチを切り替える前に、必要な作業がすべて保存されているか確認しましょう。復元時に競合することもあるため、復元後もファイルを確認してください。

Git Logを使った詳しい調査

Git -> Logウィンドウはコミットの一覧にとどまらず、変更を調べるための強力なツールです。

  • コミットハッシュはa1b2c3dのような英数字の文字列です。コードの各スナップショットを識別する一意のIDです。ログに表示されたコミットハッシュ
  • ブランチ、作成者、日付、コミットメッセージ内の語句で履歴を絞り込めます。特定の部分を誰がいつ変更したかをすばやく調べられます。
  • 特定のコード行が追加または削除されたコミットを探すには、Logウィンドウでメッセージだけでなく変更内容も検索できます。
  • エディターのガター(行番号がある部分)を右クリックしてAnnotate with Git Blameを選ぶと、各行を最後に変更した人とコミットがIDEに表示されます。その後コミットと関連する議論を開いてください。Blameが示すのは行の直近の変更であり、その理由までは分かりません。

注意が必要な操作 - Force Push

push済みのコミットを書き換えるのはよくない、と確認しました。それでもUndo CommitやAmendでローカルの履歴を変更し、サーバーには古い状態が残っている場合はどうでしょうか。通常のpushでは、共有履歴が上書きされないようGitがエラーを返します。

Force pushを使うと、新しい履歴が以前の履歴を引き継いでいない場合でも、選択したリモート参照を置き換えられます。サーバー全体を消去するわけではありません。影響する範囲は送信する参照によって異なり、ブランチ保護によって拒否される場合もあります。

Force pushを使うと、ローカル履歴にないコミットがリモートブランチから取り除かれることがあります。そのため、共有ブランチの履歴を書き換えるには、チームで別途合意が必要です。通常の修正には、新しいコミットかRevertを使ってください。

Force pushを検討する典型的な場面は、合意のうえで自分のブランチの履歴を書き換えた後です。その場合でも、ほかの人が新しいコミットを追加していないか確認してください。--force-with-leaseオプションは、リモートブランチが想定した状態かを確認しますが、置き換えるコミットを理解する必要がなくなるわけではありません。

スクリーンショットでは、Force PushはPushボタンのドロップダウンメニューにあります。使う前に、お使いのIDEのバージョンでどの強制送信モードが適用されるか確認してください。

Force Pushボタン

何をしているのか完全に分からない場合は、force pushを使わないでください。修正を含む新しいコミットを作るか、Revertを使うほうが安全です。

Claude Codeとの関係

このルールは、ご自身にもClaude Codeにも同じように当てはまります。共有履歴を書き換えるのは危険です。force pushを通常の手段として扱わず、共有ブランチで実行させないでください。Claudeがサーバー上の履歴を書き換える操作を提案したら、一度止まり、安全な代替案(新しいコミット、Revert)がないか確認してください。

プロジェクトを更新する

新しい作業を始める前に、ベースとなるブランチと未完了の変更を確認してください。必要に応じて更新を取得し、統合結果を確認します。Update Projectを実行しても競合がなくなるとは限りません。設定に応じてmergeまたはrebaseが使われます。

更新後は、現在のブランチ、コミット一覧、ファイルの状態を確認してください。競合が発生した場合は、作業を続ける前に解決します。

Git Logのコンテキストメニュー

Git -> Logタブを開いてコミットを右クリックすると、大きなコンテキストメニューが表示されます。便利なコマンドを用途別に見ていきましょう。

"Git Logのコンテキストメニュー"セクションの図

グループ1 - 表示と分析(安全な操作)

  • Copy Revision Number - コミットの一意なハッシュをクリップボードにコピーします。同僚にコミットを共有したり、タスクに記載したりするときに便利です(Jira、YouTrack)。
  • Compare with Local - 古いコミット内のファイルと、現在エディターにあるファイルを比較します。1か月前のコードを確認するのにも役立ちます。
  • Show Repository at Revision - コミット作成時点のプロジェクト内の全ファイル構成を開きます(現在のブランチは変わりません)。

グループ2 - ブランチ操作

  • New Branch... - 過去の選択したコミットから新しいブランチを作成します。作業をかなり進めた後ですべて壊してしまったと気づき、最後に動いていた地点から新しいブランチを始めたいときに便利です。
  • Checkout Revision - ローカルプロジェクトをこのコミットに切り替えます。detached HEAD状態になり、古いコードは実行できますが、新しいコミットはどのブランチにも紐づきません。detached HEADで必要なコミットを作成した場合は、まず新しいブランチで保存してください。戻るには通常のブランチ(たとえばmain)をCheckoutします。

グループ3 - 変更と移動

  • Cherry-Pick - 別のブランチから特定のコミットを取り出して、現在のブランチにコピーできます。たとえば、別ブランチで作業を妨げるバグが修正された場合、そのブランチ全体を統合せずに、該当コミットだけをCherry-Pickできます。
  • Edit Commit Message... - コミットをまだ送信していない(Pushしていない)場合、メッセージをすばやく変更できます。テキストだけを変えるならAmendより手軽です。

グループ4 - 変更を取り消す

これらのコマンドは先ほど詳しく説明しました:

  • Reset Current Branch to Here... - 現在のブランチをこのコミットまで移動します(このブランチからたどれる履歴が変わります)。
  • Revert Commit - 変更を取り消す"逆向きのコミット"をローカルに作成し、その後サーバーに送信します。
  • Undo Commit... - ローカルコミットを変更ウィンドウに戻します。

グループ5 - 履歴を書き換える

メニューにはSquash Commits...(複数のコミットを1つにまとめる)、Drop Commits(履歴の途中にあるコミットを削除する)、Interactively Rebase from Here...などもあります。どれもローカル履歴を慎重に編集するためのツール(Interactive Rebase)です。

ご注意ください

使い方に慣れるまでは、これらのコマンドを避けてください。選択したコミットと、その後のブランチ履歴を書き換える可能性があります。チームで作業するときは、レビュー用のpull requestを作る前に、ローカルの作業ブランチを整理するために使うことがあります。

Gitは作業を守るセーフティネット

作業の状態に応じて復元方法を選びましょう。コミット前のファイル、ローカルコミット、公開済みの履歴では、それぞれ必要な操作が異なります。必要なバージョンを保存し、操作前に変更を確認するほうが、どんな間違いも取り消せると期待するより確実です。

Claude Codeと一緒に使う

プロジェクトでClaude Codeを使うとき、これらのツールが一番の安全策になります。使い方を確認しましょう:

  • こまめにコミットを作成してください。各コミットが戻り先になります。エージェントが意図しない方向へ進んでも、直近の正常な状態に戻せます。
  • コミット前の変更を取り消すときは、まず必要な変更を切り分けてから、Rollbackやgit restoreで対象範囲と復元元を確認します。
  • コミット済みでも未送信なら、Undo Commitで変更をエディターに戻せます。
  • 間違いがすでにサーバーにあるなら、履歴を書き換えるより、修正コミットまたはRevertのほうが安全です。
ご注意ください

データを削除したり履歴を書き換えたりする操作(Reset hard、force push)を、内容を確認せずに承認しないでください。まずClaude Codeが何をしようとしているか確認します。大きな作業を始める前に必要な状態を保存し、戻り先に自分の作業が確実に含まれているかも確認してください。

前の記事: Pull requestの作成からマージまで · 次の記事: リポジトリの作成、rebase、シークレット