git 倉庫拆分方案對比
此文已由作者張磊授權網易雲社群釋出。
歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。
前言
git 拆分倉庫在網上已有的案例上來看,分為 submodule 和 subtree。 還有基於這兩個方案進行改進的 subrepo、git-repo 等,當然還可以使用 npm 去管理。
準備工作
可以先閱讀之前的 submodule 、 subtree 以及 subrepo 的文章
git-repo 可以閱讀 https://code.google.com/archive/p/git-repo/ 和https://source.android.com/source/developing 以及網上其他內容
倉庫拆分
無論是最終使用哪種方式,首先是要把程式碼拆開放到新倉庫裡。
方案1:手工強拆
把目錄的程式碼備份,然後從主倉庫刪除,再將程式碼上傳到新建的子倉庫,問題在於提交歷史去丟失,這個問題很嚴重,以後找背鍋的人都難 :(。
方案2:git subtree split
使用 git subtree split -P path/to/module -b branchName,注意 branchName 不要重名,如果歷史記錄多的話這個比較慢,看起來是檢索歷史提交記錄,抓出符合條件(某個資料夾下)的提交日誌,具體可以檢視說明文件,支援並行。這種做法主倉庫的歷史記錄還保留提交。
方案3:filter-branch
這個命令本質上是重寫提交,但是反過來想一想,如果你把指定目錄之外的檔案都刪除了,那不就是得到一個乾淨的子倉庫了? git filter-branch -f --prune-empty --subdirectory-filter path/to/module。這在檔案被新增的時候才會開始遍歷,這樣在某些情況下就比 方案2 快很多,不支援並行。
使用舉例:比如說歷史記錄中提交某個網站的帳號密碼,又過了很多提交才發現,希望刪除掉,就可以使用這個方案。這種做法也會讓歷史記錄變的乾淨。
看起來方案3好用很多。
方案選擇
submodule 在程式碼頻繁更新的時候,需要處理的衝突會比較多,而且一開始會比較迷惑,實際上還算簡單。但是在頻繁的衝突處理的過程中,無疑增大了時間消耗。submodule 本質上是子倉庫自身做修改推送合併,而主倉庫獲取的是子倉庫的最新的 commitid,對子倉庫的更新僅僅是更新其 commitid。
subtree 可以向正常使用 git 倉庫一樣操作子倉庫,成員感知不到子倉庫的存在,複雜度被隱藏在了維護主倉庫和子倉庫的同步的人那裡。
subrepo 需要安裝相關程式,且還在發展中,雖然解決了一些 submodule 和 subtree 的問題。
npm 在只是引用倉庫的情況下,不失為是一種好辦法,但是實際上更改頻率會很高,故不考慮。
git-repo 增加了學習成本,需要學習 repo 的用法,同時需要尋找安裝 Windows 版本的方法,以及用於管理 Android 專案,看完官網說明就準備捨棄這個方案了。
參考
https://services.github.com/on-demand/downloads/submodule-vs-subtree-cheat-sheet/
https://stackoverflow.com/questions/359424/detach-move-subdirectory-into-separate-git-repository
更多網易技術、產品、運營經驗分享請點選。
相關文章:
【推薦】 Kylin儲存和查詢的分片問題
【推薦】 Http介面系列:如何提高Http介面用例的資料穩定性