追記あり:gitで管理されているディレクトリ配下のフォルダをgit submodule管理に切り替えるときの手順

gitで管理されているディレクトリ配下の特定のディレクトリをsubmoduleにしたい時の手順です。短くなりそうだけど不慣れなので色々確認しながら。

submodule一般については一番下に。

git-root-dir
- dirA
- dirB
-- subDirToSwitch

という構成になっているときに、dirBの下にあるdirToSwitchをsubmoduleにしたいのです。

WordPressで言うと、

  • 複数のサイトで共通の親テーマを使っていて、親テーマにアップデートがあった場合に、他のサイトでも親テーマを最新にしたい
  • WordPressの公式ディレクトリに登録されていない、gitレポジトリにあるプラグインがあって、それを使いたい
  • jsなどのライブラリを最新にしたい

などの時ですが、今回は、既存のディレクトリを置き換えるというケースで苦労したのでメモを残します。

普通のサブモジュール追加

制作が始まるタイミングで、twitter bootstrapを追加しようというとき、

git submodule add git://github.com/twitter/bootstrap.git bootstrap

のようにすれば、bootstrapディレクトリができて、そこがサブモジュールとなります。

置き換えるときのパターン

今回はディレクトリが既に存在している場合。

既存のディレクトリをなくしてみる。

git mv dirB/subDirToSwitch dirB/subDirToSwitch.bk
git add -A

サブモジュールの追加を行う。

git add submodule <repository> dirB/subDirToSwitch

以上で、このレポジトリ上ではサブモジュールでの管理に移ります。

Indexに同じディレクトリが登録されている状態だとエラーになるのです。

他の場所のレポジトリで、プルした後に、同じようにsubmodule管理したい

ひとつのレポジトリ上では上記でOKなのですが、よそでクローンしたりプルしたりすると、dirB/subDirToSwitchは空っぽになります。
サブモジュールが登録されていない状態なので、改めてクローンしなければならないです。

この場合、下記のようにします。

git pull // か git clone ~
git submodule init
git submodule update

サブモジュールを更新する場合には、サブモジュールのディレクトリに移動してgit pullです。

理由は分かっていないのですが、時々ブランチの指定がなくなっている時があります。その際は、ブランチを切り替えるというか指定します。

たいていgit checkout masterだと思います。

$ git pull
You are not currently on a branch. Please specify which
branch you want to merge with. See git-pull(1) for details.

    git pull  

$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
$ git pull
Updating 7678177..3cd0edd
Fast-forward
 header-head.php            |   2 +-
 // なんか色々
 7 files changed, 57 insertions(+), 34 deletions(-)
 create mode 100644 img/common/icon_search.png
$

Git Submoduleの基本

仕組みとしては、レポジトリの中にレポジトリを持ちたいという時に使われます。参考:Git Submodules: コアコンセプト、ワークフロー、コツ | Atlassian Japan

サブモジュールの更新取り込んだりリモートレポジトリへプッシュしたい場合などは、そのディレクトリで git pull/push/fetchとかすれば大丈夫です。

分かりにくかったのは、親レポジトリがこの変更を、子レポジトリのコミットを参照しているだけ、というところでした。

子レポジトリで何かの変更をgit pullしたら、親レポジトリに移動して、子レポジトリのディレクトリをaddします。

cd 子レポ
git pull
cd ..
git add 子レポ

みたいな感じです。

感想

分かりにくいのとコマンドがちょっと面倒なきがします。それでも、僕の場合、一つの親テーマをあちこちで使いまわすみたいなことになっているので、その管理のために前々から様子を探っていたのですが、今後はいちいちディレクトリを手動で置き換える(爆)ことなく作業できそうで、面倒臭さが軽減されそうです。あと、変更の履歴も追えるのでやっぱりありがたいかな。。なんかもっと効率的な方法もある気がします。

追記

なんか大変だなぁと思っていたら、安藤さん @yandod にバッドプラクティスの指摘をもらいました!

Facebookのポスト↓なので、見てみてください。色々議論が進んで、WordMoveというツールを宮内さんに教えてもらったりして(welaika/wordmove · GitHub)、ちょっと週末にでも、試してみたいと思ってます。

Wordmove Tutorial: Pull Database & Uploads from weLaika on Vimeo.

↓ プラグインを作る方々への本、書きました。 ↓

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です