【Git教程】(十八)拆分大項目 — 概述及使用要求,執行過程及其實現,替代解決方案 ~

Git教程 · 拆分大項目

  • 1?? 概述
  • 2?? 使用要求
  • 3?? 執行過程及其實現
      • 3.1 拆分模塊版本庫
      • 3.2 將拆分出的模塊作為外部版本庫集成
  • 4?? 替代解決方案

在這里插入圖片描述

通常軟件項目都是由單體小型系統開始的,在開發過程中項目規模和團隊人員不斷擴大, 將項目模塊化會顯得越發重要。第一步是將項目內部結構模塊化,最終會需要將各個模塊獨立開發并擁有不同的提交發布周期。

由于 Git 版本庫是以整個版本庫作為一個整體來發布版本的,所以每個擁有獨立發布周期的模塊都需要新的Git 版本庫。
為 Git 版本庫拆分模塊過程中的挑戰之處在于要盡可能保留原版本庫中文件及其版本信息。同時,新的版本庫不應該包含本模塊不需要的文件,也不需要包含那些沒有更改本模塊相關文件的提交。

在主版本庫中,模塊的歷史沒有被刪除,所以原項目中的歷史版本已然存在并可以復現。因此,不同模塊的歷史數據同時存在于拆分前后兩個版本庫中。
大部分拆分出的模塊依然被主項目所需要,應以外部模塊的角色集成到主項目中,這種集成關系,在Git 中被稱為子模塊 (submodule)。

這段工作流演示了如何在Git 中抽取模塊,同時實現這樣3種目標。

  • 只有該模塊所需要的文件被導入到新版本庫。
  • 模塊文件歷史將被保留在新版本庫中。
  • 模塊可以作為外來模塊再次被集成到主項目中。

1?? 概述

接下來這段操作中,我們使用如圖上部顯示的項目結構為例。這段實例工作流是基于Java 目錄結構的,整個項目有3個模塊,每個模塊中的文件分別置于源代碼 (src) 和測試代碼 (test) 兩個子目錄中。換句話說,也就是每個模塊包括兩個部分。接下來將模塊3分化到獨立的版本庫中。

第一步,刪除所有無用的文件,使用 filter branch 命令在原版本庫的一個克隆分支上提交即可。接下來,更新新模塊版本庫的目錄結構用以管理模塊3。最后,將模塊3從原項目中移除,再將新模塊版本庫作為子模塊合入原項目的外部引用目錄中,結果如圖下部所示。

在這里插入圖片描述
新的模塊版本庫中可以重建文件的修改歷史,也就是跟蹤記錄誰在什么時間做了什么修改,但是不可以完整地重現歷史版本。原因是一個模塊的文件往往源自另外一些模塊。在模塊版本庫中嘗試恢復項目的某一歷史版本可能不僅會涉及本模塊目錄,而是不同目錄文件的混雜集合。而且,在過去的版本中本模塊可能被用作某些文件的依賴,而這些文件已經不存在了。
在主版本庫中,整個項目的舊版本依然可以恢復重現。


2?? 使用要求

  • 項目內部需要模塊化時:項目內部需要被分為不同的模塊,比如當某一模塊需要獨立開發和發布版本。
  • 模塊文件被分置于不同的目錄中時:這時要提取模塊的某一歷史版本,文件在不同個目錄中將需要不同的處理,如果文件十分分散代價將非常大。

3?? 執行過程及其實現

一個模塊從項目中被刪除并遷移到獨立的版本庫中,提交歷史將被保留下來,無用的文件和提交歷史將被刪除。獨立模塊將以外部子模塊的形式回到項目中。

需要注意,部分以下命令將徹底改變版本庫。雖然 Git 中改變通常可以撤回,但仍應在開始之前確保你的版本庫已備份。

> git clone --no-hardlinks --bare projekt.git projekt.backup.git

使用 --no-hardlinks 選項來保證克隆的版本庫和源版本庫不共享任何文件。


