とある日
いつも通りの開発作業を行っていたある日。
新規の機能追加(A)を依頼されていたので、色々とファイルを追加したり既存ファイルを修正したりしていつも通り作業を進めていました。イメージとしては下記のように変更を加えているとしましょう。
# 変更点
script-a.js ←既存ファイル
script-b.js ←既存ファイル
script-c.js ←新規ファイル
script-d.js ←新規ファイル
ただ、途中で優先度高めの機能修正(B)(というか不具合修正)の依頼が舞い込んできました。
上述の機能追加(A)は優先度が高くないこともあり、いったん置いといて先に後から来た機能修正(B)を実施していくことにしました。
さて、ローカルには機能追加(A)の変更が入ったソースコードがあり、9割方完成しているのですが微妙に整理しきれていないしチェックも出来ていない状態です。
「この状態ならまだcommitするのはまだだな…」と考え、一度stashへ退避させることへしました。
git stash -u
# 保存されたファイル達
script-a.js ←既存ファイル
script-b.js ←既存ファイル
script-c.js ←新規ファイル
script-d.js ←新規ファイル
安心と信頼のstashへの保存です。当然、新規ファイル(untracked files)も存在しているので-u
オプションも付けています。
これでローカルの変更が無くなったのを確認し、mainブランチへと戻って機能修正(B)用の新しいfeatureブランチを作成して修正作業に入ったのでありました。
機能修正(B)についてはさほど難しい内容ではなく、修正量も多いわけではありませんでした。
しかし、何と先ほどの機能追加(A)で手を加えていたscript-a.js
において、同じ部分をこちらでも別の形で修正する必要があるということが判明しました。
つまりconflictが発生することは確定なのですが、まあ致し方なし。
「機能追加(A)の作業に戻った時に解消させればいいや」と考えてそのままcommitし、無事マージされていきました。
そして起こった悲劇
さてさて、機能追加(A)の作業に戻っていきましょう。
まずは元のfeatureブランチに戻ってきて、stashから戻していきましょう。とりあえずいつも通りpopでいいか~
git stash pop
# 復元されたファイル達
script-a.js ←既存ファイル、コンフリクトしている
script-b.js ←既存ファイル
・・・???????
新規で作ったファイル達(script-c.js
・script-d.js
)が…戻ってこない…!?
5分くらいその場で固まった後、何か手順やらコマンドをミスったのかと考えましたが該当せず。
とりあえずコンフリクトを解決してみたり戻してみたり何やかんやしたものの何も解決しません。
どこに行ったんだあいつらは…闇に消えたのか…???
救出方法
とりあえず原因が何かを考えてみます。
いつもは同じ手順で問題なかったので、コンフリクトが発生したのが何か悪さをしていそうです。
となるとコンフリクトをしないように修正を加えてからgit stash pop
を行うのが良さそうですが、今回は結構それが面倒なパターンだったので断念しました。あとその場しのぎにしかならないしね。
色々とネットを調べてみましたが、状況が限定的なのかなかなか同じ現象で困っている方が見当たらず。
しかし、何とかこの現象について記述しているサイトを発見できました。
見てみると一番上にこんな文言が。
Git had a bug from version 2.33 onwards, fixed in 2.35. (Thanks to Richard Laager’s comment for the exact version numbers.)
…Gitの特定バージョンのバグかよ!
すぐにgit --version
で確認すると、見事2.33.1とこの対象内でした。ちょっと古いバージョンで放置しているのがバレた
さて、バージョンの問題で解消済みなのであればバージョンアップしてしまいましょう。
何か気が抜けて疲れたので、何も確認せずにえいやっと最新版(2.45.2)にバージョンアップしちゃいます。
そして完了したのでstashから復元してみましょう。
git stash pop
# 復元されたファイル達
script-a.js ←既存ファイル、コンフリクトしている
script-b.js ←既存ファイル
script-c.js ←新規ファイル
script-d.js ←新規ファイル
…帰ってきた!
見事、闇の中に消えたと思われた新規ファイル達が復元されました。
ああ疲れた…
今回はバージョンアップで解決しましたが、コンフリクトしないように修正してからstashを戻す方法でもOKです。
ただ、発生する度に毎回行う必要があるので、対策としてはバージョンアップ可能ならそれをおすすめします。
最後に
ということで、結果としてはGitの特定バージョンの不具合に引っかかった、というお話でした。
先ほど紹介したサイトのコメント欄を見ると、ここでバグが混入してここで修正された、と詳しく記載されていました。
ただ限定的な状況だからこの現象に遭遇した方も少なく、ネット上に情報が少なかったんでしょう。
「やらかし」かというと微妙なラインですが、危うくやらかして自分の結構な分の作業が0になる所だったので教訓にしていきたいですね。