Google Git-Repo (Android)多倉庫項目管理

原文:Google Git-Repo (Android)多倉庫項目管理

前言

如果不是 Android dev 可以忽略標題的 Android。

項目模塊化/組件化之后各模塊也作為獨立的 Git 倉庫從主項目里剝離了出去,各模塊各自管理自己的版本。正常 Android 項目,各剝離出去的子模塊倉庫則通過 Maven 倉庫 來管理,然后和引入第三方庫一樣依賴到主項目里。這種狀態(tài)下的項目迭代帶來的問題會是:需要頻繁發(fā)布子模塊的 版本并需要把修改的版本提交 Merge Request 到主模塊里茴丰,尤其像我們一周一版的快速迭代的情況下,問題尤為凸顯天吓。此外還有個問題就是 Debug/斷點 會變得不太方便贿肩,因為可能子模塊的源碼并未發(fā)到 Maven 上。

在上面所說的狀態(tài)下工作了一段時間后龄寞,需要找到個方案來解決這個問題汰规。遂嘗試在多倉庫管理的方向上嘗試。支持 Git 多倉庫的管理工具也有好幾個:git-repo物邑、git-submodule溜哮、gitslavegit-subtree色解,看了一番茂嗓,除了 git-repo 外的幾個要么 子模塊需要手動指定本地倉庫路徑、要么 主倉庫與子倉庫會產(chǎn)生污染 且操作不夠簡便化科阎。所以最終就采用了 Google 的 Git-repo(Repo)

Git-repo

Repo 是對 Git 構(gòu)成補充的多(可以巨多的那種)代碼庫管理工具在抛,簡單說就是使用 Python 在 Git 基礎(chǔ)上開發(fā)的一系列腳本命令。當前整個 Android 項目(AOSP)就是通過 repo 來管理萧恕,最新版本的倉庫大約 七百多個刚梭,可見 Repo 在多倉庫的代碼管理和版本管理上是可以支撐現(xiàn)有我們的項目的。接下來描述分析下遷移使用 Repo 的過程和一些解釋票唆。

環(huán)境準備

準備好梯子朴读,把 repo 裝到系統(tǒng)里:

mkdir ~/bin
PATH=~/bin:$PATH  # 自己加到 ~/.zshrc or ~/.bashrc or /etc/profile 里 

curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

# 最后 source 下環(huán)境變量

然后就可以操作項目了,如初始化 AOSP 項目:

repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1

Manifest

Repo 管理的核心就在于 Manifest走趋,每個采用 repo 管理的復雜多倉庫項目都需要一個對應的 manifest 倉庫衅金,如 AOSP 的 manifest ,此倉庫用來存儲所有子倉庫的配置信息簿煌,repo 也是讀取此倉庫的配置文件來進行管理操作氮唯。里面的配置就是 xml 定義的結(jié)構(gòu),一般有兩個主要的配置:子倉庫用到的倉庫地址(remote)姨伟、子倉庫詳細配置信息(project)惩琉。舉例如下:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote  name="remote1"
           alias="origin"
           fetch=".."
           review="https://android-review.googlesource.com/" />

  <remote  name="remote2"
           alias="origin"
           fetch="git@github.com:group2/"
           review="https://android-review2.googlesource.com/" />         

  <default revision="master"
           remote="remote1"
           sync-j="4" />

  <project path="build/make" name="platform/build" groups="pdk" >
    <copyfile src="core/root.mk" dest="Makefile" />
    <linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
  </project>
  <project path="build/blueprint" name="platform/build/blueprint" groups="pdk,tradefed" revision="other_branch" remote="remote1"/>

<!-- ... -->

</manifest>

解釋下常用的各節(jié)點:

remote

遠程倉庫地址配置,可以多個夺荒。

  • name: 名字瞒渠,也用于子倉庫的 git remote 名稱(.git/config 里的 remote)
  • alias: 別名,可省略技扼,建議設(shè)為 origin伍玖, 設(shè)置了那么子倉庫的 git remote 即為此名,方便不同的 name 下可以最終設(shè)置生成相同的 remote 名稱
  • fetch: 倉庫地址前綴剿吻,即 project 的倉庫地址為: remote.fetch + project.name
  • pushurl: 一般可省略窍箍,省略了則直接用 fetch
  • review: Gerrit code review 的地址,如果沒有用 Gerrit 則不需要配置(也就不能用 repo upload 命令了)
  • revision: 使用此 remote 的默認分支

