使用git submodule管理一個需要多個分立開發或者第三方repo的專案

世有因果知因求果發表於2015-05-29

  在專案開發中,特別是web前端開發中,有非常多的開源第三方library,我們希望引用他們,同時也希望能夠方便地保持這些第三方

開源repo的更新。另外一方面如果我們自己在開發一個網站的專案,這個專案一般分為前端和後端兩個相對獨立的子專案,特別是前端的repo可能在不同的專案中共享,那麼這時,你就可能希望將專案分開為前端和後端兩個repo,如何管理這種情況呢?一個比較好的方案就是使用git的submodule功能。

  假設我們的父repo在prepo目錄,sumodule newtestrepo希望放在prepo/submods/newtestrepo這個目錄,首先我們cd submods目錄,

  1. 在submods目錄下執行:git submodule add https://github.com/cnweibo/newtestrepo.git  這個命令將在prepo目錄下建立.gitmodules檔案以及在prepo/submods/目錄下建立newtestrepo目錄用於儲存newtestrepo內容。.gitmodules檔案包含以下內容:

[submodule "submods/newtestrepo"]                                                               
        path = submods/newtestrepo                                                              
        url = https://github.com/cnweibo/newtestrepo.git  

 注意:在1.8版本git之前,上述命令必須在preop的root目錄下執行!

      2.執行git status,則發現有兩個變更需要commit

(newcnweibo_branch)*$ git status                                                                
On branch newcnweibo_branch                                                                     
Your branch is up-to-date with 'origin/newcnweibo_branch'.                                      
                                                                                                
Changes to be committed:                                                                        
  (use "git reset HEAD <file>..." to unstage)                                                   
                                                                                                
        new file:   ../.gitmodules                                                              
        new file:   newtestrepo 

3.執行git commit將增加submodule newtestrepo這個commit做一下提交

(newcnweibo_branch)*$  git commit -m "intro newtestrepo submodule"                              
[newcnweibo_branch 2bb87a3] intro newtestrepo submodule                                         
 2 files changed, 4 insertions(+)                                                               
 create mode 100644 .gitmodules                                                                 
 create mode 160000 submods/newtestrepo  

4. git push 將上述修改放到preop的中央庫中去以便其他teammember使用

5. 如何在prepo這個專案中修改submodule呢?git checkout master 進入newtestrepo的master branch, 修改檔案,commit,隨後git push,注意這裡的push是將submodule push到中央庫中。注意:submodule/newtestrepo目錄下不再有.git目錄,而只有一個.git檔案,這一點很是奇妙!

在我們的submodule的目錄中,你檢視一下.git這個檔案(不是資料夾哦!)的內容實際上指示列出來一個引用gitdir指向prepo的.git/modules/xxxdir/xxxrepo

(detached*)$ cat .git                                                                           
gitdir: ../../.git/modules/submods/newtestrepo  

 

6. 注意,這時如果我們到prepo的目錄中,git status發現我們又有了兩個沒有commit的commit。

隨後我們需要將prepo也做push以便將上述兩個commits遞交.

之所以在submodule中修改並且push後還要在prepo中push是因為我們的父repo其實是引用了子module的一個snapshot,子module修改後,父repo並沒有修改對版本的引用,因此需要commit來反映這個變化。

 7.當我們另外一個teammember clone這個prepo時,注意,prepo裡面所包含的submodule本身目錄都為空!

*$ pwd                                                                                                                                                                     
/home/cabox/workspace/testgit                                                                                                                                              
*$ git clone https://github.com/cnweibo/githubtest.git                                                                                                                     
Cloning into 'githubtest'...                                                                                                                                               
remote: Counting objects: 53, done.                                                                                                                                        
remote: Total 53 (delta 0), reused 0 (delta 0), pack-reused 53                                                                                                             
Unpacking objects: 100% (53/53), done.                                                                                                                                     
Checking connectivity... done.                                                                                                                                             
*$ ls                                                                                                                                                                      
githubtest                                                                                                                                                                 
*$ cd githubtest/                                                                                                                                                          
(newcnweibo_branch)$ ls                                                                                                                                                    
localconfig  newweibobranchfile  readmegithub  submods                                                                                                                     
(newcnweibo_branch)$ git status                                                                                                                                            
On branch newcnweibo_branch                                                                                                                                                
Your branch is up-to-date with 'origin/newcnweibo_branch'.                                                                                                                 
                                                                                                                                                                           
