😇

git push -f でやらかさないために・・

2022/06/22に公開

先日、プロジェクト先にてGit pushでやらかしてしまったため備忘録として残します
内容としてはgit push -fでリモートブランチがブランチ作成後まで遡ってしまったこと・・

環境

  • 1つのブランチを複数人で使用する開発スタイル
    (基本的には個々でブランチを作成するのが主流かと思います)

  • 共通ファイルのpushを1人の方が行い、それをそれぞれpullする
    その後、個々の作業箇所をpushし最終的に1つのブランチにまとめあげるといったもの

経緯

  • 共通ファイル等をpullしてきた後に、自分の担当箇所をpush
    その際にpushした内容に誤りがあったことに気づく(本当は誤りはなく、早とちりしたことが原因でもあった)

  • 自分がpushした内容を取り消そうと思いローカルでgit reset HEAD~2を実行

  • リモートに差分が出てしまうためこのままだとコンフリクトが起きてしまう

  • そこで滅びの呪文git push -f origin HEADを実行してしまう・・

  • これで自分の誤ったコミットがリモートに削除されたかと思いきや、リモートブランチはブランチ作成直後まで遡ってしまう
    →ローカルは特に何もコミットされていない状態になり、それをリモートに反映させたため
    (幸い数コミットしかまだない状態だったので大事には至らなかったのですが少し間違えば大惨事でした)

何がいけなかったのか

今回行けない点としては大きく2つあると思います。

1つ目は、git resetを使用したこと

git resetコマンドはコミットをなかったことにできます。
誤ったコミットをなかったことにできるなんてちょーラッキーと思うかもしれませんが大間違いです!
個人開発をする分にはなかったことにしてコミットをスッキリできます。
しかし、チーム開発をやる上でしかも同じブランチで作業を行なっている場合では特に注意しないいけません。

resetを使用後にリモートにpushすると差分が生まれてpushできないため、強制的にリモートを上書き(コミットをなかったことに)しなければいけません。
つまり、その際に他のメンバーがブランチにpull・pushなどを行なっていた場合にも差分が発生しコンフリクトが起きてしまうため要注意です。

そのため、今回は誤ったコミットをしたことを素直に認めgit revertコマンドを実行することが正しかったと思います。
このコマンドを使用することで、コミットを打ち消すコミットを作成します
コミットは増えてしまいますが、上記の問題を考えると無駄な時間が発生しないし何より安全です
(調べて思ったのですが基本resetは使用せずrevertを使用するプロジェクトの方が多いのではないかと感じた)

git refloggit resetを取り消すこともできるみたい!

2つ目はあまり理解せずgit push -fを使用したこと

git push -fはどのような状況下でも強制的にpushを行なってしまいます
 調べると危険、絶対使うなと書かれている記事が多く、あまり調べないまま使用したことが大きな過ちでした。。

これを使用しないためにも代替案として、git push ——force-with-leaseオプションでローカルがリモートより古かった場合はpushできないようにしたり、そもそもpushできないようにGitHub等で設定もできるみたい(厳しいとこだと開発メンバーにはpushはさせないとこも多そう)

まとめ

今回は大惨事にならなくて幸いだったけど一歩間違えば大損害を与えていたことになるので、
改めてGit操作は慎重にやるべきだと学びました。
git push -fは使わず違う方法を模索しましょう!
なんなら間違えたコミットをpushした場合は素直に誤りを認め、先輩・PL・PMに相談して、
話し合いながら解決するのが一番だと思います!

Discussion