這里的 fetch 遇到個坑丽旅,git@github.com:group2/ 這樣 git scheme 開頭的地址會有問題(ssh/https 的正常)椰棘,最終子倉庫在本地的 remote 地址一直是 manifest 的地址拼上 fetch 再加 project 的 name (manifest.git_path + remote.fetch + project.name)。最終發(fā)現(xiàn)是 git-repo 里的代碼 manifest_xml.py 有問題魔招,需要 fix 下晰搀,簡單的把 78 行注釋掉,然后推到自己的倉庫办斑,指定下系統(tǒng)環(huán)境變量:

REPO_URL=your_fix_git-repo_git_url
# repo 腳本會使用此變量的地址

project

子項目倉庫配置外恕,可以多個。

  • path: repo sync 同步時乡翅,相對于根目錄的子倉庫文件夾路徑
  • name: 子倉庫的 git 倉庫名稱
  • group: 分組
  • revision: 使用的分支名
  • clone-depth: 倉庫同步 Git 的 depth
copyfile

project 的子節(jié)點屬性.

  • src: project 下的相對路徑
  • dest: 整個倉庫根路徑下的相對路徑
linkfile

project 的子節(jié)點屬性鳞疲,類似 copyfile,只是把復制文件變?yōu)閯?chuàng)建鏈接文件蠕蚜。

default

project 沒有設(shè)置屬性時會使用的默認配置尚洽,常用的是 remote 和 revision。

其他

其他現(xiàn)在暫時用的較少靶累,詳細完整的 manifest 格式說明請看官方文檔腺毫。
了解了 Repo 下的 Manifest 配置倉庫的概念后就可以根據(jù)自己的項目來創(chuàng)建了癣疟,Just do it!

local_manifest

local_manifest 簡單說就是一個比 repo init 時設(shè)置的 manifest 有更高優(yōu)先級的本地配置,一般用在不改動遠程 manifest 配置又想設(shè)置到本地的專屬配置時用得到潮酒。版本高一點的 repo 下睛挚,在工作根目錄新建配置文件即可: .repo/local_manifests/local_manifest.xml

有一點需要注意的是如果需要覆蓋主 manifest 文件已有 project 的配置那么需要先 remove-project 才行,不然會報錯:

fatal: duplicate path project_name in .repo/manifest.xml

fix :

<remove-project name="project_name" />
<!-- 再重寫 project 配置 -->
<project path="xxx" name="xxx" revision="xxxx" remote="xxxx"  />

Repo 命令

repo init -u yout_manifest_git_url 初始化了你的項目 repo 工作區(qū)后急黎,repo sync扎狱,你就可以進入正常的特性開發(fā)狀態(tài)了。那么我們以開發(fā)一個 feature 為例勃教,順序說明下需要使用到的常用命令淤击,也是我現(xiàn)在嘗試使用的 repo workflow 了。

repo init

初始化故源。

repo init -u your_project_git_url

其他常用可選參數(shù):

  • -b 選取的 manifest 倉庫分支污抬,默認 master
  • -m 選取的默認配置文件,默認 default.xml
  • --depth=1 git clone 的深度心软,一般如在 Jenkins 上打包時可用壕吹,加快代碼 clone 速度
  • --repo-url=URL 使用自定義的 git-repo 代碼,如前面說到的 fix 了 bug 的 git-repo
  • --no-repo-verify 不驗證 repo 的源碼删铃,如果自定義了 repo url 那么這個一般也加上

repo sync

初始化好一個 repo 工作目錄后下一步就是把代碼同步下來了:

repo sync

同步完成后就會在當前目錄下生成 manifest 里配置的各倉庫和其對應目錄耳贬。其他常用可選參數(shù):

  • -f 不阻斷同步,即一個 project 失敗會繼續(xù)下一個 project 同步
  • --force-sync 如果需要猎唁,強制覆蓋現(xiàn)有的 git 目錄指向不同的對象目錄咒劲。此操作可能會導致數(shù)據(jù)丟失
  • -d 把項目回退到 manifest 里配置的分支
  • -m 手動指定當前操作使用哪個 manifest 文件
  • -t 使用對應 tag 里的 manifest 文件

同步完后你就可以用你的 IDE 打開項目了。此時诫隅,你需要根據(jù)當前的子倉庫目錄配置腐魂,在項目里處理下子倉庫的依賴問題,比如 Android 項目逐纬,在 settting.gradle 里就需要根據(jù)此 repo 倉庫的項目目錄把子倉庫 include 進來蛔屹。

repo start

從 manifest 配置文件中指定的分支里,創(chuàng)建一個新的分支進行開發(fā)豁生,如:

repo start your_feature_branch_name --all | [project1 project2]

后續(xù)如果發(fā)現(xiàn)還改動到了其他模塊倉庫那么再 start 一個對應 project 的分支

Work in progress