3.1 拆分模塊版本庫

  • 第1步:克隆主版本庫
    作為模塊版本庫的起點,首先將主版本庫克隆一份。

    > git clone --no-hardlinks --bare projekt.git modul3-work.git
    
  • 第2步:刪除無用的文件和提交
    接下來,必須刪除無用的文件和提交,這是最復雜的一步,也是為了保留模塊歷史至關重要的一步。
    刪除一個版本庫中的部分內容可以用 filter-branch 命令。它將針對待修改的提交來創建一次新的提交,通過配置不同的過濾器來改變這次提交的內容。
    以下示例 filter-branch 命令將刪除 src/module1 目錄下內容。

    > cd module3
    > git filter-branch --force --index-filter
    'git rm -r -cached --ignore-unmatch src/module1'--tag-name-filter cat--prune-empty -- --all
    

    參數可以這樣配置。

    • --index-filter 'git rm -r -cached --ignore-unmatch …': 通過配置這樣的參數,可以將文件從提交中移除。rm 命令逐個提交操作。在如上示例中,將作用于src/module1文件目錄。 如果待清理的項目沒有明顯的模塊化結構層次,可能需要刪除多個文件或多個文件目錄。
    • --tag-name-filter cat: 可以為已經存在的或者新建的提交標注標簽。
    • --prune-empty: 將刪除經過前面的過濾器后不包含任何文件的空提交。
    • --all: 將過濾器適用于整個項目的所有分支。
      在示例的項目中,如此的操作需要依次在 test/module1 、src/module2 和 test/module2 文件目錄下執行。
      關于 filter branch 命令每項參數的詳細描述,可以參照 Git 幫助。
  • 第3步:刪除無用的分支和標簽
    不是所有標簽和分支在新的模塊分支都有意義。例如,那些與模塊不相關的文件標簽和分支就是無意義的,需要被刪除。

    > git tag -d v1.0.1
    > git branch -D v2.0_bf
    
  • 第4步:縮減模塊版本庫的規模
    Git 為了縮減規模在管理數據中刪除無用的文件需要重復克隆一次。

    > git clone --no-hardlinks
    --bare module3-work.git module3.git
    

    這樣,過去的模塊版本庫 module3-work.git 就不再有效,可以刪除了。

    > rm -rf modul3-work.git
    
  • 第5步,定制模塊版本庫文件架構
    到目前為止,新版本庫的文件結構和主項目一樣,只是刪除了無關本模塊的文件。調整文件目錄結構是通過一般的文件操作完成的,為了這個目的,首先應做一份帶有工作空間的克隆。

    > git clone module3.git module3
    

    將源代碼目錄 src/module3 重命名為 src , 測試代碼目錄 test/module3 重命名為 test

    > cd module3
    > mv src/module3 module3
    > rmdir src
    > mv module3 src
    > mv test/module3 module3
    > rmdir test
    > mv module3 test
    

    接下來,修改操作通常是借助于commit 命令,再通過 push 上傳到干凈的版本庫中。

    > git add --all
    > git commit -m "Directory structure adapted"
    > git push ,
    

    如果版本庫中有多個分支,那文件操作要在各個分支上依次完成。 .
    通常沒有必要保留主項目所有的分支。新的版本庫有新的分周期,舊分支通常沒有意義。

  • 第6步:在主項目中刪除已被拆分出來的模塊目錄
    當拆分出的模塊已遷移到新的版本庫中,下一步就是讓主項目來做拆分后的調整。刪除 無用的源代碼目src/module3 和測試目錄 test/module3。這里的調整主要是在主版本庫中的一些普通的文件操作。

    如果項目中有多個分支需要集成這一個改變,那也需要分別進行調整。cherry-pick 命令可以用作將變化調整部署到不同的分支。


3.2 將拆分出的模塊作為外部版本庫集成

經過前面一系列操作,現在已經擁有兩個版本庫了,通常原主項目仍需引用拆分后的模塊,所以需要集成操作。
集成操作嚴格依賴于開發平臺。例如在 Java Maven項目中,可以將拆分出的模塊項目獨 立創建編譯,并將結果保存在 Maven 項目中,在主項目中將其定義為依賴條件,在創建編譯主項目的過程中充 Maven 中獲得模塊項目。

如果使用 Git 來執行集成操作,那就需要用到子模塊 (submodule) 。 有了子模塊, 一個Git版本庫就可以鏈接到另外一個 Git版本庫了。

在上述示例中,模塊3 (module3) 的版本庫被鏈接到了主項目的extern/module3 文件目錄下。首先從主項目版本庫的一個克隆版開始操作。選定項目的根目錄,使用 submodule add 命令加入子模塊,該命令有兩個參數,第一個是模塊版本庫的路徑或 URL, 第二個參數是在主項目中即將鏈接的路徑。

>git submodule add /global-path-to/module3.git extern/module3

submodule add 命令會在特定的目錄下創建一個模塊版本庫的克隆,這個克隆會在主版本庫中作為外部引用。
文件目錄 extern/module3 指向外部版本庫的最新一次提交 (HEAD) 。
截至目前,子模塊只能在工作區中可見,需要只用 commit 命令提交使修改作用于整個版本庫。

>git add -all
>git commit -m "Modul3 added"

可以使用 push 命令將添加子模塊鏈接捷徑的修改推送到中央版本庫。


