實例代碼:
父項目:https://github.com/jjz/pod-project
子項目:https://github.com/jjz/pod-library
使用場景
基于公司的多項目,我們提取了一個公共的類庫提供給多個項目使用,但是這個library怎么和git在一起方便的管理呢?
需要解決以下的幾個問題:
- 如何在git項目中導入library庫?
- library庫在其他的項目中被修改了如何push?
- 其他項目如何獲取到library庫最新的提交?
- 如何在clone的時候能夠自動導入library庫?
解決以上問題,我使用git 的Submodule
來解決。
什么是Submodule?
git Submodule 是一個很好的項目協作工具,他允許類庫項目做為repository,子項目做為一個單獨的git項目存在父項目中,子項目可以有自己的獨立的commit,push,pull。而父項目以Submodule的形式包含子項目,父項目可以指定子項目header,父項目中會提交 Submodule的信息,在clone父項目的時候可以把Submodule初始化。
在項目中添加Submodule
git submodule add git@github.com:jjz/pod-library.git pod-library
使用 git status
命令可以看到
git status
On branch master
Changes to be committed:
new file: .gitmodules
new file: pod-library
多了兩個需要提交的文件
gitmodules
內容
[submodule "pod-library"]
path = pod-library
url = git@github.com:jjz/pod-library.git
這里記錄了子項目的目錄和子項目的git信息
pod-libray
Subproject commit 4ac42d2f8b9ba0c2f0f2f2ec87ddbd529275fea5
這里是子項目的commit的id,git并不會記錄Submodule的文件變動,它是按照這個commit的git來對比Submodule的變動的
這兩個文件都需要提交到父項目的git中
我們還可以這樣添加Submodule
git add .gitmodules pod-ibrary
git commit -m "pod-library submodule"
git submodule init
修改提交Submodule
首先要確認有對Submodule的commit權限
進入Submodule目錄里面,對修改的文件進行提交
cd pod-library/
我們修改了其中的一個文件看下文件的變動
git status
modified: pod-library/UseAFHTTP.h
commit submodule
git commit -a -m'test submodule'
push 到遠端
>git push
然后再回到父目錄:
cd ..
git status
on branch master
modified: pod-library (new commits)
可以看到pod-library已經變更為最新的commit id
Subproject commit 330417cf3fc1d2c42092b20506b0d296d90d0b5f
我們需要把推送到父項目的遠端
git commit -m'update submodule'
git push
更新Submodule
更新的方法有兩種:
- 在父項目的目錄下運行
git submodule foreach git pull
-
在Submodule的目錄下面更新
cd pod-library
git pull
注意更新Submodule的時候如果有新的commit id
產生,需要在父項目產生一個新的提交,pod-libray文件中的 Subproject commit會變為最新的commit id
在clone的時候初始化Submodule
- 采用遞歸參數
--recursive
git clone git@github.com:jjz/pod-project.git --recursive
loning into 'pod-project'...
remote: Counting objects: 57, done.
remote: Compressing objects: 100% (45/45), done.
remote: Total 57 (delta 13), reused 49 (delta 8), pack-reused 0
Receiving objects: 100% (57/57), 18.79 KiB | 0 bytes/s, done.
Resolving deltas: 100% (13/13), done.
Checking connectivity... done.
Submodule 'pod-library' (git@github.com:jjz/pod-library.git) registered for path 'pod-library'
Cloning into 'pod-library'...
remote: Counting objects: 34, done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 34 (delta 8), reused 30 (delta 7), pack-reused 0
Receiving objects: 100% (34/34), 12.95 KiB | 0 bytes/s, done.
Resolving deltas: 100% (8/8), done.
Checking connectivity... done.
Submodule path 'pod-library': checked out '330417cf3fc1d2c
42092b20506b0d296d90d0b5f'
會自動init Submodule
或者使用第二種方法
先clone父項目
git clone git@github.com:jjz/pod-project.git
cd pod-project
git submodule init
Submodule 'pod-library' (git@github.com:jjz/pod-library.git)
registered for path 'pod-library'
git submodule update
Cloning into 'pod-library'...
remote: Counting objects: 34, done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 34 (delta 8), reused 30 (delta 7), pack-reused 0
Receiving objects: 100% (34/34), 12.95 KiB | 0 bytes/s, done.
Resolving deltas: 100% (8/8), done.
Checking connectivity... done.
Submodule path 'pod-library': checked out '330417cf3fc1d2c42092b20506b0d296d90d0b5f'
刪除Submodule
git 并不支持直接刪除Submodule需要手動刪除對應的文件
cd pod-project
git rm --cached pod-library
rm -rf pod-library
rm .gitmodules
vim .git/config
[submodule "pod-library"]
url = git@github.com:jjz/pod-library.git
刪除submodule相關的內容
git commit -a -m 'remove pod-library submodule'