vdeep

*

vdeepはプログラミング、IT、Web技術、ライフハックの事などなどを管理人okutaniがつぶやくブログです

Gitのサブモジュール機能を使ってプロジェクトを管理してみよう

   

LINEで送る
Pocket

git-submodule
こんにちは、okutani(@okutani_t)です。Gitのサブモジュール(submodule)についてイマイチよく分かっていなかったので、備忘録も兼ねて記事にしてみました。

Gitのサブモジュール機能を使うと、プロジェクトで管理しているGitリポジトリとは別に、独立したリポジトリをプロジェクトに含ませることができます。

サブモジュールを含んだプロジェクトでは、プッシュ・プルをおこなってもサブモジュール側のリポジトリには影響がない、といった特徴があります。

他の特徴としては、サブモジュールはあくまで特定コミットを示すポイントを追加したディレクトリに埋め込むものです。

本記事ではGitのバージョンは1.8.5以上を対象としています。それ以下のバージョンでは使えないコマンドなどあるので注意してください。

では、さっそくGitのサブモジュールの使い方を見ていきましょう。

参考Git のサブモジュールってどんなもの? – Qiita

参考git submodule は癖がすごいとの噂だったが素直につきあっていけそうという話 | deadwood

スポンサーリンク

プロジェクトにサブモジュールを追加する

まずは、Gitで管理しているプロジェクトにサブモジュールを追加してみます。適当にsubmodule_testプロジェクトを作成。

$ mkdir submodule_test && cd submodule_test
$ git init
$ echo test > test.txt
$ git add .
$ git commit -m "first commit"

次のコマンドで、現在のプロジェクトにサブモジュールを追加します。今回はあらかじめ「hello」というリポジトリを用意してあります。詳細は後述します。

サブモジュールを追加するには「git submodule add」コマンドを使います。

$ git submodule add https://github.com/okutani-t/hello.git

もし、ディレクトリを指定したい場合は以下のとおりです。以下の例では、vendorディレクトリ以下にhelloという名前で配置しています。

$ git submodule add https://github.com/okutani-t/hello.git vendor/hello

git submodule addは内部で「git submodule init」が実行され、初期化処理がおこなわれています。

このサンプルのサブモジュール(hello)は、あらかじめ、先ほどと同じ手順で作成しておいたGitHubで管理している別プロジェクトです。hello.txtファイルのみを持っており、helloとだけ記述されています。

$ ls hello
hello.txt
$ cat hello/hello.txt
hello

では、「git status」でリポジトリの状態を確認してみます。

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD ..." to unstage)

        new file:   .gitmodules
        new file:   hello

「.gitmodules」と「hello」が追加されていることが確認できました。

追加された.gitmodulesファイルの中身を見てみます。

$ cat .gitmodules
[submodule "hello"]
        path = hello
        url = https://github.com/okutani-t/hello.git

helloという名前で設定されていることが確認できます。ローカルのパスと、リモートのURLがそれぞれ記述されていますね。

ちなみに、.git/configファイルの中身にも、次のように追記されていることが確認できます。

$ cat .git/config
...省略...
[submodule "hello"]
        url = https://github.com/okutani-t/hello.git

サブモジュールは追加をおこなったあと、プロジェクト側でコミットしておく必要があります。次のコマンドでコミットを実行。

$ git commit -m "add submodule: hello"

これでプロジェクトにサブモジュールを含ませることができました。

以下のコマンドでサブモジュールの状態を確認できます。

$ git submodule status
または
$ git submodule

サブモジュールの状態が表示されているのが確認できればOKです。

リポジトリをGitHubにプッシュしてみる

GitHubにプッシュしてみます。

$ git remote add origin https://github.com/okutani-t/submodule_test.git
$ git push origin master

このように、helloサブモジュールが追加されていることが確認できました。

git-submodule2

サブモジュール名の隣に書いてある「5224fb8」は、サブモジュールを追加した時点のhelloのコミットを指しています。

サブモジュールをアップデートしてみる

次に、「サブモジュールが更新された際、現在のプロジェクトへサブモジュールの最新版を反映する」といったことをしてみます。

helloプロジェクト(サブモジュール)の中身を適当にごにょごにょして、次のコマンドでアップデートしてみます(GitHub上でhello.txtの中身をhello2にしてから下記を実行しました)。

$ git submodule foreach git pull

上記のコマンドでは、「git submodule foreach」コマンドを使って、それぞれのサブモジュールにgit pullをおこなわせています。なので、現在のプロジェクトすべてのサブモジュールがアップデートされます。

