2021/04/10(Sat)
○[バージョン管理] そろそろgit subtree捨てたい
せっかくオレオレN6は本家と違ってgitで管理してるので、3rd Partyでgitで管理されてるものは可能な限りgit subtree使って更新を楽にしようと計画してるのだが、現在のとこopensslとtzdataしか終わってなくてなかなか道は険しい。
そもそもN独自で当たってるローカルな修正の監査が大変なのである、opensslとか差分全部 リストアップして全部妥当かどうか検証するのさすがに辛かったし世界でユーザー1名様のみのOSにかける手間じゃねぇよな…
そしてtzdataもデータファイルとzic/zdumpコマンドのマージは終わったけど、libc/time以下にあるCソースの更新がめんどくさいくて手が止まっている。 なんせtzdataが ソース互換失ってる上にprivate.hとNのクロスビルド用のtoolchainが用意してるnbtool_config.hであっちこっち定義が衝突して宇宙ヤバいのだ。 あとstrftime/strptimeのERA対応実装をファイルサーバの未整理の中から発掘してそれもマージしねぇとならんしISO 14652 LC_TIME extensionsとかの作業以下略
それでも本家への追従は楽になって、先日リリースされたtzdataの2021aへの追従は
$ git subtree pull --prefix=external/public-domain/tz/dist --squash tz 2021a
と叩くだけでCONFLICT出ない限りサクッと作業が終わる、書いたdeveloper本人しか中身理解してないようなhoge2n**bsd.shなんてスクリプト群はゴミ箱ポイーで。
ただgit submoduleでなくgit subtreeを使ったのはちょっと早計だったなぁと後悔している、以前 git subtreeの落とし穴という記事を書いたけど、subtreeが存在する状態でgit rebaseを実行しようとすると意味不明な挙動を示すのでな…
結局過去記事にリンク張ってあるAltassianのブログにもあるように、基本subtreeの含まれるリポジトリのrebaseをするのなら
- 事前にコミットログのsubtreeのadd及びpullに関する操作
をすべて記録しておくcommit 5e3869954c0ec6815c022b787f5d2ace62da58a7 Author: Takehiko NOZAKI <tnozaki@outlook.com> Date: Wed Jan 13 09:26:20 2021 +0900 Squashed 'external/public-domain/tz/dist/' content from commit 256742ba47 git-subtree-dir: external/public-domain/tz/dist git-subtree-split: 256742ba47463803ab539a26097d4bd46551a99a
- rebase --interactiveを実行する
- 過去のadd/pullはすべてdropする
- 改めて↑で行った操作をいちからやり直す
という苦行が必要になるのだよな。
まぁrebaseは禁止でCVSやSubversionみたいにコミット積み重ねてきゃいいという運用で回避でもいいんだが、gitの開発者ライナス中指ファックおじさん的にはrebaseこそがかつてのLinux kernelの管理手法であるtarballとpatchの上位互換であるわけだから、おいそれと禁止するわけにもいかない。 実際private branch切って長期間作業してると、masterの変更取り込みをrebaseでなくmergeでやると履歴グチャグチャになって何やってたかよくわからんようになるからな。
それにこの問題はrebaseだけでなくfilter-branchでも発生するのよな、よって
- 間違って機密入りのファイルをコミットしちゃった
- .gitignoreに記載を忘れてバイナリファイルまでコミットしちゃって容量ヤバい
なんて時に、歴史を改編して葬り去りたいなんて迅速に行わなければならない作業がなかなか終わらないという地獄絵図になる。
なんでgit submoduleを選ばなかったかというと、submodule側に変更を加えないのであればorigin変えずに済むんだけど、加えた瞬間にそれはforkと同義になるのでリポジトリ用意してそっちにorigin変更せにゃならんから、とにかく管理がめんどくさいのだ。 まだ使いはじめた頃はBitBucketもリポジトリ数上限とかあってsubmodule毎にリポジトリ作ってたらオーバーしかねないのもネックだった記憶、それにcommitがsubmodule側と親リポジトリ側の2回コミットが必要になるのもダルい。
その点git subtreeだとただ一つのリポジトリ(ただしoriginは複数)と一回のコミットで履歴も--squashで圧縮できるから飛びついたんだけど、上記のような仕様なのかバグなのかよくわからん挙動でいちいち作業止まるのでなぁ。
ところでしばらく前からbaseでもcontribでもないんだけど、 git subrepoというつくれぽみたいな第三の選択肢が登場して、submoduleとsubtreeのいいとこどりなんて謳い文句なんだが、どんなもんなんだろうね。 中開いたらBashで書かれてたのでシバン含めて3行以上のシェルスクリプトは信用しないしないオレルールに抵触したので試してないけど。 というかIssueのopen数みるとまだ安定して無さげなので、見に回ってるのだが。
やはり分散型バージョン管理は SVKがオレの理想形でかなり期待してたんだけどな、OpenSolarisがほんの初期に使っててすぐMercurialに乗り換えたくらいか。 まだCPANには残ってるが開発は長期間止まってるね。
ファイルバックアップも Subversion+DeltaVで実現できると信じてた昔々のお話ですな、まだ1.0になる前の死ぬほど重いBerkeley DBバックエンド時代のSubversionとか2003年くらいから使ってたの今考えるとアホだったなーと。