nikkie-ftnextの日記

イベントレポートや読書メモを発信

git revert 出会い直し。コミットは打ち消せる単位

はじめに

「お前のやりたいことが理屈に逆らってるってことじゃない。 ただ、ものすごく馬鹿げてるってだけだ。」1
nikkieです。

公開日より昔の学びになるのですが、Today I Learnedです。
git revert ようやく少しつかめた感じです。

目次

git revert

こんなときに使えます:

くっそー、5つ前のコミットを元に戻さないといけないって!
https://ohshitgit.com/ja#undo-a-commit

git revert HEAD~5

git revert打ち消しのコミットを作ります
上記の例だと、5つの前のコミットを打ち消したコミットがされます(真逆のコミット)

出会いはSourceTreeで

私は最初GitをSourceTreeからGUI操作で使っていました。
SourceTreeで「一度作ったコミットを元に戻したい!」2となったときに、revertを見つけます3
「これで戻るのかな」と思ってGUIからrevertするんですよね。

そしてできあがる、打ち消しのコミット😭
revertはコミットを作ってワーキングツリーを元の状態に戻すわけです(コミットを取り消すわけではないのです)

「え?こんなの作りたくなかったんだけど」と慌てて再度revert

打ち消しの打ち消しコミット誕生!
2コミット進んだぞ(何も仕事してないのに...)

これは手痛い体験となり、「全然欲しくない機能だった」と、SourceTreeを卒業してもgit revertは触らないようにしていました。

再会:複数のコミットをrevert

直近手を動かしたのが、複数のコミットをrevert

git revert HEAD HEAD~

指定したコミットごとに、打ち消しのコミットが作られます。

今の私はgit rebaseが使えるので、2つを1つにまとめました(squash)

1つにまとめたことで腑に落ちたのが、(たしかSourceTreeを使ったGit講座動画で聞いた)コミットの分け方の話。
複数のファイルを作ったときに1つ1つ分けてコミットしていたんですよ4
その理由は「コミット単位で戻せるように

今回のgit revertで「コミット単位で戻せる」が腑に落ちました。
コミット単位で打ち消すコミットが作れる(revert)ので、あるコミットだけを打ち消して戻すことができるわけですね。
Gitってコミットを積み上げていくイメージがあるのですが、特定のコミットを打ち消すコミットを積むこともできるんだな〜と体感しました。

なお今の私はgit resetも少しは理解しているので、誤ってrevertしてもresetでことなきを得られます。
先のSourceTreeの例のように誤ってrevertしても、git reset HEAD~ --hard

ドキュメントより

Revert some existing commits

exampleを見ました

git revert HEAD~3
すでに取り上げた「3つ前のコミットの内容を打ち消したい」ですね

git revert -n master~5..master~2
こんな書き方が!
-n--no-commit、打ち消しコミットまで作らずワーキングツリーのみ変更
上で示したような連続する複数のコミットを打ち消すときに便利そうです(私がやったようなrebase不要!)

終わりに

GitをSourceTreeで使い出した頃に元に戻せると信じてrevertしたばっかりにプチトラウマとなっていましたが、Gitの理解が進んだことでrevertのありがたみが分かった気がします(プチトラウマからの和解)。

  • コミット単位で打ち消すコミットが作れる(コミット=戻せる単位、という視点!)
  • -nでrevertコミットまで作らないことを知る

  1. 当時はgit commit -mなぞ知りません
  2. 求めていたのはgit reset(コミットの取り消し)で、見つかりやすかったのがgit revert(打ち消すコミット追加)というわけです
  3. 例は2ファイルだった(HTMLとCSS?)のですが、30ファイルあったら30コミット作るかというとそれは別の話だと思います(今の私としては、戻すかもしれない単位で分けたい)