開發(fā)過程中需要用到的常用命令:

  • repo status: 跟 git status 類似兔毒,會把當前 repo 工作區(qū)的狀態(tài)信息列出來
  • repo diff: 同理 git diff
  • repo forall <PROJECT_LIST> -c <COMMAND>: 在(所有)子倉庫下執(zhí)行命令,比如 repo 沒有類似 git stash 的命令甸箱,利用 forall 就可以實現(xiàn):repo forall -c git stash
  • repo prune: 刪除已經(jīng)合并分支
  • repo stage: 把文件添加到 index 表(暫存區(qū))中
  • repo manifest: 顯示當前使用的 manifest 信息內(nèi)容

repo upload

提交代碼到 Gerrit code review 中育叁,如果沒有使用 Gerrit,則可以跟之前那樣手動操作單個倉庫 push 或者使用 repo forall -c git push xxx

Other

其他更詳細的參考可以查看 Repo 命令參考資料

Workflow

上面一節(jié)介紹的 repo 命令的順序過程可以說就是一個常用的 repo 工作流程芍殖,AOSP 給的開發(fā)流程可以先看下:
開發(fā)

Git 和 Repo 快速參考表

那么根據(jù)上一節(jié)的介紹豪嗽,給出下當前嘗試使用的 repo-workflow 的圖示:

Git-repo workflow

具體到每個倉庫來說,主倉庫位置原有的 git workflow 不用變,各子倉庫新增 devbuild 分支,那么對應的合版打包與發(fā)版打包對應 Manifest 固定的分支配置就行柑贞,如果沒有項目刪減,那么合版與發(fā)版時的子模塊倉庫版本也是不用動的成榜。避免了頻繁的合版時,各模塊版本頻繁/繁瑣的修改合并蹦玫。

Jenkins

使用 Jenkins 的需要使用 repo 插件,也還算挺方便的刘绣,稍微由原來的 git 遷移到 repo 的配置就行樱溉。
配合 Jenkins 的自動化打包,加一些自動化的打包配置纬凤,如遠程參數(shù)化構(gòu)建福贞、自定義的 Gradle 打包插件等,如果需要在 Jenkins 上打 Feature 包的停士,那么在 Manifest 項目里可以不需要再新建 Feature 分支了挖帘。所以綜合來看,合版時的工作量減輕了不少~

End

參考:

AOSP 文檔
Git多項目管理
git-repo README

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恋技,一起剝皮案震驚了整個濱河市拇舀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜻底,老刑警劉巖骄崩,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異薄辅,居然都是意外死亡要拂,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門站楚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脱惰,“玉大人,你說我怎么就攤上這事窿春±唬” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵谁尸,是天一觀的道長舅踪。 經(jīng)常有香客問我,道長良蛮,這世上最難降的妖魔是什么抽碌? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上货徙,老公的妹妹穿的比我還像新娘左权。我一直安慰自己,他們只是感情好痴颊,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布赏迟。 她就那樣靜靜地躺著,像睡著了一般蠢棱。 火紅的嫁衣襯著肌膚如雪锌杀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天泻仙,我揣著相機與錄音糕再,去河邊找鬼。 笑死玉转,一個胖子當著我的面吹牛突想,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播究抓,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼猾担,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了刺下?” 一聲冷哼從身側(cè)響起绑嘹,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怠李,沒想到半個月后圾叼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡捺癞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年夷蚊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片髓介。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡惕鼓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出唐础,到底是詐尸還是另有隱情箱歧,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布一膨,位于F島的核電站呀邢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏豹绪。R本人自食惡果不足惜价淌,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝉衣,春花似錦括尸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啦膜,卻和暖如春有送,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背僧家。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工娶眷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人啸臀。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像烁落,于是被迫代替她去往敵國和親乘粒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 開發(fā)中我們經(jīng)常會遇到這樣的情況:項目越來越大伤塌,一些通用的模塊我們希望將他抽離出來作為單獨的項目灯萍,以便其他項目也可以...
    feil0n9wan9閱讀 19,885評論 0 24
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)每聪,斷路器旦棉,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 美國感恩節(jié)即將來臨,洛杉磯中餐館的感恩節(jié)火雞預訂生意越發(fā)火爆药薯,不少華人新移民表示绑洛,感恩節(jié)吃火雞已經(jīng)是過節(jié)必做的事...
    余溫殘閱讀 151評論 0 0
  • 第一回請圣旨雙仙結(jié)發(fā) 巍巍天門鎖風塵,秋水延綿入曉春童本。山間仙果七八樹真屯,村頭犬吠一兩聲。千年清修金剛體穷娱,萬載緣得結(jié)發(fā)...
    猴子豬閱讀 719評論 10 5
  • 大易無邊閱讀 192評論 1 2