背景
gitで管理しているプロジェクトのクラスを一部、他のプロジェクトでも使いたい。
丸ごとはいらないし、諸事情からcomposerなりで管理することもできない。
gitのsubmoduleってあんまり使ったことないけど、これでいけるんちゃうかな。
他にいい方法あるやろ!
なんかそんな気もするけど、submoduleの理解も兼ねて・・・
手順
Submoduleとして扱いたいプロジェクト(以下Sとする)をメインプロジェクト(以下Mとする)で使いたい
- MでSをサブモジュールとして呼び込む
- Sを最新にする(特定のバージョンで状態を止めておきたい場合は必要ないが)
- Sから必要無いファイルを外す
具体例
MでSをサブモジュールとして呼び込む
git submodule add -b <branch> <url>
urlはサブモジュールリポジトリのURLです
bオプションで追従するブランチを指定しています。
まあデフォルトブランチを追従する場合bオプションはいらないかと思いますが。
Sを最新にする(特定のバージョンで状態を止めておきたい場合は必要ないが)
submoduleはaddされた時点での最新コミットを見るように設定されるため、
今後submoduleの更新を追従したい場合には必要なコマンド
git submodule update --remote
これでsubmoduleの中身を最新に更新します。
ただ、他のプロジェクトに依存するのはしんどいので、メジャーリリースのタイミングとかに絞った方が良いかと思います。
Sから必要無いファイルを外す
これで最新のSがMに含まれたと思いますが、
ほとんどいらないファイルかと思いますので、submoduleから外しちゃいましょう
対象ファイルを選択する手順としてはコマンドからやるのが一般的ですが、
ここは最終的にはプロジェクトのメンバー間で使う想定とし、gitで設定を管理できる形で紹介します。
で、結論から言うと他のメンバー用にこんなスクリプトとファイルをコミットしました。
[submodule "<S>"]
path = <S>
url = <url>
branch = <branch>
サブモジュールの状態を表すファイル
どこのURLのリポジトリのどのブランチをどこにaddするかを指定するのものです
#!/usr/bin/env bash
git submodule update -i
cp ./sparse-checkout ./.git/modules/<S>/info/
cd <S>
git config core.sparsecheckout true
git read-tree -mu HEAD
開発環境作成の際にメンバーが実行するスクリプトです。名前はなんでもいいです
app/Services/
app/Repositories/
app/Models/
S内の必要なファイルを示したものです
ファイルの中身はこんな感じで必要なファイルをSから見たパスで指定し羅列します
例えば、一番上はS/app/Services
といったディレクトリを丸ごと残しておく、という指示です
あと、コミットハッシュ(バージョン)が保存されているので
S自体のディレクトリ(?)もコミットします
これにより他のメンバーはinit.shだけを実行すれば、自動的にsubmoduleを引っ張ってきて、かつ特定のファイル以外は葬られる、という感じになります
init.shの説明
git submodule update -i
.gitmodulesにしたがってsubmoduleを取得します
cp ./sparse-checkout ./.git/modules/<S>/info/
sparse-checkoutで設定した必要なファイル情報をgitの設定ディレクトリにぶち込みます
cd <S>
取得したモジュールSに移動
git config core.sparsecheckout true
gitのsparse-checkoutという技術を使うための準備
git read-tree -mu HEAD
上でぶち込んだsparse-checkoutに追従してHEADを更新します
免責事項
まだ試験運用中なんでなんか問題起きる可能性もございます。
なんかあれば追記します。。。