nothing to commit, working directory clean                                                                                                                                 
(newcnweibo_branch)$ cd submods/                                                                                                                                           
(newcnweibo_branch)$ ls                                                                                                                                                    
newtestrepo                                                                                                                                                                
(newcnweibo_branch)$ cd newtestrepo/                                                                                                                                       
(newcnweibo_branch)$ ls                                                                                                                                                    
(newcnweibo_branch)$ ls -la                                                                                                                                                
total 8                                                                                                                                                                    
drwxrwxr-x 2 cabox cabox 4096 May 30 01:08 .                                                                                                                               
drwxrwxr-x 3 cabox cabox 4096 May 30 01:08 ..                                                                                                                              
(newcnweibo_branch)$                                                                                                                                                       
                                  

但是我們的prepo: githubtest本身卻有一個檔案.gitmodules,它列出了在prepo中是如何引用sub module的

(newcnweibo_branch)$ pwd                                                                                                                                                   
/home/cabox/workspace/testgit/githubtest                                                                                                                                                                                                                                                       
(newcnweibo_branch)$ ls -la                                                                                                                                                
total 32                                                                                                                                                                   
drwxrwxr-x 4 cabox cabox 4096 May 30 01:08 .                                                                                                                               
drwxrwxr-x 3 cabox cabox 4096 May 30 01:08 ..                                                                                                                              
drwxrwxr-x 8 cabox cabox 4096 May 30 01:11 .git                                                                                                                            
-rw-rw-r-- 1 cabox cabox  108 May 30 01:08 .gitmodules                                                                                                                     
-rw-rw-r-- 1 cabox cabox 1747 May 30 01:08 localconfig                                                                                                                     
-rw-rw-r-- 1 cabox cabox   66 May 30 01:08 newweibobranchfile                                                                                                              
-rw-rw-r-- 1 cabox cabox  185 May 30 01:08 readmegithub                                                                                                                    
drwxrwxr-x 3 cabox cabox 4096 May 30 01:08 submods                                                                                                                         
(newcnweibo_branch)$ cat .gitmodules                                                                                                                                       
[submodule "submods/newtestrepo"]                                                                                                                                          
        path = submods/newtestrepo                                                                                                                                         
        url = git@github.com:cnweibo/newtestrepo.git                                                                                                                       

8.為了能夠正常使用submodule,我們必須在新clone的prepo中執行 git submodule init命令,執行該命令時:git將通過檢查.gitmodules檔案中的

[submodule "submods/newtestrepo"] 這個section,為每一個submodule都正在prepo的.git/config檔案中增加一條
[submodule "submods/newtestrepo"]                                                                                                                                          
        url = git@github.com:cnweibo/newtestrepo.git 資訊!
(newcnweibo_branch)$ pwd                                                                                                                                                   
/home/cabox/workspace/testgit/githubtest                                                                                                                                   
(newcnweibo_branch)$ git submodule init                                                                                                                                    
Submodule 'submods/newtestrepo' (git@github.com:cnweibo/newtestrepo.git) registered for path 'su                                                                           
bmods/newtestrepo'                                                                                                                                                                                                                                                                          
(newcnweibo_branch)$ ls -la                                                                                                                                                
total 32                                                                                                                                                                   
drwxrwxr-x 4 cabox cabox 4096 May 30 01:08 .                                                                                                                               
drwxrwxr-x 3 cabox cabox 4096 May 30 01:08 ..                                                                                                                              
drwxrwxr-x 8 cabox cabox 4096 May 30 01:17 .git                                                                                                                            
-rw-rw-r-- 1 cabox cabox  108 May 30 01:08 .gitmodules                                                                                                                     
-rw-rw-r-- 1 cabox cabox 1747 May 30 01:08 localconfig                                                                                                                     
-rw-rw-r-- 1 cabox cabox   66 May 30 01:08 newweibobranchfile                                                                                                              
-rw-rw-r-- 1 cabox cabox  185 May 30 01:08 readmegithub                                                                                                                    
drwxrwxr-x 3 cabox cabox 4096 May 30 01:08 submods                                                                                                                         
(newcnweibo_branch)$ cat .git/                                                                                                                                             
HEAD         config       hooks/       info/        objects/     refs/                                                                                                     
branches/    description  index        logs/        packed-refs                                                                                                            
(newcnweibo_branch)$ cat .git/config                                                                                                                                       
[core]                                                                                                                                                                     
        repositoryformatversion = 0                                                                                                                                        
        filemode = true                                                                                                                                                    
        bare = false                                                                                                                                                       
        logallrefupdates = true                                                                                                                                            
