git pushでやらかして頭が真っ白になった話
悲劇は出社1時間後に起こりました。
$ git commit -m "華麗なるコミット" $ git push
pushしてから自分のコミットになかなか恥ずかしいミスを見つけたので
プルリクの更新を見られる前にpushを取り消して証拠隠滅しようとしました
$ git log # ↓pushしたけど取り消したいコミット commit hogehogehogehogehogehogehogehogehogehoge Author: helen <heleeen@hoge.com> 華麗なるコミット # ↓戻りたいコミット commit fugafugafugafugafugafugafugafugafugafugafuga Author: Mr.X <xxx@hoge.com> コメントの余地もないコミット
git logで戻りたいコミットのハッシュ値を確認し
git reset --hard <戻りたいコミットのハッシュ値> で戻します
$ git reset --hard fugafugafugafugafugafugafugafugafugafugafuga $ git push -f
ここでようやく悲劇に気がつきます。
あれ?未承認のプルリクから自分のプルリクが消滅したぞ?
しかも自分のブランチがマージ済みになっている!?
まさか!
と思い、完了したプルリク一覧を確認すると、
helenがリモートからマージしました。
( ̄△ ̄;)エッ・・?
すぐに周りの人にヘルプ出して事情を説明しました
実は先に差分を取り込むためにdevelopブランチからpull していたため(これは間違いではない)
最初のpushで私のブランチがdevelopブランチにマージされていたのです
問題は、そこで宛先指定なしpushが実はdevelop宛てになっており、
しかも承認なしマージが可能な設定になっていたので
一撃でdevelopにマージされてしまったとのこと。
プルリク消滅の原因は、「developにマージされた」=「プルリクは完了済み」という判定らしく
自分のプルリクは完了扱いに移動していただけでした。
どうりでだれも承認してないのに完了になってるわけだ...
このときの
$ git pull $ git add $ git commit $ git push -f
の流れはコンフリクト対応時と同じです。
幸い、pushしていたのが自分の変更ファイルのみだったのと
他に影響する実装がなかったので他の人への被害はありませんでした。
ですが、なんとかして自分が打ち消してしまった差分を取り戻し
再度プルリクを作成しないと!と思ったので
git reflog で消してしまった差分を取り戻すことにしました。
$ git reflog hogege HEAD@{0}: head^^: updating HEAD fugaga HEAD@{1}: commit : fugaコミット piyoyo HEAD@{2}: commit : 華麗なるコミット # ←ここまでを取り戻したい $ git reset --hard HEAD@{2}
git logで確認すると自分のコミットを無事取り戻せていることが判明
未pushになるため、ここでpushすれば元のプルリクと同じ差分で作成できます
私「よっしゃ!セーフ!」
周り「セーフじゃねえよww」
私「以後気をつけます(´・ω・`)」
$ git push origin <branch name>
無事、プルリクを作り直すことができました!
gitって怖いけどなんて便利なんだ...
問題だったのは、git pull origin develop後に宛先を指定せずpushしたことでした
そのため、自分のリモートブランチではなくdevelopにpushされ、
承認なしマージが可能になっていたためそのままマージされてしまい、
プルリクは誰の承認も得ることなく完了扱いになっていました
今後の対策としては
- pushするときは宛先を必ず指定する癖をつける
- 未承認のプルリクはマージできない設定にする
ことになりました
やらかして一人で騒いでたけど
大丈夫大丈夫!誰もが通る道だから!って
周りのフォローが暖かくて本当に助けられました...
そしてもうgit pushだけでpushしないと心に誓いました
参考
【git】git pushを取り消す - tweeeetyのぶろぐ的めも
Git/git reflog (git resetを取り消す) - yanor.net/wiki
githubの特定ブランチへのgit push --forceをprotectしてエンジニアの精神崩壊を防ぐ( ꒪﹃ ꒪)ブクブク - Qiita