はじめに
今回は会社に入って初めての失敗を記事にしようと思います。
基本的には普通に調べてやっていれば踏まないと思うのですが、見事に踏み抜いてしまったので、今後同じようなミスをする人がいないような注意喚起となれば幸いです。
背景
当時会社には標準環境と呼ばれる、「Webアプリケーションを作るならとりあえずこれ使っとけ」というような技術スタックをまとめたリポジトリがありました。
私は当時新卒で、同じ部署に入社したエンジニア以外の職種も含めた新人だけで何かサービスを考えてみるというミッションの最中でした。
最初からWebサービスにすることが必須ではなかったのですが、結果としてWebサービスにすることとなりました。
ただ入ってすぐの自分達には、共通的に知っている技術スタックがあるわけでもなく、アーキテクチャ選定できるほどの経験もなかったので
ひとまずは標準環境のリポジトリを参考に開発を始めよう、ということになりました。
何をしたか
さて、早速リポジトリを作成するぞということで
私は以下のようなコードを打ったと思います
当時を思い出す限り、おそらくこういうことをしたはずだというものになっております。もしかしたら細かいところが違っているかもしれません。
# テンプレートのリポジトリをclone
git clone https://github.com/org/template.git
# 自分達のプロジェクト用に設定変更
# push
git push --mirror
何がいけないか?
考えてみれば当たり前なのですが、--mirrorオプションをつけるだけではダメで、ちゃんと自分のプロジェクト用に作成したリポジトリを向き先として指定する必要があります。
以下がpushするときの正しいコマンドです
git push --mirror origin https://github.com/org/new_project.git
--mirror オプションの仕様をあまり理解しないまま使ってしまった結果このような初歩的なミスをしてしまったのですが
間違えてしまったことにはログを見てすぐ気づき、なんとかしなければと思いました。
どう対処したか
最初とても焦ってしまった私は、以下のような操作をして状況を復旧しようとしました。
# 直前のcommitを取り消し
git reset --hard HEAD~
# remoteに再度push
git push --force-with-lease
これで自分の変更してしまった差分はなかったことにできるし、一件落着!
とはなりませんね。。。
対処の不味さ
まずかったのは主に2点です。
大前提、失敗の報告はしてしまった時点でするべきである
これは技術的な問題というより、社会人としての報告の仕方が問題でした。
焦ってしまったとはいえ、どう考えてもmainに再度force-pushするなんていうのはリスクが高すぎます。
失敗したらそれをなかったことにしようとするのではなく
現状を落ち着いて整理し、上長に報告することを最優先としましょう。
この点については先ほどのforce pushをしてからすぐに思い直し、エンジニア全体のチャンネルで報告をしました。
そもそも完全復旧はできていなかった
表題の問題でもあるのですが、こちらはgitに関する技術的な見落としです。
最初にやってしまったことを振り返ると
一番初めにテンプレートリポジトリをcloneする段階で
git clone https://github.com/org/template.git
としていたのですが
実はこのとき何のオプションもつけない状態でclone すると
- クローンする元になったブランチの各ブランチに対してリモート追跡ブランチを作成する
- クローン元のデフォルトブランチに対してローカルの作業ブランチを作成する
ということになります。
一見問題ないように思うのですが、リモート追跡ブランチはあくまでローカル上で読み取り専用として機能するブランチであって、pushする際にはリモートブランチに影響を与えるものではないです。
つまり、私が今回行った作業によって、元々のテンプレート環境では
mainブランチ以外の作業ブランチが全て消えてしまった😱
ということになります。
もちろん、他のユーザーのローカルブランチが消えていなければ復旧が全くできないということはないのですが
元々全てを復旧することもできていなかったわけですね。
リモート上の全てのブランチをローカルのブランチとしてもコピーするには、以下のようにする必要がありました。
git clone --mirror https://github.com/org/template.git
このように
cloneの際にもmirrorオプションが必要
ということです
まとめ
実際の失敗の流れを追ってしまったことでちょっと話がばらついてしまいましたが
- リポジトリをコピーする時には
push --mirrorで新しい向き先のURLを指定しましょう - コピー元の全てのブランチも含めてコピーしたい場合にはcloneする際にも
--mirrorオプションをつけましょう