git subtree
という便利なコマンドを教えてもらいました。
submodule と異なり、取りこむ外部リポジトリのコミットも取り込み元のリポジトリの commit に入れるので、取り込んだリポジトリの編集を commit に含めることが可能です。
How to use
help コマンド叩けば大体何ができるかわかります。
git subtree -h usage: git subtree add --prefix=<prefix> <commit> or: git subtree add --prefix=<prefix> <repository> <ref> or: git subtree merge --prefix=<prefix> <commit> or: git subtree pull --prefix=<prefix> <repository> <ref> or: git subtree push --prefix=<prefix> <repository> <ref> or: git subtree split --prefix=<prefix> <commit> -h, --help show the help -q quiet -d show debug messages -P, --prefix ... the name of the subdir to split out -m, --message ... use the given message as the commit message for the merge commit options for 'split' --annotate ... add a prefix to commit message of new commits -b, --branch ... create a new branch from the split subtree --ignore-joins ignore prior --rejoin commits --onto ... try connecting new tree to an existing one --rejoin merge the new branch back into HEAD options for 'add', 'merge', and 'pull' --squash merge subtree changes as a single commit
外部のリポジトリを取りこむときは
git subtree add --prefix=<取り込み先のpath/$directoryName> <取りこむ流リポジトリのURL> <取り込むリポジトリのbranch or commit hashj>
を叩きます。但しこのままだと取り込み先の外部リポジトリの commit がそのまま取り込み元の親リポジトリの commit に含まれるので --squash
をつけると1つの commit にまとまってくれます。
// e.g. git subtree add --prefix=app/vendor/3rdLibSample https://github.com/hoge/3rdLibSample.git master --squash
Usecase
取り込む外部リポジトリの変更を親リポジトリの commit ログに入れることができるので
- 外部のライブラリにパッチを当てて検証する
などのケースで力を発揮するのかなと思いました。
自分は普段 Go を書いて仕事をしているのですが、外部ライブラリの修正を開発中のサービスで動作検証したいときに vendor の中身をいじっていたのですが、 git subtree
コマンドを教えてもらってからは prefix で指定した path に外部のリポジトリをコピってきてそのリポジトリの中身を編集、go module の replace の機能を使ってビルドするときは prefix で指定した修正後のライブラリを使う、というフローになりました。
以下のエントリにも追記しました。