【Git】git reset hard とは?初心者向けに注意点・手順をわかりやすく解説
はじめに
Gitを使っていると、過去の状態へ戻したい場面があるかもしれません。
誤ったコミットや不要な変更が積み重なったとき、git reset hard を使えば簡単に元の状態に戻せます。
しかし、操作を誤ると大事な作業内容を失う可能性もあります。
そこで本記事では、初心者の方にもわかりやすいように git reset の基本から --hard オプション の意味、さらに安全な運用方法までを順番に解説します。
この記事を読むとわかること
- git reset の基本的な仕組み
- git reset --hard の使い方と注意点
- 実務で考えられる活用シーン
- 間違って操作したときの対処法
- 安全に使うためのポイント
git reset hardとは何か
Gitには、コミット履歴を操作して作業ツリー(ファイルの内容)を巻き戻す仕組みがあります。
その中でも git reset コマンドは、指定したコミットにリポジトリの状態を合わせるものです。
ただし、オプション次第で扱いが大きく変わります。
ここでは --hard オプションが何を意味するのかを中心に見ていきましょう。
git reset の基本
まずは git reset の基本的な役割を整理します。
このコマンドは大きく分けて3種類のオプションを使い分けることが多いです。
--soft
インデックスやワーキングツリーには触れず、コミットだけを巻き戻します。
つまり、過去のコミット履歴に戻しつつ、実際のファイルの変更は残ります。
--mixed
インデックスも巻き戻しますが、ワーキングツリーにあるファイルの変更は残します。
そのため、再コミットが簡単にできる状態です。
--hard
インデックスとワーキングツリー、両方を巻き戻します。
これが今回メインで解説する内容です。
このように git reset は、コミット・インデックス・ワーキングツリーのどこを巻き戻すかを選択できるコマンドです。
--hard オプションの意味
--hard を指定すると、指定したコミットの状態に合わせて、実際のファイルの変更内容も含めてすべてを巻き戻します。
そのため、ローカルで作業中の変更点が失われる可能性が高い点が特徴です。
便利な一方で、取り返しのつかない操作になりやすいことを理解しておきましょう。
一般的に git reset --hard の記述例は以下のようになります。
git reset --hard HEAD~1
この例では、現在のコミットから1つ前のコミットに一気に戻します。
巻き戻し前に編集していたファイルの内容は、まるごと上書きされるので注意が必要です。
git reset hard のよくある使い方
git reset --hard は、作業を一気にリセットできるため、いくつか代表的なシーンで使われます。
作業中のミスが大きかったり、コミットの内容を丸ごと取り消したりしたい時に便利です。
過去のコミットへ戻す
コミット履歴を少しだけ巻き戻したいときに使われるパターンです。
誤ってコミットしてしまった変更を削除したい場合や、挙動を確認するために一時的に過去のバージョンに戻したいときなどに役立ちます。
例えば、以下のように入力すると2つ前のコミットへ戻ります。
git reset --hard HEAD~2
こうすると2コミット分巻き戻ったうえで、ワーキングツリーの内容も元通りになります。
一方で、そこから先に追加していたコミットは通常の方法では参照できなくなるので注意してください。
最新の状態に巻き戻す
リモートリポジトリの内容に合わせて、自分のローカルリポジトリをリセットしたいときもあるかもしれません。
例えば、チーム作業で「リモートリポジトリの方が正しい状態だから、手元の変更は全部捨てたい」という状況です。
その場合は、以下のようにリモートブランチにリセットできます。
git fetch origin git reset --hard origin/main
これで、ローカルリポジトリはリモートリポジトリの main
ブランチと同じ状態になります。
作業中の変更はすべてリセットされるため、最新の正しい状態を手元で再現しやすくなります。
git reset hard を使う上での注意点
便利な git reset --hard ですが、一度実行すると戻せない変更が出てくる可能性があります。
使いどころを誤ると履歴が壊れたり、別の開発者が作業している履歴との衝突が起きたりするかもしれません。
取り消しが困難になる
git reset --hard を行うと、作業ファイルも含めて過去の状態に巻き戻されます。
そのため、ローカルで行った編集の履歴が消えてしまいます。
「ちょっとした修正を取り消しただけ」というつもりでも、思いがけない修正まで失う可能性もあるでしょう。
この巻き戻しによって失われた作業を後から取り出すのは難易度が高いです。
一部のケースでは git reflog
などを活用して救済できる場合もありますが、必ず復旧できるとは限りません。
変更履歴の消失
git reset は、過去のコミット履歴を上書きする操作のため、チームメンバーと共有しているリポジトリでは混乱が生じやすいです。
共同作業中に誤って --hard で巻き戻すと、他の人がコミットした履歴を壊してしまう恐れもあります。
特に、すでにプッシュ済みの履歴を --hard で巻き戻し、その後に再度プッシュすると、元のコミットを消去してしまうような形になるかもしれません。
そうなると、他のメンバーの作業内容が消えてしまうリスクがあります。
安全に使うためのポイント
「便利だけど危険」という二面性を持つ git reset --hard。
ここでは、できる限り安全に使うためのポイントをまとめます。
stash コマンドとの併用
もし今の作業内容を完全に失いたくない場合は、stash で一時保存してから reset --hard する方法が考えられます。
stash で作業内容を退避し、その後に git reset --hard を行えば、いざというときに stash から復元できる可能性があります。
たとえば、以下のような流れが考えられます。
git stash save git reset --hard HEAD~1 git stash pop
このようにすれば、コミット履歴自体は巻き戻しつつ、一時保存していた作業を再度取り込むことができます。
ただし、コンフリクトが発生する場合もあるので慎重に扱いましょう。
別ブランチの活用
一連の作業を別ブランチで行う習慣をつけておくと、--hard の誤操作による被害を最小限に抑えられます。
開発用ブランチを作り、そこで実験的なコミットを積みながら作業するイメージです。
メインブランチに大きな影響を与えたくない場合、テストしたい変更点があるときなどは、まずは別ブランチを切るようにしましょう。
仮に --hard を実行しても、本流の履歴にダメージが及びにくくなります。
自分だけの作業ブランチであれば、リセット系コマンドを利用しても他メンバーの履歴に混乱を与えるリスクが減らせます。
実務で考えられる活用シーン
実際に開発現場では、どんなタイミングで git reset --hard を使うのか、具体的に考えてみましょう。
コードの大幅なやり直し
機能実装途中で「やっぱりこの設計は合わない」「もっとシンプルな方法に変更したい」と感じることがあります。
ファイル構成やコードの大部分を変更してしまい、手戻りが多いと判断したとき、--hard を使って一気にやり直すことがあります。
ただし、このような場合は、周囲の作業状況を確認したり、ブランチを分けて作業していたりすることが前提です。
後戻りできない操作であることをいつも意識しましょう。
リポジトリをクリーンな状態に保つ
複数の開発者が参加していると、不要なファイルや間違ったコミットが混在してしまうこともあります。
そうしたコミットをまとめて取り消して、リポジトリを整理し直したいときにも --hard が使われる場合があります。
ただし、こうした操作はよく議論されてから実行されることが多いです。
誰かの作業が消えてしまうリスクがある以上、十分なチーム内コミュニケーションが必要だといえます。
エラーやトラブルがあった時の対処方法
万一、git reset --hard を誤って実行してしまった場合や、結果として大事なコミットを消してしまった場合は、どうすればいいのでしょうか。
ここではいくつかの対処方法を紹介します。
reflog を使った復元
Gitには reflog という履歴追跡機能があり、過去にどのコミットが参照されていたかを追えます。
誤ってコミットを消したり、ブランチを巻き戻したりしても、reflog に履歴が残っていれば復元できるかもしれません。
git reflog
このコマンドで表示されたコミットハッシュを指定して、再度 git reset --hard すれば、巻き戻す前の状態に近いところまで戻せる場合があります。
ただし、reflog の履歴も永久ではないので、時間が経つと消える可能性があります。
どうしても復元できない場合
もし reflog や stash などを駆使しても取り戻せない場合は、残念ながらデータを諦めるしかないかもしれません。
その場合は何が原因だったのかをしっかり振り返り、次回以降に備えることが大切です。
一度失われたデータの完全な復元は難しいことがあります。作業内容を消してしまわないよう、こまめにブランチを分けたりプッシュしたりする運用が大切です。
まとめ
git reset --hard は、コミットと作業ツリーを一気に巻き戻すためのコマンドです。
誤ったコミットを消去したり、一度作業内容を完全にやり直したりする場合には便利といえます。
しかし、操作を誤ると復元が困難になるリスクがあるため、事前に stash を活用したり、別ブランチを分けたりして安全策を講じることが重要です。
特にチーム開発では、他のメンバーの作業に影響が及ばないように注意しましょう。
どのような状況で git reset --hard が役に立つのかを理解し、正しい場面で活用してみてください。