搜尋

首頁  >  問答  >  主體

如何把一個工程中的某一目錄加為git submodule

舉例:我的工程叫My,目錄樹如下

My
|-- My
|   |-- Support
|   |-- main.m
|   |-- images
|   |-- My-Prefix.pch
|   |-- My-Info.plist
|   |-- MyAppDelegate.h
|   |-- MyAppDelegate.m
|
|-- My.xcodeproj

我希望把項目AFNetworking加成Submodule,他的目錄樹如下

AFNetworking
|-- AFNetworking // 这个是真正需要的目录
|-- AFNetworking.xcworkspace
|-- Example
|-- .gitignore
|-- AFNetworking.podspec
|-- CHANGES
|-- LICENSE
|-- README.md

我要把AFNetworking加成submodule

git submodule add https://github.com/AFNetworking/AFNetworking.git My/Support/AFNetworking

最終My的目錄結構

My
|-- My
|   |-- Support
|   |   |-- AFNetworking
|   |       |-- AFNetworking // 这个是真正需要的目录
|   |       |-- AFNetworking.xcworkspace
|   |       |-- Example
|   |       |-- .gitignore
|   |       |-- AFNetworking.podspec
|   |       |-- CHANGES
|   |       |-- LICENSE
|   |       |-- README.md
|   |    
|   |-- main.m
|   |-- images
|   |-- My-Prefix.pch
|   |-- My-Info.plist
|   |-- MyAppDelegate.h
|   |-- MyAppDelegate.m
|
|-- My.xcodeproj

我希望得到的目錄結構是

My
|-- My
|   |-- Support
|   |   |-- AFNetworking // 这个是真正需要的目录
|   |
|   |-- main.m
|   |-- images
|   |-- My-Prefix.pch
|   |-- My-Info.plist
|   |-- MyAppDelegate.h
|   |-- MyAppDelegate.m
|
|-- My.xcodeproj

我通過在子模塊目錄執行這個命令,達到了效果

git filter-branch -f --subdirectory-filter AFNetworking/AFNetworking -- --all

然後

git filter-branch -f --index-filter "git rm -r -f --cached --ignore-unmatch AFNetworking/AFNetworking" --prune-empty

然後回到父倉庫commit並push
看起來一切完美了,但是我重新在clone的時候
這個Submodule的狀態是掛的。。。完全clone不出來,AFNetworking隻是個目錄,沒有文件內容
我用SourceTree打開這個工程,然後看通過submodule的方式打開AFNetworking,reset一下,目錄結構就回到運行 filter-branch 命令之前的樣子了
也就是說,這個效果隻有我一個人在運行了 filter-branch 之後看的到,有沒有什麼辦法,可以讓大家都看到呢?
另外,我還不知道這樣做了以後,如果submodule有更新,能否正常。

PHP中文网PHP中文网2801 天前798

全部回覆(2)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-21 11:18:19

    git 的 submodule 方式不會為倉庫添加實際的內容的,只會透過 .gitmodules 檔案保留對應的子模組的雜湊。

    由於你要真正要用的程式碼處於一個子目錄中,我的方案是你先把這個子目錄提取成一個單獨的倉庫(可以使用git-subtree.sh 這個腳本),然後再添加這個倉庫為submodule (或直接使用git-subtree.sh 把實際的程式碼整合到你的項目,這樣別人克隆就不需要更新submodule 了)。這樣做的缺點就是每當上游有更新,就需要對 submodule 的倉庫做相對應更新。

    另外:git-subtree.sh 已經合併入 git 了,可能並不在 PATH 中,不能直接執行,不過應該在 git 的安裝中的。

    另一個思路:

    建立 bundles 目錄,添加原倉庫為 submodule 到此,然後對需要的子目錄做相對路徑軟鏈接,git 能夠正確處理軟鏈接。這可能是比較好的一個辦法了,不需要額外維護同上游的同步。

    -----------

    你在子模組目錄中進行的subdirectory-filter 已經是git-subree.sh 的split 操作了,這個時候該倉庫已經和orgin 完全不同了,等於重新建立了以該subdirectory 為根的一個倉庫,這個倉庫中的物件只在你的本地,並不包含在origin 的倉庫中,所以最後才會無效的。

    回覆
    0
  • 黄舟

    黄舟2017-04-21 11:18:19

    把一個倉庫的里的子目錄當作你的submodule這樣的方式是不可以的。 git submodule只支援整個倉庫。

    我發現很多依賴了submodule的xcode project都不會把submodule的project給去掉的。因為他們的是按照靜態lib來依賴的,編譯時會按照submodule的project先編譯成lib.a文件,然後link到你的專案。如果把submodule的project檔去掉,那麼編譯時,xcode會把submodule的source當作同一個專案來處理。先把*.m檔編譯出來,然後再link。

    樓上說得git-subtree.sh可能是個辦法。不過我沒嘗試過。

    最後還是建議你試試cocoapods,嘿嘿。

    回覆
    0
  • 取消回覆