1. 程式人生 > 其它 >git subtree用法

git subtree用法

什麼時候需要 Subtree ?
1、當多個專案共用同一個模組程式碼,而這個模組程式碼跟著專案在快速更新的時候
2、把一部分程式碼遷移出去獨立為一個新的 git 倉庫,但又希望能夠保留這部分程式碼的歷史提交記錄。

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>]

git subtree用法

準備

我們先準備一個倉庫叫photoshop,一個倉庫叫libpng,然後我們希望把libpng作為photoshop的子倉庫。
photoshop的路徑為https://github.com/test/photoshop.git

,倉庫裡的檔案有:

photoshop
    |
    |-- photoshop.c
    |-- photoshop.h
    |-- main.c
    \-- README.md

libPNG的路徑為https://github.com/test/libpng.git,倉庫裡的檔案有:

libpng
    |
    |-- libpng.c
    |-- libpng.h
    \-- README.md

1. 第一次新增子目錄,建立與git專案的關聯(在父倉庫中新增子倉庫)

建立關聯總共有2條命令。

語法:git remote add -f <子倉庫名> <子倉庫地址>

解釋:其中-f意思是在新增遠端倉庫之後,立即執行fetch。

語法:git subtree add --prefix=<子目錄名> <子倉庫名> <分支> --squash

解釋:–squash意思是把subtree的改動合併成一次commit,這樣就不用拉取子專案完整的歷史記錄。–prefix之後的=等號也可以用空格。

示例:

$ git remote add -f libpng https://github.com/test/libpng.git
$ git subtree add --prefix=sub/libpng libpng master --squash

2. 從遠端倉庫更新子目錄

更新子目錄有2條命令。

語法:git fetch <遠端倉庫名> <分支>

語法:git subtree pull --prefix=<子目錄名> <遠端分支> <分支> --squash

示例:

$ git fetch libpng master
$ git subtree pull --prefix=sub/libpng https://github.com/test/libpng.git master --squash

3. 從子目錄push到遠端倉庫(確認你有寫許可權)

推送子目錄的變更有1條命令。

語法:git subtree push --prefix=<子目錄名> <遠端分支名> 分支

示例:

$ git subtree push --prefix=sub/libpng https://github.com/test/libpng.git master

4.git subtree split

每次執行 subtree 的 push 命令的時候,總會重新為子目錄生成新的提交。然而這造成了一些很麻煩的問題:

  1. 每個提交都需要重新計算,因此每次推送都需要把主倉庫所有的提交計算一遍,非常耗時;
  2. 每次 push 都是重新計算的,因此本地和遠端新倉庫的提交總是不一樣的,關鍵還沒有共同的父級,這導致 git 無法自動為我們解決衝突。

git subtree 提供了 split 命令就是為了解決這個問題

當使用了 split 命令後,git subtree 將確保對於相同歷史的分割始終是相同的提交號。

於是,當需要 push 的時候,git 將只計算 split 之後的新提交;並且下次 split 的時候,以前相同的歷史紀錄將得到相同的 git 提交號。

示例:

$ git subtree split --rejoin --prefix=sub/libpng  --branch new_libpng
$ git push zenjs new_libpng:master  

簡化git subtree命令

我們已經知道了git subtree 的命令的基本用法,但是上述幾個命令還是顯得有點複雜,特別是子倉庫的源倉庫地址,特別不方便記憶。
這裡我們把子倉庫的地址作為一個remote,方便記憶:

$ git remote add -f libpng https://github.com/test/libpng.git

然後可以這樣來使用git subtree命令:

$ git subtree add --prefix=sub/libpng libpng master --squash
$ git subtree pull --prefix=sub/libpng libpng master --squash
$ git subtree push --prefix=sub/libpng libpng master