4?? 替代解決方案

  • 何不采用一個全新的版本庫
    有另外一種可以考慮的替換方案是簡單地為模塊創建一個新版本庫。那么,新版本庫中就沒有原模塊的歷史記錄了,但是原始版本庫中仍然有模塊的舊版本信息。如果這種缺陷可以被接受,那這種方案在實現上顯得最為簡單。

  • 為什么不采用 --subdirectory-filter 選項
    使用 filter-branch 命令和 -index-filter 參數可以實現將提交中的文件刪除。
    filter-branch 命令的 --subdirectory-filter 參數可以指定將排除某一文件夾之外的文件全部刪除,還可以在刪除指定的文件夾后改變項目的根目錄節點。

    只要模塊全部獨立存儲在一個文件目錄下,那么這個命令就可以較方便地用來創建模塊版本庫。在上文示例中,模塊文件被分散在兩個目錄下,因此不能適用這樣的操作。

    即使模塊中的文件所屬文件目錄被遷移或者被改名, subdirectory-filter 仍然可以保留部分歷史信息。



? 溫習回顧上一篇(點擊跳轉)
《【Git教程】(十七)發行版交付 — 概述及使用要求,執行過程及其實現,替代解決方案 ~》

? 繼續閱讀下一篇(點擊跳轉)
《》

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13241.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13241.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13241.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#實現各種Hash計算

C#實現各種Hash計算 文章目錄 C#實現各種Hash計算涉及框架及庫目前支持可計算的類型核心代碼完整可運行代碼 BCrypt總結 涉及框架及庫 自己在NuGet管理器里面安裝即可 BouncyCastle.Cryptography:是加密算法和協議的.NET實現。 目前支持可計算的類型 BLAKE2B_16…

如何在Idea離線情況下安裝vue.js插件

親踐有效,步驟如下: 1. 互聯網環境登陸vue.js官網(Vue.js - IntelliJ IDEs Plugin | Marketplace)。 2. 然后先確定你的IDEA的版本:在你IDEA的安裝文件中找到product-info.json,里面的buildNumber記錄著你IDEA的精確版本號,根據…

【Entity Framework】EF中SaveChanges如何使用

【Entity Framework】EF中SaveChanges如何使用 文章目錄 【Entity Framework】EF中SaveChanges如何使用一、概述二、更改跟蹤和SaveChanges三、SaveChanges優勢四、使用SaveChanges添加數據五、使用SaveChanges更新數據六、使用SaveChanges刪除數據七、單個SaveChanges中的多個…

roscore啟動報錯的解決方法【將環境變量配置于最后】