これでhello.txtの中身がhello2になっていればOKです。

$ cat hello/hello.txt
hello2

サブモジュールがきちんと最新版に更新されていることが確認できました。

ステージング・コミットしてプッシュしておきましょう。

$ git add .
$ git commit -m "update submodule hello: hello2"
$ git push origin master

これで、リモートのリポジトリにもサブモジュールの更新が反映されました。

git-submodule3

上記のように、helloプロジェクトのコミット番号が変更されているのが確認できます。クリックするとhello.txtの内容がhello2になっているのが確認できるかと思います。

サブモジュールを含んだプロジェクトをクローンする

サブモジュールを含んだプロジェクトをGitHubで管理する、というところまで見てきました。次に、そのプロジェクトをクローンする方法を見てみましょう。

以下のコマンドで、サブモジュールを含んだプロジェクトを一発でクローンすることができます。

$ git clone --recursive https://github.com/okutani-t/submodule_test.git

もし、すでにクローン済みで、サブモジュールを含んでいない場合、次のコマンドでサブモジュールを落としてくることができます。

$ git clone https://github.com/okutani-t/submodule_test.git
$ git submodule update --init --recursive

もしくは、次の手順でも同様にサブモジュールを落としてくることができます。

$ git clone https://github.com/okutani-t/submodule_test.git
$ git submodule init
$ git submodule update

基本的には一番上の「git clone --recursive」を使えばOKかと思います。

サブモジュールを編集する

先ほどは、helloプロジェクトをリモート上で直接書き換えましたが、今度はサブモジュールをローカルで直接編集して、リモートリポジトリに反映させてみましょう。

helloディレクトリに移動し、新しく作業用ブランチを切ります。作業用ブランチを切らないと、のちにdetached HEAD状態になってしまうので注意。

$ cd hello
$ git checkout -b work

hello.txtの中身を変更、ステージング・コミットします。

$ echo hello3 > hello.txt
$ git add .
$ git commit -m 'fix submodule: hello'

masterブランチへマージ。

$ git checkout master
$ git merge work

リモートのhelloへプッシュします。

$ git push origin master

作成した作業用ブランチは不要なので削除してもOK。

$ git branch -d work

現在のプロジェクトに戻り、ステージング・コミットします。

$ cd ..
$ git add .
$ git commit -m "hello3 rewite to hello.txt"

リモートリポジトリにプッシュ。

$ git push origin master

リモートのプロジェクトからhelloプロジェクトに移動して、hello3になっていればOKです。

サブモジュールを削除する

サブモジュールを削除したい場合は以下のコマンドを実行します。

$ git submodule deinit hello
$ git rm -rf hello
$ rm -rf .git/modules/hello

これでサブモジュールを削除できます。

もしくは「git submodulesで間違えて追加したときの削除手順 – Qiita」のようなやり方もあるようです。参考にしてください。

まとめ

Gitのサブモジュール機能を使って、独立した別プロジェクトを現在のプロジェクトに追加する方法を見てきました。

Rubyであればgem、PHPであればcomposerなどのツールがありますが、gitで同じようなことをおこないたい場合はサブモジュール機能を使うと良いですね。

Gitのサブモジュールは直接編集してリモートリポジトリに反映させることができるので、自分で管理しているプロジェクトのメンテナンスなども楽におこなうことができます。

今回利用したテストのリポジトリはこちらです。

参考okutani-t/submodule_test: git submoduleの練習

Gitユーザーの参考になれば幸いです。

LINEで送る
Pocket

okutani (okutani_t) のヒトコト
サブモジュールは概念が掴めないとちょっと理解するのに時間がかかりますね。。使いこなせると非常に便利になるかと思うので、ぜひチャレンジしてみてください。

Web開発のお仕事を募集しています

フリーランスのエンジニアとして、Webシステム開発のお仕事依頼を随時募集しています(現在の業務量によってお受けできない場合もあります)。

Ruby on Rails」「JavaScript(jQuery, Reactなど)」「HTML + CSS」を用いたシステム開発、「Heroku」等を用いたサーバー構築・運用、「Git」や「GitHub」を利用したソーシャルコーディングなどに対応しています。

ご依頼を検討している方は、下記リンク本ブログからのお問い合わせ、もしくはokutaniのポートフォリオからご連絡ください。

LINKお問い合わせ

LINKokutani's Portfolio


 - Git

スポンサーリンク

PC用AdSense

PC用AdSense

  こちらもどうぞ

vdeepのトップページへ戻る画像です。風船の形をした島を女の子が掴んでいます。