git resetの使い分け完全ガイド|–soft・–mixed・–hardとrevertの違い

コミットを取り消したいだけなのに、コマンドが複数あって迷う場面はよくあります。

ところが、git resetには--soft--mixed--hardという3つのオプションがあり、git revertという別のコマンドもあります。

そこで、この記事では「取り消したい範囲」と「共有済みかどうか」という2つの判断軸で、それぞれの使い分けを整理しました。

resetとrevertの違い

どちらも「なかったことにする」コマンドですが、履歴を消すか、履歴を残すかが決定的に違います。

コマンドオプション使うタイミングの目安何をするか
git reset–soft直前のコミットメッセージや粒度をやり直したいときコミットだけ取り消す(変更はステージに残る)
git reset–mixed(デフォルト)ステージし直してからコミットしたいときコミットとステージを取り消す(変更はワーキングツリーに残る)
git reset–hardその変更ごと丸ごと不要になったときコミット・ステージ・変更内容すべてを消す
git revert(オプションなし)共有済みのブランチで、履歴を残したまま取り消したいとき取り消し内容を新しいコミットとして追加する

resetは履歴そのものを書き換え、revertは打ち消しの記録を積み増します。この一点さえ押さえれば、どちらを使うべきかはほぼ自動的に決まります。

git resetの3つのオプション

–soft:コミットだけ取り消す

直前のコミットを取り消しつつ、変更内容はステージされた状態のまま残します。

Bash
git reset --soft HEAD~1

コミットメッセージを書き直したい、あるいは複数のコミットを1つにまとめ直したいときに使います。

–mixed:コミットとステージを取り消す(デフォルト)

オプションを省略した場合の挙動です。コミットとステージを取り消し、変更内容はワーキングツリーに残します。

Bash
git reset HEAD~1
# git reset --mixed HEAD~1 と同じ

ファイルの内容は消えないので、ステージするファイルを選び直してコミットし直したいときに使います。

–hard:全部消す

コミット・ステージ・ワーキングツリーの変更内容まで、すべて指定した状態に巻き戻します。変更内容そのものが消える、唯一のオプションです。

Bash
git reset --hard HEAD~1

実行前に、消えて困る変更が残っていないか必ず確認しましょう。地味に見落としがちですが、--hardはワーキングツリーの未コミット分も巻き込んで消えます。

実務で役立つTips

共有ブランチではrevertを使う

resetはコミット履歴そのものを書き換えるコマンドです。すでにリモートへpush済みで、他の人が同じブランチを見ている場合にresetすると、履歴の食い違いが起きます。

そこで使うのがrevertです。取り消したいコミットを打ち消す、新しいコミットを追加する形で処理します。

Bash
git revert <取り消したいコミットのハッシュ>

履歴を書き換えないので、他の人の作業に影響を与えません。「まだ自分しか見ていないローカルの作業ならreset、すでに共有したらrevert」と覚えておけば判断に迷いません。

–hardで消しすぎたときの復旧はreflog

もしreset --hardで必要なコミットまで消してしまっても、多くの場合はreflogから復旧できます。

Bash
git reflog
# 一覧からコミットハッシュを確認して
git reset --hard <復旧したいコミットのハッシュ>

reflogはHEADの移動履歴を記録しているので、resetやrebaseのやり直しにも使える保険です。ただし記録には期限があるので、過信は禁物です。

複数のコミットをまとめてresetする

HEAD~1の数字を変えることで、さかのぼるコミット数を指定できます。例えば直近3件をまとめて取り消したい場合は、以下のように書きます。

Bash
# 直近3件をまとめてsoftで取り消す
git reset --soft HEAD~3

revertで複数コミットをまとめて取り消す

コミット範囲を指定すれば、複数コミットをまとめて打ち消すコミットを作成できます。

Bash
git revert <古い方のハッシュ>..<新しい方のハッシュ>

ただしコンフリクトが起きやすくなるため、範囲が広い場合は1件ずつ確認しながら実行するほうが安全です。

まとめ

取り消す範囲で選ぶならsoft・mixed・hardのどれか、共有済みかどうかで選ぶならreset・revertのどちらか。この2軸を意識するだけで、取り消し系コマンド選びに迷わなくなります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

普段は主にPython開発をしています。
最近はAI駆動開発にも関わっています。

コメント

コメントする