🉐

他のリポジトリからsubmoduleで一部ファイル、一部ディレクトリのみ取ってくる方法!

2023/10/03に公開

はじめに

お久しぶりです。
フロントエンドエンジニアをやっているRimlと申します。

皆さんsubmoduleを使っていますでしょうか?

他リポジトリからdllファイルやOpenAPI GeneratorなどのOAS定義ファイルなどを他のディレクトリから引っ張ってきたりしたい時に有用な手段の一つだと思います。

ただsubmoduleで持ってきたいのはリポジトリの一部だけで全部は持ってきたくない!となることはありませんか?
私はあったので今回その備忘録を書いていこうと思います。

この記事には以下の情報が含まれています。

  1. submoduleの導入方法
  2. 一部ファイルのみ取り込みにする方法

submoduleの導入方法

まず持ってきたい情報を持っているリポジトリを現プロジェクトに導入する

git submodule add -b ブランチ リポジトリ 好きなモジュール名

上記を実行することでsubmoduleとしてcloneしてくることが出来ます。

ではちゃんと落とせてきているか確認しましょう

ls モジュール名

# 以下コンソール結果
cloneしてきたリポジトリの中身

こちらが表示されていれば成功です。

同様に .gitmodules というファイルが生成されます。
そちらを確認してみましょう。

cat .gitmodules

# 以下コンソール結果
[submodule "モジュール名"]
	path = モジュールパス
	url = clone URL
	branch = 指定したブランチ

このように設定されています。

もし .gitmodules を書き換えた際は以下のコマンドでリポジトリ内のsubmoduleの情報を更新することができます。

サブモジュールを追加削除したりURLを変更し .git/config に反映させる

git submodule sync

サブモジュールのファイルを取得

git submodule update --init

これで導入完了です。

一部ファイルのみ取り込みにする方法

まずこれを行うには sparse checkout というgitの機能を利用します。
sparse checkoutとは、ローカルに checkout するディレクトリを限定することができる機能です。

まずこちらを利用するには git config に設定してあげないといけません。

git -C モジュール名 config core.sparsecheckout true

設定されているか git config を確認してみましょう

git -C モジュール名 config -l

#以下コンソール結果
credential.helper=osxkeychain
filter.lfs.required=true
filter.lfs.clean=git-lfs clean %f
filter.lfs.smudge=git-lfs smudge %f
user.name=*****
user.email=*****
~

core.sparsecheckout=true ## これが表示されていればOK

次に sparse checkout の設定が必要になります。
お好きなエディタやIDEで書き換えましょう。
例はわかりやすくVSCodeで編集します。

code .git/modules/モジュール名/info/sparse-checkout 

ここに必要なディレクトリまたはファイルを記述していきます。
例は utilsディレクトリOASファイル swagger-spec.yamlを落としてくる場合です。

/utils/
/swagger-spec.yaml

これで保存しましょう。

モジュールのツリー情報を読み直しましょう

git -C モジュール名 read-tree -mu HEAD

絞られているか確認しましょう

ls モジュール名

# 以下コンソール結果
utils
swagger-spec.yaml

サブモジュールのファイルを取得をしても上記のファイルのみになっています。

git submodule update --init

これで終わりです!
お疲れ様でした。

おわりに

OAS定義ファイルのみを取り込みたいからCI/CDで何処かに上げて引っ張ってきたり~など考えていたのですが、コードファーストで生成したOAS定義を持ってくるくらいでそんな大変な事をしたくないなと思い今回のようなアプローチを取ってみました。

フロントエンドのリポジトリでOASから型生成など行ったりします。

GitLabRunnerでは以下のように書くと同様のことができます!

variables:
    GIT_SUBMODULE_STRATEGY: 'recursive'
script:
    - git -C モジュール名 config core.sparsecheckout true
    - echo "/swagger-spec.yaml" > .git/modules/モジュール名/info/sparse-checkout
    - git -C モジュール名 read-tree -mu HEAD

以上を設定するとCIで回す際にimageがslimだったりするとgitが無いと怒られる場合があるのでbefore_scriptでgitを入れてあげるなどの対応をしましょう。

よりよい方法があればぜひコメントしていただけると嬉しいです!

最後まで読んでいただきありがとうございました。

Discussion