git subtree使用說明

爲什麼要使用subtree

在實際的項目開發過程中,公共的代碼或者模塊是必定會出現的,爲了不重複寫相同的代碼;普遍的做法就是將其抽取成一個公共模塊,這個模塊由不同的使用者引用;作爲java工程師,可能會選擇將這一部分打包封裝成一個jar,並且將其推送到Maven的私有倉庫,各個使用者將其添加到pom文件即可;但是有沒有更好的方式呢?因爲使用這種方式,對使用者來說,並不是透明的,當前可能已經更新版本了,但是我作爲使用者並不知道當前已經更新了,知道更新了可能也不知道最新版本是多少,我還得通過諮詢模塊開發人員或者說到私有倉庫去查看才能知道,那有沒有更好的方式呢?
接下來,就一起探討一種更好的管理方式:git subtree,如果說你現在還不知道git是啥或者怎麼用?強力建議去學習一下。

什麼是git subtree?有啥優勢?

  • git subtree可以將一個倉庫作爲倉庫的子倉庫
  • 各個倉庫之前的版本管理是相對獨立的
  • 對於使用者來說,是透明的,可能使用者根本都不知道有子倉庫的存在;
  • 主子倉庫的分支同步,即你切換主項目分支的時候,關聯的子倉庫也會同步切換

缺點

  • 需要學習新的操作指令,git subtree有自己的一套指令
  • 指令的複雜度比較高,相比於常規的操作指令,其更加的複雜;
  • 子倉庫操作的時候,由於關聯了其他倉庫,因此指令的響應速度沒有單倉庫快
  • 子倉庫的分支管理比較麻煩

指令列表

git subtree add   --prefix=<prefix> <commit>
git subtree add   --prefix=<prefix> <repository> <ref>
git subtree pull  --prefix=<prefix> <repository> <ref>
git subtree push  --prefix=<prefix> <repository> <ref>
git subtree merge --prefix=<prefix> <commit>
git subtree split --prefix=<prefix> [OPTIONS] [<commit>]

幾條指令而已,再複雜也只有這麼幾條,所以相對於他的優點來說,上面說的缺點也就只是微乎其微了

操作說明


在碼雲上面創建了三個倉庫用於做測試:praent(主倉庫), childa、childb(子倉庫)

  • 引入子倉庫

    git remote add -f <倉庫別名> <倉庫地址>
    #如 git remote add -f childa https://gitee.com/pengfeilu/subtree-childa.git
    

    這條指令不是git subtree的指令,只是爲了方便後續的操作,把倉庫引入到當前項目作爲一個remote,並且給其取了個別名,後續的操作 childa = https://gitee.com/pengfeilu/subtree-childa.git


  • 添加子倉庫
    git subtree add --prefix=<prefix> <repository> <ref>
    #如: git subtree add --prefix=childa childa master --squash
    #等價於: git subtree add --prefix=childa https://gitee.com/pengfeilu/subtree-childa.git master --squash
    
  • 第一個參數 --prefix=modulea
    指明子倉庫放在父倉庫存放的路徑,--prefix可以使用大寫的-P簡寫;這裏是放在childa目錄,也允許設置多級目錄,如childa/a/b/c
  • 第二個參數 modulea
    子遠程倉庫地址,由於上面一個做了關聯,所以這裏直接使用的別名,直接使用遠端地址也是可以的
  • 第三個參數 master : 添加的子倉庫的分支名稱,這裏使用標籤或者commitId也是可以的
  • 第四個參數 --squash: 只將本次操作在主倉庫生成一條commit記錄,子倉庫的歷史記錄並不會合並進來,可以根據實際情況使用

  • 推送更新到子倉庫
    git subtree push  --prefix=<prefix> <repository> <ref>
    #如:git subtree push  --prefix=childa childa master
    #等價於: git subtree push  --prefix=childa https://gitee.com/pengfeilu/subtree-childa.git master
    

    參數說明等價於上面添加的參數


  • 更新子倉庫代碼
    git subtree pull  --prefix=<prefix> <repository> <ref>
    #如:git subtree pull  --prefix=childa childa master --squash
    #等價於: git subtree pull  --prefix=childa https://gitee.com/pengfeilu/subtree-childa.git master --squash
    
    測試:
    1. 子倉庫childa添加文件並上傳
    2. 主倉庫基於分支獲取最新的 childa的提交

  • 對已有的項目目錄進行拆分
    以上的操作是我們從一開始就考慮好那一部分是子倉庫,從一開始就將子倉庫定義好了,這種場景比如在RPC(thrift、grpc等)相關框架自動生成的代碼,那麼這個子倉庫就是用於保存自動生成的那部分代碼,而且從一開始就有了,客戶端和服務端直接引用就好了;但是業務開發,可能會出現做到一半,發現某一部分可以抽離出來作爲一個公共的子模塊,那該怎麼做呢?
    git subtree split --prefix=<prefix> [OPTIONS] [<commit>]
    
    如當前我的項目下有個文件夾myfile,我需要將其剝離成一個新的子項目childb
  1. 第一步,將myfile目錄剝離成一個新的分支
     git subtree split -P myfiles -b childb
    
  2. 在主項目的同級目錄創建一個用於保存這個分支的文件夾
    # 創建文件夾
    mkdir ../subtree-childb
    # 切到對應的文件夾
    cd ../subtree-childb/
    # 初始化成一個git倉庫
    git init
    
  3. 將剝離出來的分支併到當前目錄來
     # ../subtree-praent 爲主倉庫的路徑
     # childb 爲第一步剝離出來的分支名稱
     git pull ../subtree-praent childb
    
    
  4. 將新的倉庫關聯到遠端倉庫
    git remote add origin https://gitee.com/pengfeilu/subtree-childb.git
    
  5. 推送到遠端代碼
    git push -u origin  master
    

到此!git subtree的常規操作都覆蓋了,具體可以在實際使用中去體會!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章