Deep in Deep

プログラミング勉強中。遠回りですが、ゆっくり深く学んでいきたい。

GitHubインシデントレポート

はじめに

個人開発においてもチーム開発においても大変お世話になっているGit、GitHub

大変便利なツールですが、まだ慣れない点も多く、しばしば使い方を誤ってしまうことがあります。

人間はミスをします。よく労働災害や医療事故などのお話の中に登場する「ハインリッヒの法則」というものがあります。

アメリカの損害保険会社の安全技師であったハインリッヒ氏が発表した法則で、

「同じ人間が起こした330件の災害のうち、1件は重い災害(死亡や手足の切断等の大事故のみではない。)があったとすると、29回の軽傷(応急手当だけですむかすり傷)、傷害のない事故(傷害や物損の可能性があるもの)を300回起こしている。」

というものです。(参考: [厚生労働省]職場のあんぜんサイト

今のところ、大きな事故は起こしていないものの、軽微な事故、事故寸前で気づいたというような失敗も経験しています。大きな事故が起こってしまう前にそれぞれのヒヤリハットについて分析し、どのようにしたらそういったミスが起きないか、という対策を考えることは大事かもしれません。

自戒の念も込めて、自分の恥ずかしいミスを曝そうと思います。「あ~あるある。」というようなミスもあるかもしれませんし、「え!?そんなことしたん?」っていうミスもあるかもしれませんが、今後自分が同じ過ちを犯さないように、簡単にですが、ミスが起こった背景やそれについての対策などを書き残しておこうかと思います。

失敗その1 コンフリクト解消のMerge commitのミス

起こったことを端的に

developブランチから切ったブランチAで作業中。developブランチにブランチBをMergeしたことで、developとブランチAの間でコンフリクトが発生。

それを解除した(できたと思っていた)ら、developブランチにおけるブランチBで実装したコードが全部消えてしまった。

なぜそんなことが起こったか

コンフリクトが起こった時の解消方法については、以前も記事にしました。 yusei-qqq.hatenablog.com

コンフリクトが起こったときはmainやdevelop等のブランチを最新のものにして、開発ブランチにMergeしてあげて、コンフリクトを解消してあげたらよい、という認識でした。

こちらについては概ね間違いではないと思うのですが、自分はコンフリクトが起こっているファイルのみcommitしたのです。

developブランチをブランチAにMergeした際、ブランチBでの実装分の変更がstaging状態で追加されます。これと、今回発生したコンフリクトを解除したものをmerge commitとして commitするべきだったのですが、ブランチAの実装分にブランチBの実装も入ってしまったら、何か良くない気がして、あろうことか、staging状態になっていたブランチBの変更分を git reset --hard + git checkoutして亡き者にしてしまい、コンフリクトが起こっていたファイルのみcommitしてしまったという状況です。

こちらの問題が発生したブランチがmain等の本番ブランチでなかった+デプロイ前であったため、Revert等行うことにより、ブランチBの実装分は元に戻ったのですが、本当に肝を冷やしました。

原因と解決策

こちらが起こった原因に関しては、自分のGitに関する理解不足です。Merge Commitがどのようなものかきちんとわかっていなかったため起こりました。

git mergeを実行して、コンフリクトが発生した場合は素直にコンフリクトの解消を行い、stagingに上がっている変更たちもまとめてcommitしたらよかったです。

また、commit名についても、git commit -m 'コンフリクト解消'のようにしてもいいかと思いますが、git commitだけ実行すると、Merge branch 'master' into developのようなcommitメッセージになるので、「ああ、ここでMergeしたんだな」というのも分かりやすいかと思いました。