[remote "origin"]                                                                                                                                                          
        url = https://github.com/cnweibo/githubtest.git                                                                                                                    
        fetch = +refs/heads/*:refs/remotes/origin/*                                                                                                                        
[branch "newcnweibo_branch"]                                                                                                                                               
        remote = origin                                                                                                                                                    
        merge = refs/heads/newcnweibo_branch                                                                                                                               
[submodule "submods/newtestrepo"]                                                                                                                                          
        url = git@github.com:cnweibo/newtestrepo.git                                                                                                                       
(newcnweibo_branch)$ 

9.隨後我們在prepo再執行git submodule update,這時git將通過Internet把所有的submodule clone進入我們的子目錄中(由.gitmodules檔案來決定放到哪個子目錄中)

(newcnweibo_branch)$ pwd                                                                                                                                                   
/home/cabox/workspace/testgit/githubtest                                                                                                                                   
(newcnweibo_branch)$ ls -la submods/newtestrepo/                                                                                                                           
total 8                                                                                                                                                                    
drwxrwxr-x 2 cabox cabox 4096 May 30 01:08 .                                                                                                                               
drwxrwxr-x 3 cabox cabox 4096 May 30 01:08 ..                                                                                                                              
(newcnweibo_branch)$ git submodule update                                                                                                                                  
Cloning into 'submods/newtestrepo'...                                                                                                                                      
Warning: Permanently added 'github.com,192.30.252.129' (RSA) to the list of known hosts.                                                                                   
Permission denied (publickey).                                                                                                                                             
fatal: Could not read from remote repository.                                                                                                                              
                                                                                                                                                                           
Please make sure you have the correct access rights                                                                                                                        
and the repository exists.                                                                                                                                                 
Clone of 'git@github.com:cnweibo/newtestrepo.git' into submodule path 'submods/newtestrepo' failed                                                                                                                                                                                  
$ ssh -T git@github.com                                                                                                                                                    
Hi kidsit! You've successfully authenticated, but GitHub does not provide shell access.                                                                                    
$ exit                                                                                                                                                                     
exit                                                                                                                                                                       
(newcnweibo_branch)*$ pwd                                                                                                                                                  
/home/cabox/workspace/testgit/githubtest 
(newcnweibo_branch)*$ git submodule update                                                                                                                                 
Cloning into 'submods/newtestrepo'...                                                                                                                                      
Warning: Permanently added the RSA host key for IP address '192.30.252.130' to the list of known hosts.                                                                    
remote: Counting objects: 6, done.                                                                                                                                         
remote: Compressing objects: 100% (3/3), done.                                                                                                                             
remote: Total 6 (delta 0), reused 3 (delta 0), pack-reused 0                                                                                                               
Receiving objects: 100% (6/6), done.                                                                                                                                       
Checking connectivity... done.                                                                                                                                             
Submodule path 'submods/newtestrepo': checked out '6c495d0229fcd15fd7e0bb3cded878d0692988a5'                                                                               
(newcnweibo_branch)$ git submodule update^C                                                                                                                                
(newcnweibo_branch)$ ls -la submods/newtestrepo/                                                                                                                           
.git             README.md        changefromprepo                                                                                                                          
(newcnweibo_branch)$ ls -la submods/newtestrepo/                                                                                                                           
.git             README.md        changefromprepo                                                                                                                          
(newcnweibo_branch)$ ls -la submods/newtestrepo/                                                                                                                           
total 20                                                                                                                                                                   
drwxrwxr-x 2 cabox cabox 4096 May 30 01:32 .                                                                                                                               
drwxrwxr-x 3 cabox cabox 4096 May 30 01:32 ..                                                                                                                              
-rw-rw-r-- 1 cabox cabox   47 May 30 01:32 .git                                                                                                                            
-rw-rw-r-- 1 cabox cabox   14 May 30 01:32 README.md                                                                                                                       
-rw-rw-r-- 1 cabox cabox   29 May 30 01:32 changefromprepo                                                                                                                 
(newcnweibo_branch)$ cat submods/newtestrepo/.git                                                                                                                          
gitdir: ../../.git/modules/submods/newtestrepo            

 

相關文章