今天在啟動rviz時發生一個很奇怪的報錯: rviz: error while loading shared libraries: librviz.so: cannot open shared object file: No such file or directory 我感覺很納悶!再試著啟動一下roscore,發現如下報錯: [rosout-1…

[muduo網絡庫]——使用muduo庫搭建Echo服務器(剖析muduo網絡庫核心部分、設計思想)

在此之前,我們對于muduo庫的每一類幾乎都進行了逐行的分析,但是一個網絡庫的每個模塊之間總是有千絲萬縷的關系,所以可能有的地方還是有分析的不到位,所以從這一篇開始,我們從muduo的簡單使用----搭建一個Echo服務器&a…

Python爬蟲從入門到精通:一篇涵蓋所有細節的高質量教程

目錄 第一部分:Python爬蟲基礎 1.1 爬蟲原理 1.2 Python爬蟲常用庫 1.3 爬蟲實戰案例 1.4 注意事項 第二部分:爬蟲進階技巧 2.1 處理動態加載的內容 2.2 登錄認證 2.3 分布式爬取 2.4 反爬蟲策略 第三部分:爬蟲實戰項目 3.1 豆瓣…

【C語言】指針(二)

目錄 一、傳值調用和傳址調用 二、數組名的理解 三、通過指針訪問數組 四、一維數組傳參的本質 五、指針數組 六、指針數組模擬實現二維數組 一、傳值調用和傳址調用 指針可以用在哪里呢&#xff1f;我們看下面一段代碼&#xff1a; #include <stdio.h>void Swap(i…

基于Spring封裝一個websocket工具類使用事件發布進行解耦和管理

最近工作中&#xff0c;需要將原先的Http請求換成WebSocket&#xff0c;故此需要使用到WebSocket與前端交互。故此這邊需要研究一下WebSocket到底有何優點和不可替代性&#xff1a; WebSocket優點&#xff1a; WebSocket 協議提供了一種在客戶端和服務器之間進行全雙工通信的…

如何在MATALB中調用libMR

? 因為個人項目原因,我曾將參考OpenMax源碼GitHub - abhijitbendale/OSDN: Code and data for the research paper “Towards Open Set Deep Networks” A Bendale, T Boult, CVPR 2016將其轉換到MATLAB使用。 OpenMax 使用極值理論實現對開放集的篩選,在計算得分時需要用l…

異地組網群暉不能訪問怎么辦?

在日常使用群暉網絡儲存設備時&#xff0c;我們常常會遇到無法訪問的情況&#xff0c;特別是在異地組網時。這個問題很常見&#xff0c;但也很讓人困擾。本文將針對異地組網群暉無法訪問的問題進行詳細解答和分析。 異地組網的問題 在異地組網中&#xff0c;群暉設備無法訪問的…

Unity | Spine動畫動態加載

一、準備工作 Spine插件及基本知識可查看這篇文章&#xff1a;Unity | Spine動畫記錄-CSDN博客 二、Spine資源動態加載 1.官方說明 官方文檔指出不建議這種操作。但spine-unity API允許在運行時從SkeletonDataAsset或甚至直接從三個導出的資產實例化SkeletonAnimation和Skel…

被耽誤了的發明家

高三的某一天&#xff0c;數學焦老師在黑板上推公式&#xff0c;突然花屁股&#xff08;見另一篇博文《數學老師們》&#xff09;上出現了一個光圈。我心里一樂&#xff0c;有人在玩鏡子。本來大家對于焦老師的花屁股已經司空見慣了&#xff0c;可以不受干擾地聽課&#xff0c;…

HNU-算法設計與分析-作業3

第三次作業【動態規劃】 文章目錄 第三次作業【動態規劃】<1>算法實現題 3-1 獨立任務最優解問題<2>算法實現題 3-4 數字三角形問題<3>算法實現題 3-8 最小m段和問題<4>算法實現題 3-25 m處理器問題 <1>算法實現題 3-1 獨立任務最優解問題 ▲問…

postgresql安裝及性能測試

postgresql安裝及性能測試 1. Postgresql介紹 Postgresql是一款功能強大的開源對象關系型數據庫管理系統&#xff08;ORDBMS&#xff09;&#xff0c;以其穩定性、擴展性和標準的SQL支持而聞名。它支持復雜查詢、外鍵、觸發器、視圖、事務完整性、多版本并發控制&#xff08;MV…

Linux(七) 動靜態庫

目錄 一、動靜態庫的概念 二、靜態庫的打包與使用 2.1 靜態庫的打包 2.2 靜態庫的使用 三、動態庫的打包與使用 3.1 動態庫的打包 3.2 動態庫的使用 3.3 運行動態庫的四種方法 四、總makefile 一、動靜態庫的概念 靜態庫&#xff1a; Linux下&#xff0c;以.a為后綴的…

Python專題:十五、JSON數據格式

Python的數據處理&#xff1a;JOSN 計算機的主要工作&#xff1a;處理數據 最容易處理的數據就是結構化數據 非結構化數據&#xff1a;視頻&#xff0c;文件等 近些年的大數據、數據挖掘就是對互聯網中的各種非結構化的數據的分析和處理 半結構化數據 明確的結構屬性&…

陪診服務運用預約小程序的效果是什么

在中高型城市里&#xff0c;陪診師近些年也很有熱度&#xff0c;已經衍生成為一個新的小眾行業&#xff0c;不同醫院/不同科目等其它情況針對不同群體往往很難完善&#xff0c;比如部分老年人腿腳不便、不認識字、外地語言難以溝通等&#xff0c;陪診師的作用就尤為凸顯. 對相…

[Bootloader][uboot]code總結

文章目錄 1、U_BOOT_DRIVER2、DM框架dm_scan_platdatadm_extended_scan_fdt 1、U_BOOT_DRIVER 使用這個宏可以定義一個驅動實例&#xff0c;宏定義是 其中使用的struct driver結構體 使用的ll_entry_declare宏定義是 歸結為 2、DM框架 1、 DM框架 DM模型抽象出了以下四個…

16.投影矩陣,最小二乘

文章目錄 1. 投影矩陣1.1 投影矩陣P1.2 投影向量 1. 投影矩陣 1.1 投影矩陣P 根據上節知識&#xff0c;我們知道當我們在解 A X b AXb AXb的時候&#xff0c;發現當向量b不在矩陣A的列空間的時候&#xff0c;我們希望的是通過投影&#xff0c;將向量b投影到矩陣A的列空間中&…

ModuleNotFoundError: No module named ‘sklearn‘

ModuleNotFoundError: No module named sklearn 解決辦法&#xff1a; pip install scikit-learn