Git Tools - Submodules

34277 ワード

Git Tools - Submodules
1.シーンの適用
需要
1つのプロジェクトproject 1で作業する場合は、別のプロジェクトlib 1を使用する必要があります.サードパーティが開発したライブラリか、独立して開発し、複数の親プロジェクト(priject 2、prject 2......)にあるかもしれません.に表示されます.このシーンの次の一般的な問題は、2つのプロジェクトpriject 1、lib 1を単独で処理したいが、そのうちの1つのproject 1で別のlib 1を使用する必要があるということです.
ソリューション
git submodulesを使用しない方法:ライブラリを含む
  • ライブラリを含む:lib 1コードをproject 1(project 2、project 3......)プロジェクトに
  • 含める
  • 問題:プロジェクトのカスタマイズと導入がさらに困難になりました.
  • 問題の原因:各お客様がlib 1を持っていることを確認する必要があります.またlib 1が修正されると(fix bug)、project 1(project 2、project 3......)におけるlib 1の修正はいずれも集計しにくい.
  • 《Git    》
                             ,
                   ,       ,                        ,           ,                    ?
                             ,             ,         。
    

    Git Submodules
    Gitはこの問題をサブモジュールで処理する.サブモジュールでは、Git倉庫を別のGit倉庫のサブディレクトリとして使用できます.これにより、別の倉庫をプロジェクトにクローン化し、コミットを相対的に独立させることができます.git submoduleを習得することで、プロジェクトに重複するリソースファイル、共通クラスライブラリが二度と現れないようにします.さらに、複数のバージョンは発生せず、1つのお客様の複数のプロジェクトスタイルにも様々な違いがあります.
    2.Git Submodulesの使用
    この例では、2つのプロジェクトと2つの共通クラスライブラリを使用してsubmoduleの操作を学習します.
    2.1 Git Submoduleテスト項目の作成
    2.1.1環境の準備
  • 現在のディレクトリ
  • ➜  ~ pwd
    /Users/yjizhang
    ➜  ~ mkdir -p submd/repos
    
  • 必要なローカルウェアハウスを作成する
  • ➜  ~ cd ~/submd/repos
    ➜  repos git --git-dir=lib1.git init --bare
    Initialized empty Git repository in /Users/yjizhang/submd/repos/lib1.git/
    ➜  repos git --git-dir=lib2.git init --bare
    Initialized empty Git repository in /Users/yjizhang/submd/repos/lib2.git/
    ➜  repos git --git-dir=p1.git init --bare
    Initialized empty Git repository in /Users/yjizhang/submd/repos/p1.git/
    ➜  repos git --git-dir=p2.git init --bare
    Initialized empty Git repository in /Users/yjizhang/submd/repos/p2.git/
    ➜  repos ls
    lib1.git lib2.git p1.git   p2.git
    
  • 初期化ワークスペース
  • ➜  ~ mkdir ~/submd/ws
    ➜  ~ cd submd/ws
    

    2.1.2プロジェクトの初期化
  • 初期化p 1(project 1)
  • ➜  ~ cd ~/submd/ws
    ➜  ws git clone ../repos/p1.git
    Cloning into 'p1'...
    warning: You appear to have cloned an empty repository.
    done.
    ➜  ws cd p1
    ➜  p1 git:(master) echo "p1" >> p1-infos.txt
    ➜  p1 git:(master) ✗ ls
    p1-infos.txt
    ➜  p1 git:(master) ✗ gst
    On branch master
    
    Initial commit
    
    Untracked files:
      (use "git add ..." to include in what will be committed)
    
        p1-infos.txt
    
    nothing added to commit but untracked files present (use "git add" to track)
    ➜  p1 git:(master) ✗ git add p1-infos.txt
    ➜  p1 git:(master) ✗ gst
    On branch master
    
    Initial commit
    
    Changes to be committed:
      (use "git rm --cached ..." to unstage)
    
        new file:   p1-infos.txt
    
    ➜  p1 git:(master) ✗ gc -m "init p1"
    [master (root-commit) 960cb75] init p1
     1 file changed, 1 insertion(+)
     create mode 100644 p1-infos.txt
    ➜  p1 git:(master) git push origin master
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 217 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p1.git
     * [new branch]      master -> master
    ➜  p1 git:(master)
    
  • 初期化p 2
  • ➜  ~ cd ~/submd/ws
    ➜  ws git clone ../repos/p2.git
    Cloning into 'p2'...
    warning: You appear to have cloned an empty repository.
    done.
    ➜  ws cd p2
    ➜  p2 git:(master) gst
    On branch master
    
    Initial commit
    
    nothing to commit (create/copy files and use "git add" to track)
    ➜  p2 git:(master) echo "p2" >> p2-infos.txt
    ➜  p2 git:(master) ✗ ls
    p2-infos.txt
    ➜  p2 git:(master) ✗ gst
    On branch master
    
    Initial commit
    
    Untracked files:
      (use "git add ..." to include in what will be committed)
    
        p2-infos.txt
    
    nothing added to commit but untracked files present (use "git add" to track)
    ➜  p2 git:(master) ✗ git add p2-infos.txt
    ➜  p2 git:(master) ✗ gst
    On branch master
    
    Initial commit
    
    Changes to be committed:
      (use "git rm --cached ..." to unstage)
    
        new file:   p2-infos.txt
    
    ➜  p2 git:(master) ✗ gc -m "init p2"
    [master (root-commit) 449e7ed] init p2
     1 file changed, 1 insertion(+)
     create mode 100644 p2-infos.txt
    ➜  p2 git:(master) gst
    On branch master
    Your branch is based on 'origin/master', but the upstream is gone.
      (use "git branch --unset-upstream" to fixup)
    nothing to commit, working tree clean
    ➜  p2 git:(master) git push origin master
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 217 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p2.git
     * [new branch]      master -> master
    ➜  p2 git:(master)
    

    2.1.3共通クラスライブラリの初期化
  • 共通クラスライブラリlib 1
  • を初期化
    ➜  ~ cd ~/submd/ws
    ➜  ws git clone ../repos/lib1.git
    Cloning into 'lib1'...
    warning: You appear to have cloned an empty repository.
    done.
    ➜  ws cd lib1
    ➜  lib1 git:(master) echo "I'm lib1" > lib1-features
    ➜  lib1 git:(master) ✗ git add lib1-features
    ➜  lib1 git:(master) ✗ gc -m "init lib1"
    [master (root-commit) 101b2e6] init lib1
     1 file changed, 1 insertion(+)
     create mode 100644 lib1-features
    ➜  lib1 git:(master) git push origin master
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 224 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/lib1.git
     * [new branch]      master -> master
    
  • 共通クラスライブラリlib 2
  • を初期化
    ➜  lib1 git:(master) cd ~/submd/ws
    ➜  ws git clone ../repos/lib2.git
    Cloning into 'lib2'...
    warning: You appear to have cloned an empty repository.
    done.
    ➜  ws cd lib2
    ➜  lib2 git:(master) echo "I'm lib2" >> lib2-features
    ➜  lib2 git:(master) ✗ git add lib2-features
    ➜  lib2 git:(master) ✗ gc -m "init lib2"
    [master (root-commit) fa8fdee] init lib2
     1 file changed, 1 insertion(+)
     create mode 100644 lib2-features
    ➜  lib2 git:(master) git push origin master
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 225 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/lib2.git
     * [new branch]      master -> master
    

    2.2主プロジェクトにSubmodulesを追加
    2.2.1 lib 1とlib 2をp 1に追加
  • コマンド:git submodule add
  • ➜  cd ~/submd/ws/p1
    ➜  p1 git:(master) ls
    p1-infos.txt
    ➜  p1 git:(master) git submodule add ~/submd/repos/lib1.git libs/lib1
    Cloning into '/Users/yjizhang/submd/ws/p1/libs/lib1'...
    done.
    ➜  p1 git:(master) ✗ git submodule add ~/submd/repos/lib2.git libs/lib2
    Cloning into '/Users/yjizhang/submd/ws/p1/libs/lib2'...
    done.
    ➜  p1 git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes to be committed:
      (use "git reset HEAD ..." to unstage)
    
        new file:   .gitmodules
        new file:   libs/lib1
        new file:   libs/lib2
    
    ➜  p1 git:(master) ✗ tree
    .
    ├── libs
    │   ├── lib1
    │   │   └── lib1-features
    │   └── lib2
    │       └── lib2-features
    └── p1-infos.txt
    
    3 directories, 3 files
    ➜  p1 git:(master) ✗ cat libs/lib1/lib1-features
    I'm lib1
    ➜  p1 git:(master) ✗ cat libs/lib2/lib2-features
    I'm lib2
    
    

    このとき、git submodule addコマンドを使用してp 1に2つの共通クラスライブラリlib 1 lib 2を追加することに成功しました.では、サブモジュールが追加に成功したかどうかをどのように確認しますか?
    2.2.2表示.gitmodulesの内容
  • .gitmodules:このファイルには、submoduleごとの参照情報と、現在のプロジェクトの場所、および倉庫の所在地
  • が記録されています.
    ➜  p1 git:(master) ✗ cat .gitmodules
    [submodule "libs/lib1"]
        path = libs/lib1
        url = /Users/yjizhang/submd/repos/lib1.git
    [submodule "libs/lib2"]
        path = libs/lib2
        url = /Users/yjizhang/submd/repos/lib2.git
    
    

    2.2.3サブモジュールを追加した変更のコミット
    ➜  p1 git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes to be committed:
      (use "git reset HEAD ..." to unstage)
    
        new file:   .gitmodules
        new file:   libs/lib1
        new file:   libs/lib2
    ➜  p1 git:(master) ✗ git commit -a -m "add submodule [lib1、lib2] to p1"
    [master 65a41b4] add submodule [lib1、lib2] to p1
     3 files changed, 8 insertions(+)
     create mode 100644 .gitmodules
     create mode 160000 libs/lib1
     create mode 160000 libs/lib2
    ➜  p1 git:(master) git push
    Counting objects: 4, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (4/4), done.
    Writing objects: 100% (4/4), 488 bytes | 0 bytes/s, done.
    Total 4 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p1.git
       960cb75..65a41b4  master -> master
    

    公共クラスライブラリlib 1、lib 2からp 1の開発者を初めて導入したとしたら、nameプロジェクトグループの他の人はどのようにしてCloneにSubmodulesのあるプロジェクトを持っていますか?
    2.3 Clone Submoduleのある倉庫
    シミュレーション開発者B CloneがSubmoduleを持つプロジェクトp 1
    2.3.1 Clone submodule付きライブラリp 1
    ➜  ~ cd ~/submd/ws
    ➜  ws git clone ../repos/p1.git p1-b
    Cloning into 'p1-b'...
    done.
    ➜  ws ls
    lib1 lib2 p1   p1-b p2
    
    # clone   ,   p1-b  dir tree
    
    ➜  ws cd p1-b
    ➜  p1-b git:(master) tree
    .
    ├── libs
    │   ├── lib1
    │   └── lib2
    └── p1-infos.txt
    
    #    p1-b   p1   dir tree
    
    ➜  p1-b git:(master) cd ../p1
    ➜  p1 git:(master) tree
    .
    ├── libs
    │   ├── lib1
    │   │   └── lib1-features
    │   └── lib2
    │       └── lib2-features
    └── p1-infos.txt
    
    3 directories, 3 files
    
    

    我々cloneのp 1−bにおけるsubmodule[lib 1,lib 2]の内容はcloneから下りていないことが分かった.一気にモジュールを表示できますが、サブモジュールのステータスをどのように表示しますか?
    2.3.2サブモジュールステータスの表示git submodule
    ➜  p1-b git:(master) git submodule
    -101b2e60e0f8c759d2f60c7fca12f3b1e474de21 libs/lib1
    -fa8fdeed9d7c8938c0fe470766c568fb32b1ed14 libs/lib2
    
    ➜  p1-b git:(master) cd ../p1
    ➜  p1 git:(master) git submodule
     101b2e60e0f8c759d2f60c7fca12f3b1e474de21 libs/lib1 (heads/master)
     fa8fdeed9d7c8938c0fe470766c568fb32b1ed14 libs/lib2 (heads/master)
    
    

    -サブモジュールがまだチェックアウトされていないことを示します.どのようにしてサブモジュールの内容をチェックアウトしますか?
    2.3.3サブモジュールコンテンツの検出git submodule init&git submodule update
  • git submodule initローカルプロファイル.git/config
  • を初期化する.
  • git submodule update指定項目.git/configからすべてのデータを引き出し、上位項目に記載されている適切な提出
  • を検出します.
    ➜  p1-b git:(master) git submodule
    -101b2e60e0f8c759d2f60c7fca12f3b1e474de21 libs/lib1
    -fa8fdeed9d7c8938c0fe470766c568fb32b1ed14 libs/lib2
    ➜  p1-b git:(master) cat .git/config
    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = /Users/yjizhang/submd/ws/../repos/p1.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    ➜  p1-b git:(master) git submodule init
    Submodule 'libs/lib1' (/Users/yjizhang/submd/repos/lib1.git) registered for path 'libs/lib1'
    Submodule 'libs/lib2' (/Users/yjizhang/submd/repos/lib2.git) registered for path 'libs/lib2'
    ➜  p1-b git:(master) cat .git/config
    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = /Users/yjizhang/submd/ws/../repos/p1.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [submodule "libs/lib1"]
        url = /Users/yjizhang/submd/repos/lib1.git
    [submodule "libs/lib2"]
        url = /Users/yjizhang/submd/repos/lib2.git
    ➜  p1-b git:(master) git submodule update
    Cloning into '/Users/yjizhang/submd/ws/p1-b/libs/lib1'...
    done.
    Cloning into '/Users/yjizhang/submd/ws/p1-b/libs/lib2'...
    done.
    Submodule path 'libs/lib1': checked out '101b2e60e0f8c759d2f60c7fca12f3b1e474de21'
    Submodule path 'libs/lib2': checked out 'fa8fdeed9d7c8938c0fe470766c568fb32b1ed14'
    ➜  p1-b git:(master) git submodule
     101b2e60e0f8c759d2f60c7fca12f3b1e474de21 libs/lib1 (heads/master)
     fa8fdeed9d7c8938c0fe470766c568fb32b1ed14 libs/lib2 (heads/master)
    ➜  p1-b git:(master) tree
    .
    ├── libs
    │   ├── lib1
    │   │   └── lib1-features
    │   └── lib2
    │       └── lib2-features
    └── p1-infos.txt
    
    3 directories, 3 files
    ➜  p1-b git:(master) cat libs/lib1/lib1-features libs/lib2/lib2-features
    I'm lib1
    I'm lib2
    
    

    2.4 Submoduleのあるライブラリの変更
    シミュレーション開発者Bはサブモジュールの内容を修正する
    2.4.1サブモジュールの表示
    ➜  p1-b git:(master) cd libs/lib1
    ➜  lib1 git:(101b2e6) gst
    HEAD detached at 101b2e6
    nothing to commit, working tree clean
    

    サブモジュールlib 1が匿名のブランチにあることを発見しました.なぜですか.
  • 理由:GitはSubmoduleに対して特別な処理方式を持っている.
  • 主なプロジェクトにSubmoduleを導入しましたGitは3つのことをしました
  • 参照倉庫(サブモジュール倉庫説明)
  • を記録する
  • 主項目におけるSubmoduleのディレクトリ位置を記録する
  • Submoduleを参照するcommit id
  • を記録する
  • 説明:p 1でpushの後、submoduleに対してコミットされた参照commit idがp 1に記録され、p 1-bがclone p 1の時にp 1でsubmoduleに対してコミットされた参照commit idがp 1-bでgit submodule updateが実行されるとgitはmodulesに基づいてsubmoduleのcommit idを取得し、submoduleのファイルを取得する.したがってcloneの後、サブモジュールはブランチにありませんが、masterブランチとcommit idとHEADは一致しています.

  • 2.4.2サブモジュールの更新
  • はmasterブランチ
  • に切り替える.
  • 更新サブモジュールコンテンツ
  • 提出サブモジュール更新
  • メインプロジェクトサブモジュール更新リファレンス
  • をコミット
    #      master   
    
    ➜  p1-b git:(master) cd libs/lib1
    ➜  lib1 git:(101b2e6) gco master
    Switched to branch 'master'
    Your branch is up-to-date with 'origin/master'.
    
    #         
    
    ➜  lib1 git:(master) echo "add by developer b" >> lib1-features
    
    #         
    
    ➜  lib1 git:(master) ✗ ga .
    ➜  lib1 git:(master) ✗ gc -m "update lib1-feature by dev b"
    [master 241e03b] update lib1-feature by dev b
     1 file changed, 1 insertion(+)
    ➜  lib1 git:(master) git push
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 286 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/repos/lib1.git
       101b2e6..241e03b  master -> master
       
    #               
    
    ➜  lib1 git:(master) cd ../../
    ➜  p1-b git:(master) ✗ git diff
    diff --git a/libs/lib1 b/libs/lib1
    index 101b2e6..241e03b 160000
    --- a/libs/lib1
    +++ b/libs/lib1
    @@ -1 +1 @@
    -Subproject commit 101b2e60e0f8c759d2f60c7fca12f3b1e474de21
    +Subproject commit 241e03bf0bf574063417c05a1d558fa4a6006425
    (END)   
    
    ➜  p1-b git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes not staged for commit:
      (use "git add ..." to update what will be committed)
      (use "git checkout -- ..." to discard changes in working directory)
    
        modified:   libs/lib1 (new commits)
    
    no changes added to commit (use "git add" and/or "git commit -a")
    ➜  p1-b git:(master) ✗ git add libs/lib1
    ➜  p1-b git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes to be committed:
      (use "git reset HEAD ..." to unstage)
    
        modified:   libs/lib1
    
    ➜  p1-b git:(master) ✗ gc -m "update libs/lib1 to lastest commit id"
    [master ea785a2] update libs/lib1 to lastest commit id
     1 file changed, 1 insertion(+), 1 deletion(-)
    ➜  p1-b git:(master) git push
    Counting objects: 3, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 389 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p1.git
       65a41b4..ea785a2  master -> master
    

    サブモジュールlib 1の内容をp 1−bで更新した.では、p 1のlib 1の内容をどのように同期して更新しますか?
    2.5メインプロジェクトのSubmoduleの更新
  • 主プロジェクトの最新更新git pullまたはgit pull -r ( . , )
  • サブモジュール更新内容git submodule update(注:実行前にgit submodule initが実行することを確認してサブモジュール情報を.git/congfigに登録する)
  • .
    ➜  p1-b git:(master) cd ../p1
    ➜  p1 git:(master) gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    nothing to commit, working tree clean
    ➜  p1 git:(master) git pull
    remote: Counting objects: 3, done.
    remote: Compressing objects: 100% (3/3), done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /Users/yjizhang/submd/ws/../repos/p1
       65a41b4..ea785a2  master     -> origin/master
    Fetching submodule libs/lib1
    From /Users/yjizhang/submd/repos/lib1
       101b2e6..241e03b  master     -> origin/master
    Updating 65a41b4..ea785a2
    Fast-forward
     libs/lib1 | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    ➜  p1 git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes not staged for commit:
      (use "git add ..." to update what will be committed)
      (use "git checkout -- ..." to discard changes in working directory)
    
        modified:   libs/lib1 (new commits)
    
    no changes added to commit (use "git add" and/or "git commit -a")
    ➜  p1 git:(master) ✗ git submodule update
    Submodule path 'libs/lib1': checked out '241e03bf0bf574063417c05a1d558fa4a6006425'
    ➜  p1 git:(master) cat libs/lib1/lib1-features
    I'm lib1
    add by developer b
    

    2.6 p 2にサブモジュールlib 1 lib 2を追加
    ➜  ws cd ~/submd/ws/p2
    ➜  p2 git:(master) git submodule add ../../repos/lib1.git  libs/lib1
    Cloning into '/Users/yjizhang/submd/ws/p2/libs/lib1'...
    done.
    ➜  p2 git:(master) ✗ git submodule add ../../repos/lib2.git  libs/lib2
    Cloning into '/Users/yjizhang/submd/ws/p2/libs/lib2'...
    done.
    ➜  p2 git:(master) ✗ git add .
    ➜  p2 git:(master) ✗ gc -m "add submodules [lib1 lib2] to p2"
    [master 742934c] add submodules [lib1 lib2] to p2
     3 files changed, 8 insertions(+)
     create mode 100644 .gitmodules
     create mode 160000 libs/lib1
     create mode 160000 libs/lib2
    ➜  p2 git:(master) git push origin master
    Counting objects: 4, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (4/4), done.
    Writing objects: 100% (4/4), 467 bytes | 0 bytes/s, done.
    Total 4 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p2.git
       449e7ed..742934c  master -> master
    ➜  p2 git:(master)
    

    2.7 lib 1 lib 2を修正しp 1 p 2に同期する
  • 使用シーン:開発者Cがp 1とp 2の2つのプロジェクトを同時に担当していると仮定し、彼がp 2を開発したときにlib 1/lib 2にバグがあることを発見したら、私たちはどうすればいいですか?
  • 例の要件は次のとおりです.
  • lib 1にファイルREADME
  • を追加
  • lib 2におけるlib 2-featuresに文字learn git submodule
  • を追加する.

    2.7.1 p 2のlib 1にREADMEを追加
    ➜  p2 git:(master) cd libs/lib1
    ➜  lib1 git:(master) touch README
    ➜  lib1 git:(master) ✗ ga .
    ➜  lib1 git:(master) ✗ gc -m "add readme to lib1"
    [master 2c0e667] add readme to lib1
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 README
    ➜  lib1 git:(master) git push
    Counting objects: 3, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 281 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/lib1.git
       241e03b..2c0e667  master -> master
    

    2.7.2 p 2のlib 2にlearn git submoduleを追加
    ➜  lib1 git:(master) cd ../lib2
    ➜  lib2 git:(master) echo "learn git submodule" >> lib2-features
    ➜  lib2 git:(master) ✗ ga .
    ➜  lib2 git:(master) ✗ gc -m "add text to lib2 feature"
    [master cc6dc70] add text to lib2 feature
     1 file changed, 1 insertion(+)
    ➜  lib2 git:(master) git push
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 284 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/lib2.git
       fa8fdee..cc6dc70  master -> master
    

    2.7.3 p 2で参照したcommit idを更新する
    ➜  p2 git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes not staged for commit:
      (use "git add ..." to update what will be committed)
      (use "git checkout -- ..." to discard changes in working directory)
    
        modified:   libs/lib1 (new commits)
        modified:   libs/lib2 (new commits)
    
    no changes added to commit (use "git add" and/or "git commit -a")
    ➜  p2 git:(master) ✗ git add libs/lib1
    ➜  p2 git:(master) ✗ gc -m "update lib1 to lastest commit id"
    [master 6be8d5f] update lib1 to lastest commit id
     1 file changed, 1 insertion(+), 1 deletion(-)
    ➜  p2 git:(master) ✗ git add libs/lib2
    ➜  p2 git:(master) ✗ gc -m "update lib2 to lastest commit id"
    [master deebabf] update lib2 to lastest commit id
     1 file changed, 1 insertion(+), 1 deletion(-)
     
     ➜  p2 git:(master) git push
    Counting objects: 6, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (6/6), done.
    Writing objects: 100% (6/6), 730 bytes | 0 bytes/s, done.
    Total 6 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p2.git
       742934c..deebabf  master -> master
    

    2.7.4同期p 2におけるlib 1 lib 2の変更点p 1
    ➜  p1 git:(master) ✗ git pull
    Already up-to-date.
    ➜  p1 git:(master) git submodule
     241e03bf0bf574063417c05a1d558fa4a6006425 libs/lib1 (remotes/origin/HEAD)
     fa8fdeed9d7c8938c0fe470766c568fb32b1ed14 libs/lib2 (heads/master)
    
    #    p2
    
    ➜  p2 git:(master) git submodule
     2c0e66770cc2b2f697cf0e86f3b51d737a5e6e93 libs/lib1 (heads/master)
     cc6dc70a8a46965cd1b7860a859f9e4f2a0c34f7 libs/lib2 (heads/master) 
    
    #          :
     
    * commit id    
    * libs/lib1        
    
    #      p1   lib1    master    ,       p1 lib1     master    ,    
    
    ➜  p1 git:(master) ✗ cd libs/lib1
    ➜  lib1 git:(241e03b) gco master
    Previous HEAD position was 241e03b... update lib1-feature by dev b
    Switched to branch 'master'
    Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
      (use "git pull" to update your local branch)
    ➜  lib1 git:(master) git pull
    remote: Counting objects: 3, done.
    remote: Compressing objects: 100% (2/2), done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /Users/yjizhang/submd/repos/lib1
       241e03b..2c0e667  master     -> origin/master
    Updating 101b2e6..2c0e667
    Fast-forward
     README        | 0
     lib1-features | 1 +
     2 files changed, 1 insertion(+)
     create mode 100644 README
     
    #    lib2    
     
     ➜  lib1 git:(master) cd ../lib2
    ➜  lib2 git:(master) git pull -r
    remote: Counting objects: 3, done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /Users/yjizhang/submd/repos/lib2
       fa8fdee..cc6dc70  master     -> origin/master
    First, rewinding head to replay your work on top of it...
    Fast-forwarded master to cc6dc70a8a46965cd1b7860a859f9e4f2a0c34f7.
    
    #    p1        
    
    ➜  lib2 git:(master) cd ../../
    ➜  p1 git:(master) ✗ git submodule
    +2c0e66770cc2b2f697cf0e86f3b51d737a5e6e93 libs/lib1 (heads/master)
    +cc6dc70a8a46965cd1b7860a859f9e4f2a0c34f7 libs/lib2 (heads/master)
    
    #    p2
    
    ➜  p2 git:(master) git submodule
     2c0e66770cc2b2f697cf0e86f3b51d737a5e6e93 libs/lib1 (heads/master)
     cc6dc70a8a46965cd1b7860a859f9e4f2a0c34f7 libs/lib2 (heads/master)  
    

    2.7.5 p 1のsubmoduleの参照を更新する
    前のステップではp 1のlib 1とlib 2の最新バージョンを更新し、最新のcommit idをp 1に保存して最新の参照を維持します.
    ➜  p1 git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes not staged for commit:
      (use "git add ..." to update what will be committed)
      (use "git checkout -- ..." to discard changes in working directory)
    
        modified:   libs/lib1 (new commits)
        modified:   libs/lib2 (new commits)
    
    no changes added to commit (use "git add" and/or "git commit -a")
    ➜  p1 git:(master) ✗ ga .
    ➜  p1 git:(master) ✗ gc -m "update lib1 lib2 commit id to new version"
    [master 141bf28] update lib1 lib2 commit id to new version
     2 files changed, 2 insertions(+), 2 deletions(-)
    ➜  p1 git:(master) git push
    Counting objects: 3, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 393 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p1.git
       ea785a2..141bf28  master -> master
    

    2.8 p 1-bサブモジュールの内容を更新する
    2.8.1 p 1-b参照サブモジュールのcommit idを更新
    ➜  p1-b git:(master) gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    nothing to commit, working tree clean
    ➜  p1-b git:(master) git pull
    remote: Counting objects: 3, done.
    remote: Compressing objects: 100% (3/3), done.
    remote: Total 3 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From /Users/yjizhang/submd/ws/../repos/p1
       ea785a2..141bf28  master     -> origin/master
    Fetching submodule libs/lib1
    From /Users/yjizhang/submd/repos/lib1
       241e03b..2c0e667  master     -> origin/master
    Fetching submodule libs/lib2
    From /Users/yjizhang/submd/repos/lib2
       fa8fdee..cc6dc70  master     -> origin/master
    Updating ea785a2..141bf28
    Fast-forward
     libs/lib1 | 2 +-
     libs/lib2 | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    ➜  p1-b git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes not staged for commit:
      (use "git add ..." to update what will be committed)
      (use "git checkout -- ..." to discard changes in working directory)
    
        modified:   libs/lib1 (new commits)
        modified:   libs/lib2 (new commits)
    
    no changes added to commit (use "git add" and/or "git commit -a")
    
    Git  lib1 lib2     ,          submodule commit id   。
    

    では、p 1-bサブモジュールの内容をどのように更新しますか?
    2.8.2 p 1-bサブモジュールの内容を更新する
    今、私たちは2つのサブモジュールしかありません.p 1のようにサブモジュールのディレクトリに入ってgit checkout mastergit pullに入って、メインライブラリで参照されているcommit idを更新することができます.しかし、私たちのプロジェクトにはサブモジュールがたくさんあるので、サブモジュールのディレクトリに一つ一つ入ってサブモジュールの内容を更新するのは現実的ではありません.この問題を解決する方法は2つあります.
  • git submodule foreach git pull
  • .shスクリプト
  • git submodule foreach git pullを使用してサブモジュールコンテンツ
  • を更新する
    
    ➜  p1-b git:(master) ✗ git submodule foreach git pull
    Entering 'libs/lib1'
    Updating 241e03b..2c0e667
    Fast-forward
     README | 0
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 README
    Entering 'libs/lib2'
    You are not currently on a branch.
    Please specify which branch you want to merge with.
    See git-pull(1) for details.
    
        git pull  
    
    Stopping at 'libs/lib2'; script returned non-zero status.
    ➜  p1-b git:(master) ✗ ls
    libs         p1-infos.txt
    ➜  p1-b git:(master) ✗ tree
    .
    ├── libs
    │   ├── lib1
    │   │   ├── README
    │   │   └── lib1-features
    │   └── lib2
    │       └── lib2-features
    └── p1-infos.txt
    
    3 directories, 4 files
    
    
  • .shスクリプトを使用してサブモジュールコンテンツ
  • を更新する.
    ➜  p1-b git:(master) ✗ mkdir bin
    ➜  p1-b git:(master) ✗ vim bin/update-submodule.sh
    
    #           update-submodule.sh  
    
    #!/bin/bash
    grep path .gitmodules | awk '{ print $3 }' > /tmp/study-git-submodule-dirs
     
    # read
    while read LINE
    do
        echo $LINE
        (cd ./$LINE && git checkout master && git pull)
    done < /tmp/study-git-submodule-dirs
    
    #        
    *               **/tmp/study-git-submodule-dirs** ;
    *              ,     master  (     master      ),        。
    
    #   .sh          
    
    ➜  p1-b git:(master) ✗ cd bin
    ➜  bin git:(master) ✗ ll
    total 8
    -rw-r--r--  1 yjizhang  staff   219B Jan  7 20:11 update-submodule.sh
    ➜  bin git:(master) ✗ chmod +x update-submodule.sh
    ➜  bin git:(master) ✗ ll
    total 8
    -rwxr-xr-x  1 yjizhang  staff   219B Jan  7 20:11 update-submodule.sh
    ➜  bin git:(master) ✗ cd ../
    ➜  p1-b git:(master) ✗ ./bin/update-submodule.sh
    libs/lib1
    Already on 'master'
    Your branch is up-to-date with 'origin/master'.
    Already up-to-date.
    libs/lib2
    Switched to branch 'master'
    Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
      (use "git pull" to update your local branch)
    Updating fa8fdee..cc6dc70
    Fast-forward
     lib2-features | 1 +
     1 file changed, 1 insertion(+)
     ➜  p1-b git:(master) ✗ git submodule
     2c0e66770cc2b2f697cf0e86f3b51d737a5e6e93 libs/lib1 (heads/master)
     cc6dc70a8a46965cd1b7860a859f9e4f2a0c34f7 libs/lib2 (heads/master)
     
    #      p1-b     commit id   p2      
      
    #    .sh     p1-b   
    ➜  p1-b git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Untracked files:
      (use "git add ..." to include in what will be committed)
    
        bin/
    
    nothing added to commit but untracked files present (use "git add" to track)
    ➜  p1-b git:(master) ✗ git add bin/update-submodule.sh
    ➜  p1-b git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes to be committed:
      (use "git reset HEAD ..." to unstage)
    
        new file:   bin/update-submodule.sh
    
    ➜  p1-b git:(master) ✗ gc -m "add update submodules shell to p1"
    [master beca8c0] add update submodules shell to p1
     1 file changed, 9 insertions(+)
     create mode 100755 bin/update-submodule.sh
    ➜  p1-b git:(master) git push
    Counting objects: 4, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (4/4), 560 bytes | 0 bytes/s, done.
    Total 4 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p1.git
       141bf28..beca8c0  master -> master 
    

    2.9一次クローン饅頭モジュールのライブラリgit submodule foreach git pullのようにgitは、cloneがすべてのサブモジュールの内容を含むコマンドgit clone --recursive xx.gitを提供する.
    ➜  ws git clone --recursive ../repos/p1.git p1-submodules
    Cloning into 'p1-submodules'...
    done.
    Submodule 'libs/lib1' (/Users/yjizhang/submd/repos/lib1.git) registered for path 'libs/lib1'
    Submodule 'libs/lib2' (/Users/yjizhang/submd/repos/lib2.git) registered for path 'libs/lib2'
    Cloning into '/Users/yjizhang/submd/ws/p1-submodules/libs/lib1'...
    done.
    Cloning into '/Users/yjizhang/submd/ws/p1-submodules/libs/lib2'...
    done.
    Submodule path 'libs/lib1': checked out '2c0e66770cc2b2f697cf0e86f3b51d737a5e6e93'
    Submodule path 'libs/lib2': checked out 'cc6dc70a8a46965cd1b7860a859f9e4f2a0c34f7'
    ➜  ws cd p1-submodules
    ➜  p1-submodules git:(master) tree
    .
    ├── bin
    │   └── update-submodule.sh
    ├── libs
    │   ├── lib1
    │   │   ├── README
    │   │   └── lib1-features
    │   └── lib2
    │       └── lib2-features
    └── p1-infos.txt
    
    4 directories, 5 files
    

    3.Git Submodulesの削除
    3.1 Cloneテストライブラリ
    p 1ライブラリから
    ➜  ws git clone --recursive ../repos/p1.git p1-remove-submodules
    Cloning into 'p1-remove-submodules'...
    done.
    Submodule 'libs/lib1' (/Users/yjizhang/submd/repos/lib1.git) registered for path 'libs/lib1'
    Submodule 'libs/lib2' (/Users/yjizhang/submd/repos/lib2.git) registered for path 'libs/lib2'
    Cloning into '/Users/yjizhang/submd/ws/p1-remove-submodules/libs/lib1'...
    done.
    Cloning into '/Users/yjizhang/submd/ws/p1-remove-submodules/libs/lib2'...
    done.
    Submodule path 'libs/lib1': checked out '2c0e66770cc2b2f697cf0e86f3b51d737a5e6e93'
    Submodule path 'libs/lib2': checked out 'cc6dc70a8a46965cd1b7860a859f9e4f2a0c34f7'
    ➜  ws cd p1-remove-submodules
    

    3.2サブモジュールの削除
  • git cacheと物理フォルダ
  • を削除
  • 削除.gitmodulesの内容(またはファイル全体:すべてのサブモジュールを削除する場合)
  • 削除.git/configのsubmodule構成
  • 3.2.1 git cacheと物理フォルダの削除
    ➜  p1-remove-submodules git:(master) git rm -r --cached libs/
    rm 'libs/lib1'
    rm 'libs/lib2'
    ➜  p1-remove-submodules git:(master) ✗ rm -rf libs
    ➜  p1-remove-submodules git:(master) ✗ ls
    bin          p1-infos.txt
    

    3.2.2削除します.gitmodulesの内容(またはファイル全体:すべてのサブモジュールを削除する場合)
    ➜  p1-remove-submodules git:(master) ✗ rm -rf .gitmodules
    
    #   p1-remove-submodules           
    #             ,     .gitmodules                   
    

    3.2.3削除します.git/configのsubmodule構成
    ➜  p1-remove-submodules git:(master) ✗ cat .git/config
    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = /Users/yjizhang/submd/ws/../repos/p1.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [submodule "libs/lib1"]
        url = /Users/yjizhang/submd/repos/lib1.git
    [submodule "libs/lib2"]
        url = /Users/yjizhang/submd/repos/lib2.git
        
    #    lib1 lib2    
    
    ➜  p1-remove-submodules git:(master) ✗ cat .git/config
    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = /Users/yjizhang/submd/ws/../repos/p1.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
        
    ➜  p1-remove-submodules git:(master) ✗ gst
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes to be committed:
      (use "git reset HEAD ..." to unstage)
    
        deleted:    libs/lib1
        deleted:    libs/lib2
    
    Changes not staged for commit:
      (use "git add/rm ..." to update what will be committed)
      (use "git checkout -- ..." to discard changes in working directory)
    
        deleted:    .gitmodules
    
    ➜  p1-remove-submodules git:(master) ✗ git add .
    ➜  p1-remove-submodules git:(master) ✗ gc -m "delete submodule lib1 and lib2"
    [master 28e23f9] delete submodule lib1 and lib2
     3 files changed, 8 deletions(-)
     delete mode 100644 .gitmodules
     delete mode 160000 libs/lib1
     delete mode 160000 libs/lib2
    ➜  p1-remove-submodules git:(master) git push
    Counting objects: 2, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (2/2), 279 bytes | 0 bytes/s, done.
    Total 2 (delta 0), reused 0 (delta 0)
    To /Users/yjizhang/submd/ws/../repos/p1.git
       beca8c0..28e23f9  master -> master
    
    #       
    

    リファレンス
    http://www.kafeitu.me/git/2012/03/27/git-submodule.html