9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Git】コミットの取り消し方をおさらいしよう!【初心者】

Last updated at Posted at 2023-12-02

概要

この記事で扱うこと

  • Gitの基本的なコマンドであるgit resetgit revertの扱い方
  • git resetgit revertのイメージ

この記事を読むべき人

  • Git初心者
  • 「addとかcommitとかはわかるけど実践で使ってみたらなんかよくわからん!」という方

「Gitって?」「リモートリポジトリって何?」といった基本の「き」的な内容は取り扱いません🙇

初めに

WHIのアドベントカレンダ―本日分を担当させていただきます!
git add, git commit, git pushなど、リモートリポジトリへ反映する方法はなんとなく知っていても、それを取り消す方法って意外にまとまってないですよね…
自分も新卒エンジニアという身なので、改めてGitの使い方をおさらいしようと思います!

git reset, revert の基本的な使い方

というわけで、まずは基本的な使い方からまとめていきます。

git reset

$ git reset --soft HEAD^  //直近のcommit等を取り消す
  • 直前の操作を取り消します。(commitやpushなど)

  • 第1引数ではどのレベルで巻き戻すかを指定します。

    • --soft : 直前の操作のみを取り消し、編集をステージング(git add)した状態に戻す
    • --mixed : 直前の操作とステージングを取り消し、編集したばかりの状態に戻す
    • --hard : 直前の操作・編集を丸ごとなかったことにする(※使用注意!
  • 第2引数ではどのコミットまで戻すかを指定します。

    • HEAD^ : 直前の操作を元に戻す
    • HEAD^^ : 直近2回分の操作を元に戻す(以下、^の数で戻す回数を指定)
    • コミットIDの指定 : 指定したIDのコミットまでの操作を元に戻す
      • コミットIDはgit logコマンドやGithubのコミット履歴(※)で確認可能
        ※ 画像赤枠部
        スクリーンショット 2023-11-27 234621.jpg

git revert

$ git revert コミットID 
  • 指定したのコミットを打ち消すコミットを作成します。例えば「Aという文字を書き加える」というコミットを対象にrevertを実行すると、「Aという文字を削除する」というコミットが作成されます。

  • 引数では打消しのコミットの対象を指定します。

    • コミットIDの指定 : 上述のgit resetの参照方法と同じ
  • コミット時と同様、コマンドを実行するとコミットメッセージの編集画面に遷移します。任意のメッセージを入力し、:wqで保存&quitしてください。

  • 「逆向きの変更は作りたいが、一度にコミットまでしたくない」という場合はgit revert -n コミットIDのように[-n]コマンドが使えます。

何が違う?

両者の基本的な使用法はおさらいしました。ですが、どのような差があり、どう使い分ければいいのでしょうか?

結論からいうと、両者の差はコミット履歴が残るかどうかという点だけです。
ここでは両者のイメージをまとめておきます。

git reset

resetはコミットそのものをなかったことにし、今いる地点を正とします。
image.png
過去を改変したことによってその先の未来がなくなってしまうイメージです。その手のアニメだとあるあるですね!
コミット履歴まで消えてしまうため、ユースケースとしては

  • 「本当に間違ってコミットしてしまった」
  • 「コミット後に誤りに気付いたが軽度なので誰かに見られる前に直しちゃいたい」
    などが考えられそうです。
    コミット履歴欄に余計なものが残らないので、ごちゃつかずに済みますね!
起こりうるエラーと解決法

ただし、歴史の改変は往々にして世界線の不整合を生み出してしまいます…
resetをしたのちにgit pushをしようとするとエラーが表示されてしまうのです。
image.png
上図では、要所要所でリモートリポジトリに変更を反映している状態で、ローカルでcommit3をresetし、その先の変更を反映しようとしています。
ですが、リモートリポジトリからすると「2の次に3があって、その次に4」という歴史を経ているので、急にcommit4'(ダッシュ)が来ても「歴史が違うのでプッシュされても困る!(どちらの歴史が正しいかわからない!)」となってしまうのです。

この状態を解決する方法は以下2つがあげられます。
1. git fetchなどでローカルの状態をリモートリポジトリに合わせる
1. git push origin head -f(強制プッシュ)を行うことで、リモートリポジトリの状態をローカルに合わせる

いずれもリモートと手元のソースをそろえるという手間がかかります。強制プッシュを行ってしまえばエラーなくpushが可能ですが、共同で編集しているブランチであれば、メンバーの方に一声かけるのが賢明でしょう。

git revert

revertは逆向きのコミットを生成するので、あくまで時系列としては先に進んでいます。
image.png

resetが「コミットなんて無い!0に戻す! 1 ⇒ 0)」なのに対し、
revertは「コミットが+1されたので、-1のコミットを足して0に戻します~ ( 1 + (-1) = 0 ) 」というイメージです。

過去改変を行うわけではないので、reset後のpush時に起こるようなエラーは起こりえません。
また、修正したことが明示的になるので、「この人は意図的に修正を入れたんだな・コミットを取り消そうとしたんだな」ということが他の人からもわかります。

ただし、あくまで 「逆向きのコミットを生成する」 コマンドなので、コミット履歴が残ってしまう点は注意が必要です。

まとめ

お疲れ様でした!
今回はGitにおける取り消し手段の代名詞であるgit resetgit revertについてまとめました。
開発初心者の方が一番最初につまずくのがgit周りなんじゃないでしょうか…(少なくとも私は😿)
私も日々経験を積んで、エンジニアとして大成できるよう精進いたします。ご精読ありがとうございました!

参考

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?