Git Submodule
2014-06-09 00:00
246 查看
新增一個 Git Submodule
例如我有目前本機有一個 josephj.git、在 /home/josephj/www 下,而我需要將 javascript platform 放到 /home/josephj/www/static/ 可以用以下幾行快速達成。切換到我的 repository 目錄:
$ cd /home/josephj/www
使用 git submodule add [repository 位置] [欲放置的位置] 增加一個新的 submodule:
$ git submodule add git@github.com:josephj/javascript-platform-yui.git static/platform需要注意 [欲放置的位置] 不能以 / 結尾(會造成修改不生效)、也不能已經是現有的路徑喔(不能順利 Clone)。
按下去就會看到以下結果:
$ git submodule add git://github.com/josephj/javascript-platform-yui.git static/platform Initialized empty Git repository in /home/josephj/www/static/platform/.git/ remote: Counting objects: 31, done. remote: Compressing objects: 100% (31/31), done. remote: Total 31 (delta 14), reused 0 (delta 0) Receiving objects: 100% (31/31), 6.06 KiB, done. Resolving deltas: 100% (14/14), done.這時在 /home/josephj/www/ 會產生一個 .gitmodules 記錄你的 Submodule 資訊。該 git 的相關檔案也都會在此時被拉下來。
用 git status 看一下:
$ git status # On branch master # Changes to be committed: # (use "git reset HEAD..." to unstage) # # new file: .gitmodules # new file: static/platform #會發現它只列出 submodule 目錄而非所有底下檔案,parent git 實際上也只會記錄 submodule 的 commit id 以供未來做比對用。這裡一個很重要的點是大家必須理解的:parent git 與 submodule git 的關連性(被掛入的目錄、repository 位置)記錄在 .gitmodules 中,而版本控制則是靠 parent git 記住 submodule git 的 commit id。
先 commit 一下:
$ git add .gitmodules static/platform git commit -m "Add submodule into version control";
但是你還必須做 init 的動作,你的 .git/config 才會有對應 submodule 的資訊。
$ git submodule init
更新已安裝的 Submodule
當初我第一次新增一個 Submodule 後,以為未來它都會像 SVN External 一樣、在我 git pull 的時候自動更新。但實際情況是你必須手動處理才能更新 Submodule。進入該目錄 Subomdule 目錄:
$ cd static/platform
向來源的 master branch 做 git pull 的動作(這裡的 git pull 不會更新你 parent git 的檔案)
$ git pull origin master
若 submodule 有更新的檔案,你可以到 parent git 觀看一下情況:
$ cd ../../ $ git status # Not currently on any branch. # Changed but not updated: # (use "git add..." to update what will be committed) # (use "git checkout --..." to discard changes in working directory) # # modified: static/platform (new commits) # no changes added to commit (use "git add" and/or "git commit -a")與第一次 git submodule add 相同,submodule 更新的檔案並不會在 git status 中要求你 commit 喔!
我們前面提到,submodule 的版本控制在於 submodule git 的 commit id,上面看到 static/platform 有 new commit。表示你既然把新的內容 pull 回來、應該要更新 submodule 的 commit id 到你的 git 中:
$ git add static/platform $ git commit -m "static/platform submodule updated"如此一來,新的 submodule commit id 就被你的 repositiory 給記錄下來囉!
團隊使用 Submodule
在一個多人的軟體開發團隊中,通常還是會有 Centralized Git Repositiory,像我們公司就採用了 gitosis 的解決方案。而像上述更新 Submodule 的情形,通常只有一兩個負責架構的人來做(大多是一開始把東西掛進來的人)、其他人只是單純使用者的角色,並不需要負責更新的工作。像上面我增加了一個 Submodule,對於團隊其他人來說,他們在下一次的 git pull 會看到以下的狀況:
$ git status # On branch develop # Changed but not updated: # (use "git add..." to update what will be committed) # (use "git checkout --..." to discard changes in working directory) # # modified: static/platform (new commits) # no changes added to commit (use "git add" and/or "git commit -a")這表示其他人也會拿到 .gitmodules 的設定,但他必須使用 git submodule init 將新的 Submodule 註冊到自己的 .git/config、未來才能使用。
$ git submodule init Submodule 'static/platform' (http://github.com/josephj/javascript-platform-yui.git) registered for path 'static/platform'
接著其他人使用 git submodule update 把該 Submodule 的內容全部拉下來!
$ git submodule update Cloning into static/platform... remote: Counting objects: 34, done. remote: Compressing objects: 100% (34/34), done. remote: Total 34 (delta 15), reused 0 (delta 0) Unpacking objects: 100% (34/34), done. Submodule path 'static/platform': checked out '117c5b3c5a195deac2e53aa118b78ef3f01ae371'
使用時機
簡單整理一下:git submodule init: 在 .gitmodules 第一次被其他人建立或有新增內容的時候,用 git submodule init 更新你的 .git/config、設定目錄與增加 submodule 的 remote URL。
git submodule update: 在 init 完有新的 submodule commit id 後就可以做了,會把所有相關檔案拉下來。若其他人更新 submodule 造成你拿到新的 commit id 時,你可以直接用 git submodule update 做更新即可、不需要做任何 add 或 commit 的動作!
可以想見,其他成員使用 git submodule update 的情況會遠比 git submodule init 多很多。
修改 Submodule 的內容
有時自己也是 Submodule 的 Owner,碰到要改 Code 時,要我切回原本的此 Git 開發位置有點麻煩... 不如就直接改被當成 Submodule 掛進來的原始碼吧!到 submodule 目錄去做些修改:
$ cd static/platform $ vim README # 做些修改
接著就是常見的 git add , git commit, git push
$ git add README $ git commit -m "Add comments" $ git push
push 完回到根目錄git status 看一下!會看到
$ git status # On branch master # Changed but not updated: # (use "git add..." to update what will be committed) # (use "git checkout --..." to discard changes in working directory) # # modified: static/platform # no changes added to commit (use "git add" and/or "git commit -a")
這裡也需要再做一次 Commit 喔!
$ git add static/platform $ git commit -m 'Submodule updated' $ git push
這裡有一點非常需要注意,因為 Submodule 的更新只記錄 commit id,所以你必須先在 submodule 內做 commit、push 後、再到 parent git 做commit, push,不然會出現版本錯亂的問題,別人跟你 submodule 的內容將會不一致。
如何移除 Submodule
這點也非常地不直覺,不是想像中 git submodule remove [欲移除的目錄] 這麼簡單...先砍掉目錄:
$ git rm --cached [欲移除的目錄] $ rm -rf [欲移除的目錄]
再修改 .gitmodules
$ vim .gitmodules將相關內容移除
再修改 .git/config
$ vim .git/config將相關內容移除
最後再 commit,改變整個 Repository。
$ git add .gitmodules $ git commit -m "Remove a submodule"
安全起見再做個 sync:
$ git submodule sync
相关文章推荐
- Git 通过submodule添加子项目/库。
- 【转】git submodule 与 git subtree
- Git Submodule完整教程(3/3)
- Git Submodule使用完整教程
- git submodule常用的几个命令
- Git Submodule 使用简介
- [Git] Git 文件归档, include submodule
- git submodule的使用
- Git Submodule 使用简介
- git submodule update安装/升级模块的github配置
- Git submodule 特性
- git子模块使用之git submodule与 git subtree比较
- git submodule的使用,主项目和公共库关联起来
- Git Submodule使用完整教程
- Git Submodule 命令
- 初次使用git submodule
- git submodule的使用
- git submodule的使用
- Git Submodule的坑
- git submodule的使用