git submoudle vs git subtree

git管理子項目

對於一些比較大的工程,為了便於複用,常常需要抽取子專案。通常專案中的共用UI、共用底層邏輯、共用第三方庫抽出來做git管理子項目。這時候git提供了兩種管理子專案的方式,submodule和subtree。

有人對submodule和subtree的區別做出一個總結: submodule is link; subtree is copy

submodule

container 與 module 各自都是獨立的 git repo

submodule需做一次commit

父層repo需將子層的commitID也要推送上去

submodule的坑

  1. submodule更新完後並push,但主repo沒push新meta檔到伺服器上,另一開發者git pull之後submodule會停留在未修改前的版本。

  2. 假設一切正常,主repo有最新submodule的變動檔案,開發者git submodule update並不會將submodule切到任何branch,所以默認下的submodule的repo會停留在一個detached HEAD(游離狀態)。

修改submodule的坑

  1. 常見的做法切到 submodule 的目錄,然後做修改,然後 commit 和 push。

  2. 如果你不慎忘記切換到分支,又做了提交,可以用 cherry-pick 命令挽救。

    1. 用 git checkout branch 将 HEAD 從游離狀態切換到branch ,這時候,git會報 Warning 說有一個提交没有在 branch上,記住這個提交的 change-id(假如 change-id 为 aaaa)
    2. 用 git cherry-pick aaaa將剛剛提交的檔案併到branch中。
    3. 用 git push 將更新提交到遠程資料庫中。

subtree

只有一個 git repo
只需要做一個 commit

只有一個 repo 也有它的優點在 它就會是一個完整可以 build 的專案
而相應於 git submodule 如果相依的依賴 消失的話 專案就無法開發

參考資料-唐巧的博客

Git參考範例 - 高見龍