最近仕事でgitのサブモジュール機能について触れる機会あって「なにそれ」となったので備忘録。
ちな初投稿なのとまだまだ未熟なのでツッコミ歓迎対戦オナシャス。
サブモジュールとは
ひとつのリポジトリに、別のリポジトリをネストする機能。
独立したプロジェクトを一つの親リポジトリで管理可能。
らしい。
なんか便利そう。
コマンド
git submodule add <repository> [命名したい名前]
repositoryはプロジェクトのURLを指定。ネーミングも可能。デフォルトはプロジェクト名
git submodule add https://github.com/DynamicDaikon/vue-pinia.git my-sub
コマンド実行したところにmy-subという名前でcloneされる。
サブモジュール化した後は初期化とアップデートを実施
(ガチチュートリアルなリポジトリのURL貼るの手震える)
git submodule init
git submodule update
モジュールの初期化&最新コミットをチェックアウト
イマイチよくわからんけどおまじないと思ってまずは受け入れ
.gitmoduleみたいなファイル出来てたし多分ここに色々書き込まれるんだろう
git submodule update —remote
リポジトリの変更を取り込み
親側で更新入れてたらスススっと更新取り込んできた
こういう使い方かぁ
ところで
サブモジュールで行った変更はどうなるのか
cloneってことは普通にブランチ操作とかcommitとか可能なんだよね? どうなるの?
と思ったのでちょっと試そう
- ギモン
- リポジトリ元に反映される?
- 独立した修正になる?
やってみた
-
submoduleを追加した子リポジトリで修正
- git commitまでは変わらず
- git push時に以下のワーニング発生
Dynamic_Daikon:~/git/projects/vueText/components-basics/vue-pinia % git push HEAD fatal: You are not currently on a branch. To push the history leading to the current (detached HEAD) state now, use git push origin HEAD:<name-of-remote-branch>
- どうやら他のブランチのコミットを直接チェックアウトしている時と同じ挙動になる様子
- なのでログの通りにoriginのHEADに直接pushすれば解消
- 無事、大元のサブモジュールにしたプロジェクトにコミットが追加された
正確には本体側の参照するコミットIDがsubmoduleでコミットされたものに切り替わってるっぽい。具体的な内容は追えてないけどこれ起因の不具合とか起きそうで怖い……。(臆病なgit弱者)
サブモジュールを含むプロジェクトを更にサブモジュール化してもおそらく同様の挙動なんだろう。知らんけど。
色々見てると
子プロジェクトでcommitすればpush前でも親プロジェクトから参照が可能っぽい。
なのでやろうと思えば「子プロジェクトでまだpushするつもりなかったのにー」というものも親プロジェクト側でpushできちゃうみたい。
いや怖くね?
しかも子側でブランチ切ると場合によってはデグレのリスクもついてくると。
pre-commit
のコマンドで対応可能だけど、そんなデリケートな操作したくないなぁ、という気持ち。
ということで結果
リポジトリ元に反映される?
→YES。される。
【メリット】
- プロジェクトを独立して管理、あちこちの別プロジェクトでサブモジュール化することで共通部品的な使い方が可能。
- 親子で並行開発可能で、最新状態の取り込みもコマンド一発でOK
- 双方向で修正は可能だが、もしミスってgit pushを無邪気にやってもoriginのHEADを指定しないと送信されないので一応安心?(設定によるかもだけど)
【デメリット】
- プロジェクト同士の依存関係の管理が煩雑になる
- 大規模なプロジェクトだとこの辺の整理だけで工数無限に溶けそう
- gitに関する理解度がある程度必要
- 事故った時キツそう
- コミットやブランチ戦略のルールをしっかり決めないとデグレのリスクあり
- 基本は子の方で修正しない方が吉っぽい
以上