關(guān)于子倉庫或者說是倉庫共用,git官方推薦的工具是git subtree。 我自己也用了一段時間的git subtree,感覺比git submodule好用,但是也有一些缺點,在可接受的范圍內(nèi)。
所以對于倉庫共用,在git subtree 與 git submodule之中選擇的話,我推薦git subtree。
git subtree是什么?為什么使用git subtree
git subtree 可以實現(xiàn)一個倉庫作為其他倉庫的子倉庫。

使用git subtree 有以下幾個原因:
- 舊版本的git也支持(最老版本可以到 v1.5.2).
- git subtree與git submodule不同,它不增加任何像
.gitmodule這樣的新的元數(shù)據(jù)文件. - git subtree對于項目中的其他成員透明,意味著可以不知道git subtree的存在.
當(dāng)然,git subtree也有它的缺點,但是這些缺點還在可以接受的范圍內(nèi):
- 必須學(xué)習(xí)新的指令(如:git subtree).
- 子倉庫的更新與推送指令相對復(fù)雜。
git subtree 的使用
git subtree的主要命令有:
git subtree add --prefix=<prefix> <commit>
git subtree add --prefix=<prefix> <repository> <ref>
git subtree pull --prefix=<prefix> <repository> <ref>
git subtree push --prefix=<prefix> <repository> <ref>
git subtree merge --prefix=<prefix> <commit>
git subtree split --prefix=<prefix> [OPTIONS] [<commit>]
準(zhǔn)備
我們先準(zhǔn)備一個倉庫叫photoshop,一個倉庫叫l(wèi)ibpng,然后我們希望把libpng作為photoshop的子倉庫。
photoshop的路徑為https://github.com/test/photoshop.git,倉庫里的文件有:
photoshop
|
|-- photoshop.c
|-- photoshop.h
|-- main.c
\-- README.md
libPNG的路徑為https://github.com/test/libpng.git,倉庫里的文件有:
libpng
|
|-- libpng.c
|-- libpng.h
\-- README.md
以下操作均位于父倉庫的根目錄中。
在父倉庫中新增子倉庫
我們執(zhí)行以下命令把libpng添加到photoshop中:
git subtree add --prefix=sub/libpng https://github.com/test/libpng.git master --squash
(--squash參數(shù)表示不拉取歷史信息,而只生成一條commit信息。)
執(zhí)行git status可以看到提示新增兩條commit:

git log查看詳細(xì)修改:

執(zhí)行git push把修改推送到遠(yuǎn)端photoshop倉庫,現(xiàn)在本地倉庫與遠(yuǎn)端倉庫的目錄結(jié)構(gòu)為:
photoshop
|
|-- sub/
| |
| \--libpng/
| |
| |-- libpng.c
| |-- libpng.h
| \-- README.md
|
|-- photoshop.c
|-- photoshop.h
|-- main.c
\-- README.md
注意,現(xiàn)在的photoshop倉庫對于其他項目人員來說,可以不需要知道libpng是一個子倉庫。什么意思呢?
當(dāng)你git clone或者git pull的時候,你拉取到的是整個photoshop(包括libpng在內(nèi),libpng就相當(dāng)于photoshop里的一個普通目錄);當(dāng)你修改了libpng里的內(nèi)容后執(zhí)行git push,你將會把修改push到photoshop上。
也就是說photoshop倉庫下的libpng與其他文件無異。
從源倉庫拉取更新
如果源libpng倉庫更新了,photoshop里的libpng如何拉取更新?使用git subtree pull,例如:
git subtree pull --prefix=sub/libpng https://github.com/test/libpng.git master --squash
推送修改到源倉庫
如果在photoshop倉庫里修改了libpng,然后想把這個修改推送到源libpng倉庫呢?使用git subtree push,例如:
git subtree push --prefix=sub/libpng https://github.com/test/libpng.git master
簡化git subtree命令
我們已經(jīng)知道了git subtree 的命令的基本用法,但是上述幾個命令還是顯得有點復(fù)雜,特別是子倉庫的源倉庫地址,特別不方便記憶。
這里我們把子倉庫的地址作為一個remote,方便記憶:
git remote add -f libpng https://github.com/test/libpng.git
然后可以這樣來使用git subtree命令:
git subtree add --prefix=sub/libpng libpng master --squash
git subtree pull --prefix=sub/libpng libpng master --squash
git subtree push --prefix=sub/libpng libpng master