Engineering git

git入門:git resetの使い方 - 直前のコミットを取り消す方法

コードをローカルでcommitした後に修正したくなるケースがあります。そのようなときにはgit revertを使って取り消しcommit自体を作ることもできますが、git resetを使ってcommit自体を消すとコミットグラフもきれいに保つことが出るのでお勧めです。本記事では、git resetの使い方について解説したいと思います。

git resetとは?

git resetはgitのコマンドの一つになります。主にはgit addしてインデックスに追加した状態をワーキングツリーに戻したり、git commitでローカルリポジトリにcommitした変更自体を消すことができます。

git のおさらい

ここでgitについて簡単におさらいしておきます。gitでは以下の4ステージが存在しており、ソースの変更をそれぞれの状態に遷移させることで構成管理を行っています。

  • ワーキングツリー
  • インデックス
  • ローカルリポジトリ
  • リモートリポジトリ

よく使う以下のコマンドは、コードの変更をそれぞれの状態に移動させるコマンドになります。

  • git add : ワーキングツリー → インデックス
  • git commit : インデックス → ローカルリポジトリ (いわゆるコミットする)
  • git push : ローカルリポジトリ → リモートリポジトリ

この前提のもと、git resetの動作について解説していきます。

git resetの主な使い方

さっそくgit resetのよく使うケースを解説します。

git add を取り消す

git add自体を取り消す場合には、git resetとそのまま打つことで、インデックス環境に置かれている変更がすべてワーキングツリーに戻ります。この時ファイルの変更自体は取り消されないので、再度そのままcommitを行うことも可能です。

# git addしたことを取り消す
git reset

git commit を取り消す

git commit、いわゆるコミット自体を取り消す方法にはいくつかパターンがあります。

commitだけを取り消す

git commit したことだけを取り消す場合には--softオプションを使います。これを行うことでリモートリポジトリの変更が取り消されます。以下のHEAD^を付けることで、直前のコミットをなかったことにできます。

git commit --soft HEAD^

commitとaddを取り消す

git commit とgit addを取り消す場合には、--mixedを使います。これを行うことで、変更がワーキングツリーまで戻ります。git resetのオプションは基本これがデフォルトになっています。

git reset --mixed HEAD^

コミットとaddと変更内容そのものを取り消す

ワーキングツリーで自分が行った変更も取り消したい場合には--hardオプションを付けます。個人的にはあまり使うことはないのですが、変更そのものが不要になった際には、使うことがあります。

git reset --hard HEAD^

git revertとの違いは?

似たようなコマンドにgit revertがあります。git resetはコミット自体を取り消すのに対して、git revertはコミットを取り消すコミットを追加します。なので履歴としてグラフにコミットが残ります。git resetの場合は後述する通り、リモートリポジトリへの変更が通常のgit push -u originなどでは行えませんが、git revertであればコミットを追加することになるので、リモートへの変更をpushすることが可能です。

使い分けとしては、以下で覚えておくとよいでしょう。

  • ローカルリポジトリでの変更を修正したい場合は、git reset
  • リモートリポジトリでの変更を修正したい場合には、git revert

リモートリポジトリのコミットを消したい場合には

基本的にリモートリポジトリに行った変更は、git resetをやっても消すことはできません。あくまでもローカルでの変更になります。もしどうしてもリモートのコミットを削除したい場合には、git resetをした後にforce pushを行うことで、無理やりコミットグラフを書き換えて、削除することもできます。

# ローカルで直前のコミットを取り消し
git reset --soft HEAD^
# 強制的にローカルの状態をプッシュ
git push -f origin

上記は強制的にリモートのグラフを書き換えるので、変更の履歴等も残らないため、mastermainのブランチでやることはお勧めしません。どうしても自分の作業ブランチをきれいに保ちたい場合には、上記を実行することも仕方ないですが、安全にやるのであれば、git revertでリバートコミットを打つ方をお勧めします。

まとめ

git resetを使って、直前のコミットを削除する方法などを解説しました。gitを使い始めたときは、修正するコミットをわざわざ作ってコミットしてたのですが、git resetを知ってからは作業スピードも相当速くなりました。git 初心者でまだ使ったことのない方がいればぜひ使ってみてください。

-Engineering, git
-,