教你如何搭建android源代碼repo倉(cāng)庫(kù)
如果你的開(kāi)發(fā)是基于AOSP源碼來(lái)建倉(cāng),那么搭建repo服務(wù)器和部署自己的repo倉(cāng)庫(kù)就是非常必要的工作了。
現(xiàn)實(shí)中很多公司都是直接把AOSP源代碼放在一個(gè)git倉(cāng)庫(kù)中來(lái)管理,這樣做沒(méi)什么毛病。但是如果開(kāi)發(fā)團(tuán)隊(duì)人數(shù)較多,會(huì)存在一些明顯的弊端:
- AOSP源代碼一般的大小是20GB,編譯之后達(dá)到40GB以上。每次同步會(huì)很耗費(fèi)時(shí)間。
- AOSP源代碼文件數(shù)量將近70W個(gè),單個(gè)倉(cāng)庫(kù)的文件索引會(huì)很龐大,每次檢索非常耗時(shí)。
- AOSP和芯片平臺(tái)廠(chǎng)商(例如qcom、mtk、rockchip等)的原始代碼倉(cāng)庫(kù),一般是以repo倉(cāng)庫(kù)結(jié)構(gòu)提供的,而不是單個(gè)git倉(cāng)庫(kù)。改變倉(cāng)庫(kù)結(jié)構(gòu)之后,人工維護(hù)的工作量比較大。
AOSP源代碼結(jié)構(gòu)復(fù)雜龐大,除了本身的代碼模塊之外,還集成了五六百個(gè)第三方倉(cāng)庫(kù),這些倉(cāng)庫(kù)也會(huì)在不停的更新迭代。AOSP維護(hù)整個(gè)代碼倉(cāng)庫(kù)框架就需要保持足夠的靈活性,于是就引進(jìn)了repo腳本來(lái)批量管理git倉(cāng)庫(kù)。AOSP的源代碼切分的git倉(cāng)庫(kù)數(shù)量多達(dá)六七百多個(gè)。
如果我們想要跟上游平臺(tái)倉(cāng)庫(kù)保持一致的倉(cāng)庫(kù)結(jié)構(gòu),很方便快捷的同步代碼,而我們自己也能靈活的管理本地的擴(kuò)展倉(cāng)庫(kù),就需要搭建部署自己的repo倉(cāng)庫(kù)了。
在實(shí)際的團(tuán)隊(duì)開(kāi)發(fā)實(shí)踐中,代碼管理框架一般是gerrit+repo的組合形式。gerrit的安裝部署和權(quán)限管理等不是本文檔的內(nèi)容,請(qǐng)讀者搜索網(wǎng)絡(luò)材料來(lái)安裝部署。本文檔的主要內(nèi)容包括:
- 說(shuō)明repo倉(cāng)庫(kù)的管理策略。
- 如何建立清單倉(cāng)庫(kù)。
- 如何批量切分git倉(cāng)庫(kù)。
- repo倉(cāng)庫(kù)的操作使用。
本文檔的服務(wù)器操作系統(tǒng)是ubuntu18.04。
1 repo是如何管理倉(cāng)庫(kù)的?
1.1 repo如何工作的?
新的操作系統(tǒng)安裝包中已經(jīng)包含了repo命令程序,可以直接通過(guò)下面的命令安裝:
sudo apt-get install repo
# 查看repo版本
repo --version
<repo not installed>
repo launcher version 2.17
(from /usr/local/bin/repo)
git 2.34.1
Python 3.10.4 (main, Apr 2 2022, 09:04:19) [GCC 11.2.0]
OS Linux 5.15.0-39-generic (#42-Ubuntu SMP Thu Jun 9 23:42:32 UTC 2022)
CPU x86_64 (x86_64)
Bug reports: https://bugs.chromium.org/p/gerrit/issues/entry?template=Repo+tool+issue
安裝完畢,我們可以看到安裝的實(shí)際上是一個(gè)repo的引導(dǎo)器。它還不是完整的管理工具。
通過(guò)cat命令查看一下repo文件,實(shí)際上是一個(gè)python3腳本.
which repo /usr/local/bin/repo cat /usr/local/bin/repo ........
客戶(hù)端在同步倉(cāng)庫(kù)時(shí)一般用到的幾個(gè)命令序列:
# 初始化倉(cāng)庫(kù) repo init -u .... # 檢出代碼 repo sync -j16 # 建立本地分支 repo start <BRANCH> --all # 批量執(zhí)行g(shù)it命令 repo forall -c `GIT COMMAND`
我們以清華大學(xué)官網(wǎng)的AOSP代碼為例,操作一下repo的倉(cāng)庫(kù)同步。
# 設(shè)置一下REPO_URL。
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
mkdir -p ~/aosp
cd aosp
# 初始化倉(cāng)庫(kù)
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest
Downloading Repo source from https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/
remote: Enumerating objects: 7372, done.
remote: Counting objects: 100% (7372/7372), done.
remote: Compressing objects: 100% (3935/3935), done.
remote: Total 7372 (delta 4765), reused 5577 (delta 3363)
接收對(duì)象中: 100% (7372/7372), 3.27 MiB | 3.58 MiB/s, 完成.
處理 delta 中: 100% (4765/4765), 完成.
... A new version of repo (2.21) is available.
... You should upgrade soon:
cp /home/xxx/Documents/aosp/.repo/repo/repo /usr/local/bin/repo
Downloading manifest from https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest
remote: Enumerating objects: 98793, done.
remote: Counting objects: 100% (98793/98793), done.
remote: Compressing objects: 100% (39423/39423), done.
remote: Total 98793 (delta 38918), reused 98123 (delta 38532)
接收對(duì)象中: 100% (98793/98793), 25.23 MiB | 2.40 MiB/s, 完成.
處理 delta 中: 100% (38918/38918), 完成.
Your identity is: xxx <xxx@sina.com>
If you want to change this, please re-run 'repo init' with --config-name
Testing colorized output (for 'repo diff', 'repo status'):
black red green yellow blue magenta cyan white
bold dim ul reverse
Enable color display in this user account (y/N)? y
repo has been initialized in /home/xxx/Documents/aosp/
If this is not the directory in which you want to initialize repo, please run:
rm -r /home/yl/Documents/aosp//.repo
and try again.
repo init命令執(zhí)行完畢,實(shí)際上就是下載了一個(gè).repo目錄下(repo命令版本過(guò)時(shí),可以根據(jù)提示更新一下,也可以不用更新)。
我們看一下repo目錄內(nèi)容:
repo
├── manifests // 清單倉(cāng)庫(kù)
│?? ├── .git -> ../manifests.git/
│?? ├── default.xml // 真正的倉(cāng)庫(kù)清單文件
│?? ├── GLOBAL-PREUPLOAD.cfg
│?? └── OWNERS
├── manifests.git // 清單倉(cāng)庫(kù)git配置信息
│?? ├── branches
│?? ├── config
│?? ├── description
│?? ├── FETCH_HEAD
│?? ├── HEAD
│?? ├── hooks
│?? ├── index
│?? ├── info
│?? ├── logs
│?? ├── objects
│?? ├── packed-refs
│?? └── refs
├── manifest.xml // 清單文件,內(nèi)容包含default.xml文件
└── repo // repo工具腳本
├── color.py
├── command.py
├── git_trace2_event_log.py
├── hooks
├── hooks.py
├── repo
├── .........
└── wrapper.pyrepo init干了這幾件事情:
- 下載repo工具倉(cāng)庫(kù),其中包含了python腳本。在.repo/repo目錄下。
- 下載了manifests清單倉(cāng)庫(kù),在目錄.repo/manifests下,軟鏈接包含了.repo/manifests.git目錄。
- 下載了一個(gè)倉(cāng)庫(kù)清單文件manifests.xml,其中包含default.xml。
repo批量管理倉(cāng)庫(kù)的內(nèi)容就在default.xml中。我們看一下文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="aosp"
fetch=".."
review="https://android-review.googlesource.com/" />
<default revision="master"
remote="aosp"
sync-j="4" />
<manifest-server url="http://android-smartsync.corp.google.com/android.googlesource.com/manifestserver" />
<superproject name="platform/superproject" remote="aosp"/>
<contactinfo bugurl="go/repo-bug" />
<project path="build/make" name="platform/build" groups="pdk" >
<linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
<linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
<linkfile src="core" dest="build/core" />
<linkfile src="envsetup.sh" dest="build/envsetup.sh" />
<linkfile src="target" dest="build/target" />
<linkfile src="tools" dest="build/tools" />
</project>
<project path="build/bazel" name="platform/build/bazel" groups="pdk" >
<linkfile src="bazel.WORKSPACE" dest="WORKSPACE" />
<linkfile src="bazel.sh" dest="tools/bazel" />
<linkfile src="bazel.BUILD" dest="BUILD" />
</project>
<project path="build/bazel_common_rules" name="platform/build/bazel_common_rules" groups="pdk" />
<project path="build/blueprint" name="platform/build/blueprint" groups="pdk,tradefed" />
<project path="build/pesto" name="platform/build/pesto" groups="pdk" />
<project path="build/soong" name="platform/build/soong" groups="pdk,tradefed" >
<linkfile src="root.bp" dest="Android.bp" />
<linkfile src="bootstrap.bash" dest="bootstrap.bash" />
</project>
<project path="art" name="platform/art" groups="pdk" />
<project path="bionic" name="platform/bionic" groups="pdk" />
<project path="bootable/recovery" name="platform/bootable/recovery" groups="pdk" />
<project path="bootable/libbootloader" name="platform/bootable/libbootloader" groups="vts,pdk" />
<project path="device/common" name="device/common" groups="pdk-cw-fs,pdk" />
<project path="device/generic/arm64" name="device/generic/arm64" groups="pdk" />
<project path="device/generic/armv7-a-neon" name="device/generic/armv7-a-neon" groups="pdk" />
<project path="device/generic/art" name="device/generic/art" groups="pdk" />
......
<repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
<!--
Merge marker to make it easier for git to merge AOSP-only manifest
changes to a custom manifest. Please keep this marker here and
refrain from making changes on or below it.
-->
</manifest> 折疊
這個(gè)XML文件的語(yǔ)法,不是本文檔的內(nèi)容。簡(jiǎn)單說(shuō)明一下幾個(gè)關(guān)鍵的:
remote: 遠(yuǎn)程服務(wù)端repo倉(cāng)庫(kù)名稱(chēng)
project: 每個(gè)項(xiàng)目的git倉(cāng)庫(kù)
path: 客戶(hù)端git倉(cāng)庫(kù)路徑
name: 服務(wù)端git倉(cāng)庫(kù)名稱(chēng)
revision: 分支名稱(chēng)或者commit id
linkfile: 軟鏈接文件,src和dest表示源和目的。
copyfile: 文件拷貝,src和dest表示源和目的。
groups: 分組。
概括一下repo批量管理倉(cāng)庫(kù)的方式:
- repo init命令下載工具腳本倉(cāng)庫(kù)和清單倉(cāng)庫(kù)。
- repo sync命令根據(jù)清單文件中的配置,下載遠(yuǎn)程倉(cāng)庫(kù)二進(jìn)制文件。
- repo start檢出分支。
所以,repo倉(cāng)庫(kù)的管理核心就在manifest.git,而起關(guān)鍵作用的配置文件就是倉(cāng)庫(kù)清單文件xxx.xml,有多少個(gè)項(xiàng)目倉(cāng)庫(kù),就有對(duì)應(yīng)的xml清單文件。
1.2 搭建repo服務(wù)需要做哪些事情?
接著就是關(guān)鍵問(wèn)題:搭建repo服務(wù)器我們要做哪些事情?
簡(jiǎn)而言之:
- 部署通用的工具倉(cāng)庫(kù)git-repo.git。
- 部署自己的清單倉(cāng)庫(kù)manifests.git。
- 編寫(xiě)清單文件manifests.xml
- 批量創(chuàng)建工程子倉(cāng)庫(kù)和上傳源代碼。
2 部署工具倉(cāng)庫(kù)git-repo.git
實(shí)際上,如果你的網(wǎng)絡(luò)鏈接可以鏈接到外網(wǎng)的話(huà),工具倉(cāng)庫(kù)git-repo.git是不需要搭建部署的。
只需要通過(guò)REPO_URL這個(gè)環(huán)境變量來(lái)指定URL就可以自動(dòng)拉取git-repo.git倉(cāng)庫(kù)。
export REPO_URL=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/
常用的URL有這些:
## google地址,需要梯子。 https://gerrit.googlesource.com/git-repo ## 清華大學(xué)開(kāi)源軟件鏡像站 https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/ ## 其他可以自己網(wǎng)上搜索...
但是現(xiàn)實(shí)中,很多公司的外網(wǎng)是受限的,無(wú)法訪(fǎng)問(wèn)。這個(gè)時(shí)候就需要考慮搭建自己的工具倉(cāng)庫(kù)git-repo.git了。
這個(gè)倉(cāng)庫(kù)的搭建很簡(jiǎn)單,就是一個(gè)普通的git倉(cāng)庫(kù),但是涉及到GPG簽名的問(wèn)題就比較復(fù)雜。這個(gè)過(guò)程不是本文檔的內(nèi)容,可以搜索互聯(lián)網(wǎng)上的文檔資料。
3 部署清單倉(cāng)庫(kù)manifests.git
部署清單倉(cāng)庫(kù)的方式,跟普通的git倉(cāng)庫(kù)沒(méi)有什么差別。關(guān)鍵問(wèn)題在:
- 清單倉(cāng)庫(kù)如何管理多個(gè)項(xiàng)目倉(cāng)庫(kù)?
- 如何編寫(xiě)清單文件manifests.xml?
3.1 如何設(shè)計(jì)清單倉(cāng)庫(kù)及分支?
3.1.1 需要幾個(gè)倉(cāng)庫(kù)?
從服務(wù)器的角度來(lái)看,你的服務(wù)器上肯定會(huì)管理多個(gè)項(xiàng)目倉(cāng)庫(kù)(例如qcom8953,qcom8916,mtk6219,mtk2226,rk3399,rk3358等等),那我們管理這些倉(cāng)庫(kù)的方式可能有:
- 整個(gè)服務(wù)器只建立一份manifests.git倉(cāng)庫(kù),每個(gè)倉(cāng)庫(kù)下的不同的xml文件管理不同的項(xiàng)目倉(cāng)庫(kù)。例如qcom8953.xml,rk3399.xml等。
- 每個(gè)項(xiàng)目倉(cāng)庫(kù)建立一個(gè)對(duì)應(yīng)的清單倉(cāng)庫(kù),例如manifests-qcom8953.git、manifests-rk3399.git等,其中放置各項(xiàng)目倉(cāng)庫(kù)的清單文件xml。
這兩種方式都可以,取決于你的代碼管理策略。我一般在整個(gè)服務(wù)器上使用一個(gè)manifests.git倉(cāng)庫(kù),通過(guò)不同的xml文件來(lái)管理所有的項(xiàng)目倉(cāng)庫(kù)。服務(wù)器端項(xiàng)目倉(cāng)庫(kù)的目錄結(jié)構(gòu)設(shè)計(jì)如下:
aosp
├── manifests.git // 清單倉(cāng)庫(kù)
│ ├── qcom8953.xml
│ ├── rk3399.xml
│ ├── rk3358.xml
│ └── mtk6226.xml
├── qcom/qcom8953 // 項(xiàng)目倉(cāng)庫(kù)
├── rockchip/rk3399 // 項(xiàng)目倉(cāng)庫(kù)
├── rockchip/rk3358 // 項(xiàng)目倉(cāng)庫(kù)
└── mtk/mtk6226 // 項(xiàng)目倉(cāng)庫(kù)
3.1.2 需要幾個(gè)分支?
清單倉(cāng)庫(kù)本身就是一個(gè)普通的git倉(cāng)庫(kù),他也是有分支的。同一個(gè)配置文件,例如qcom8953.xml,他也可以切分出不同的分支,來(lái)管理不同的項(xiàng)目倉(cāng)庫(kù)版本。
清單倉(cāng)庫(kù)的分支,跟項(xiàng)目倉(cāng)庫(kù)的分支沒(méi)有直接的關(guān)聯(lián)關(guān)系。但是在實(shí)踐操作中,我們一般會(huì)在清單倉(cāng)庫(kù)中建立項(xiàng)目倉(cāng)庫(kù)對(duì)應(yīng)的分支,方便管理映射。例如qcom8953項(xiàng)目倉(cāng)庫(kù),它有4個(gè)分支master、develop、test和release,那么我們的manifests.git也可以建立四個(gè)分支,跟項(xiàng)目倉(cāng)庫(kù)對(duì)應(yīng)起來(lái)。
我這里建立兩個(gè)分支:master和release。后面會(huì)按照這兩個(gè)分支來(lái)操作。
我們先看一下repo init命令的常用參數(shù):
repo init --help
Usage: repo init [options] [-u] url
Options:
Manifest options:
-u URL, --manifest-url=URL
manifest repository location
-b REVISION, --manifest-branch=REVISION
manifest branch or revision (use HEAD for default)
-m NAME.xml, --manifest-name=NAME.xml
initial manifest file
repo Version options:
--repo-url=URL repo repository location ($REPO_URL)
--repo-rev=REV repo branch or revision ($REPO_REV)
--no-repo-verify do not verify repo source code
Other options:
--config-name Always prompt for name/e-mail一般來(lái)說(shuō),-b的默認(rèn)值是master,-m的默認(rèn)值是manifests.xml。如果我們想要使用不同的默認(rèn)的清單文件,就需要在編寫(xiě)服務(wù)端清單文件和repo init參數(shù)時(shí)需要配合使用。
我這里全部使用默認(rèn)值。在aosp源碼的mannifests.xml中則體現(xiàn)在這幾個(gè)項(xiàng)上:
<remote name="aosp"
fetch=".."
review="https://android-review.googlesource.com/" />
<default revision="master" ## 遠(yuǎn)程默認(rèn)分支
remote="aosp" ## 遠(yuǎn)程默認(rèn)倉(cāng)庫(kù),就是remote標(biāo)簽中的name="aosp"
sync-j="4" />3.2 如何編寫(xiě)清單文件?
編寫(xiě)清單文件,肯定不可能全部手寫(xiě),需要拿到一份原始的manifests.xml文件。這份文件需要你從你的源頭代碼repo倉(cāng)庫(kù)中獲取是最好的。
我這里就以qcom的AOSP源碼為例,修改出我自己的倉(cāng)庫(kù)qcom8953.xml。
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<!--
remote: 服務(wù)器遠(yuǎn)程倉(cāng)庫(kù)的信息。
name: 遠(yuǎn)程manifest倉(cāng)庫(kù)名稱(chēng),一般默認(rèn)為origin
fetch: 倉(cāng)庫(kù)url。如果設(shè)置為"."(注意是一個(gè)點(diǎn)), 就表示在repo init -u url中配置。
review: 評(píng)審系統(tǒng)網(wǎng)址。如果提交代碼,就會(huì)進(jìn)入這個(gè)評(píng)審系統(tǒng)。
-->
<remote name="origin" fetch="." review="gerrit.your_domain.com" />
<!--
default: 這個(gè)repo倉(cāng)庫(kù)的默認(rèn)屬性。
revision: 默認(rèn)的工程代碼倉(cāng)庫(kù)分支,可以修改這里來(lái)指向不同的分支。
remote: 遠(yuǎn)程倉(cāng)庫(kù)的名稱(chēng)。這里跟<remote>標(biāo)簽是對(duì)應(yīng)的,當(dāng)然還可以指向其他倉(cāng)庫(kù)的remote。
-->
<default revision="master" remote="origin"/>
<!--
project: 每個(gè)倉(cāng)庫(kù)就是一個(gè)project
path: 客戶(hù)端同步到本地后的路徑名稱(chēng)。
name: 服務(wù)器端git倉(cāng)庫(kù)名稱(chēng),注意帶了路徑。
-->
<project path="build" name="build" />
<project path="device" name="device" />
<project path="frameworks/base" name="frameworks/base" />
<!--
重要說(shuō)明:
這里的build目錄和其下的三個(gè)子目錄:blueprint, kati, soong是嵌套的git倉(cāng)庫(kù)結(jié)構(gòu)!
這種嵌套的git倉(cāng)庫(kù)。有一個(gè)非常重要的控制文件:.gitignore.
父級(jí)目錄那種一定存在一個(gè).gitignore文件,其中包含了嵌套的子級(jí)倉(cāng)庫(kù)路徑。
-->
<project path="build" name="build">
<!-- copyfile: 將build/core/root.mk拷貝為Makefile。其中帶有相對(duì)路徑 -->
<copyfile src="core/root.mk" dst="Makefile" />
</project>
<project path="build/blueprint" name="build/blueprint" />
<project path="build/kati" name="build/kati" />
<project path="build/soong" name="build/soong">
<!-- linkfile: 建立一個(gè)軟鏈接Android.bp指向build/soong/root.bp -->
<linkfile src="root.bp" dest="Android.bp" />
<linkfile src="bootstrap.bash" dest="bootstrap.bash" />
</project>
<!-- 更多倉(cāng)庫(kù)信息 ...... -->
</manifest>
3.3 創(chuàng)建清單倉(cāng)庫(kù)manifests.git
創(chuàng)建清單倉(cāng)庫(kù)可以有兩種方式:
- gerrit系統(tǒng)的web頁(yè)面創(chuàng)建。這種方式適合創(chuàng)建少量的倉(cāng)庫(kù),簡(jiǎn)單快捷。
- gerrit命令創(chuàng)建。這種方式適合批量創(chuàng)建大量的倉(cāng)庫(kù),特別是AOSP倉(cāng)庫(kù)。
第一種方式比較簡(jiǎn)單,在WEB頁(yè)面上操作就可以,沒(méi)有什么特別的。
重點(diǎn)介紹第二種命令行方式。
ssh -p 29418 <USERNAME>@<GERRIT_IP_ADDRESS> gerrit create-project aosp/manifests.git
創(chuàng)建完畢,在gerrit頁(yè)面上也可以看到這個(gè)manifests.git倉(cāng)庫(kù)。管理員可以在頁(yè)面上創(chuàng)建兩個(gè)分支:master,release。
客戶(hù)端按照正常的git操作操作:
## 克隆代碼 git clone .../manifests.git ## 提交清單文件qcom8953.xml git add qcom8953.xml git commit -m "add qcom8953.xml" git push
這樣我們就建立了一個(gè)manifests.git倉(cāng)庫(kù),并上傳了一個(gè)清單文件qcom8953.xml。
下一步就是如何創(chuàng)建項(xiàng)目倉(cāng)庫(kù)了。
4 批量創(chuàng)建工程子倉(cāng)庫(kù)
初始工程倉(cāng)庫(kù)的源代碼,最好來(lái)自平臺(tái)廠(chǎng)商提供的帶了.repo和.git的完整repo倉(cāng)庫(kù),然后我們看看如何將這個(gè)倉(cāng)庫(kù)移植到我們自己的內(nèi)部倉(cāng)庫(kù)。
一般的操作步驟:
- gerrit命令批量創(chuàng)建服務(wù)端空倉(cāng)庫(kù)。
- 預(yù)處理本地repo倉(cāng)庫(kù)。
- 批量上傳源代碼。
4.1 批量創(chuàng)建服務(wù)端空倉(cāng)庫(kù)
批量創(chuàng)建子倉(cāng)庫(kù)只能通過(guò)gerrit命令行來(lái)進(jìn)行。
ssh -p 29418 <USERNAME>@<GERRIT_IP_ADDRESS> gerrit create-project aosp/qcom8953/xxx.git
這里我們需要知道的qcom8953倉(cāng)庫(kù)的所有倉(cāng)庫(kù)名字,然后通過(guò)腳本來(lái)批量創(chuàng)建,有兩種方式:
- 從xml腳本中提取倉(cāng)庫(kù)名稱(chēng)。
- 從原始源代碼倉(cāng)庫(kù)的.repo/manifets.git中的project.list文件中直接獲取。
不管哪種方式,都需要人工核對(duì)一下最終的倉(cāng)庫(kù)數(shù)量和名稱(chēng)是一致的。
我們最終需要一個(gè)倉(cāng)庫(kù)列表文件:project.list。文件內(nèi)容如下:
qcom/qcom8953/art qcom/qcom8953/bionic qcom/qcom8953/bootable/bootloader/edk2 qcom/qcom8953/bootable/recovery qcom/qcom8953/build/blueprint qcom/qcom8953/build/kati qcom/qcom8953/build qcom/qcom8953/build/soong qcom/qcom8953/cts qcom/qcom8953/dalvik qcom/qcom8953/developers/build qcom/qcom8953/developers/demos/JustForUs qcom/qcom8953/developers/samples/android qcom/qcom8953/development qcom/qcom8953/device/common qcom/qcom8953/device/generic/arm64 qcom/qcom8953/device/generic/armv7-a-neon ......
接下來(lái)我們可以使用下列命令來(lái)批量創(chuàng)建服務(wù)端空倉(cāng)庫(kù):
# 參數(shù)說(shuō)明
# --empty-commit: 強(qiáng)制參數(shù), 必須添加;
# -p YOUR-projects: 你的gerrit權(quán)限倉(cāng)庫(kù)。根據(jù)你的gerrit權(quán)限名稱(chēng)來(lái)確定。
# 其他參數(shù)就不要再添加了,畫(huà)蛇添足以后,多出很多問(wèn)題。
# 注意遠(yuǎn)程倉(cāng)庫(kù)名稱(chēng)前需要帶path前綴(qcom/qcom8953),防止服務(wù)器端倉(cāng)庫(kù)路徑混亂。
cat project.list | xargs -I {} ssh -p 29418 root@192.168.1.1 gerrit create-project "{}" --empty-commit -p YOUR-projects創(chuàng)建完畢,在gerrit頁(yè)面上就看到了幾百個(gè)git倉(cāng)庫(kù)。
4.2 預(yù)處理本地repo代碼
在上傳本地repo倉(cāng)庫(kù)之前,需要做幾個(gè)預(yù)處理動(dòng)作:
- 刪除本地工程中的.repo目錄。
- 核對(duì)本地倉(cāng)庫(kù).repo/manifests.git/xxxx.xml清單文件,根據(jù)文件內(nèi)容刪除掉本地代碼中的copyfile和linkfile的源。
- 修改本地每個(gè)倉(cāng)庫(kù)的git remote url路徑。這里你需要自己編寫(xiě)腳本來(lái)批量完成。
git remote set-url origin ssh://root@192.168.1.1:29418/xxx
4.3 上傳分支和代碼
倉(cāng)庫(kù)預(yù)處理完畢,你需要一一上傳各倉(cāng)庫(kù)的指定的分支和代碼到服務(wù)器倉(cāng)庫(kù)。
這里是通用的操作, 你也需要自己編寫(xiě)腳本進(jìn)行上傳同步:
git checkout master git push origin master:master git push -- tags
當(dāng)然,上傳之后,你最好在第三方測(cè)試驗(yàn)證一下,是不是有些.gitignore或者某些嵌套倉(cāng)庫(kù)存在問(wèn)題,需要手工進(jìn)行修復(fù)。
5 repo倉(cāng)庫(kù)使用簡(jiǎn)述
repo倉(cāng)庫(kù)搭建完畢,對(duì)客戶(hù)端來(lái)說(shuō),使用操作并不麻煩,使用常用的repo命令和git命令即可完成代碼提交。
# 初始化倉(cāng)庫(kù) repo init -u <remote manifests url> -n <manifests branch> -m <manifest NAME.xml> # 檢出代碼 repo sync -j16 # 建立本地分支 repo start <BRANCH> --all # 批量執(zhí)行g(shù)it命令 repo forall -c `GIT COMMAND`
單個(gè)倉(cāng)庫(kù)的代碼提交合并:
git add xxx git commit -m "xxxx" git push HEAD:refs/for/BRANCH
初次提交時(shí)可能會(huì)報(bào)告no change id的小錯(cuò)誤,百度搜索一下,很容易修復(fù)的。
到此這篇關(guān)于教你如何搭建android源代碼repo倉(cāng)庫(kù)的文章就介紹到這了,更多相關(guān)android源代碼repo倉(cāng)庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實(shí)現(xiàn)Service重啟的方法
這篇文章主要介紹了Android實(shí)現(xiàn)Service重啟的方法,涉及Android操作Service組件實(shí)現(xiàn)服務(wù)重啟的功能,需要的朋友可以參考下2015-05-05
Kotlin圖文并茂講解續(xù)體與續(xù)體攔截器和調(diào)度器
這篇文章主要介紹了Kotlin開(kāi)發(fā)中續(xù)體與續(xù)體攔截器和調(diào)度器的相關(guān)使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
詳解Android 硬布局item的高級(jí)寫(xiě)法
這篇文章主要介紹了詳解Android 硬布局item的高級(jí)寫(xiě)法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Android 創(chuàng)建依賴(lài)庫(kù)的方法(保姆級(jí)教程)
這篇文章主要介紹了Android 創(chuàng)建依賴(lài)庫(kù)的方法(保姆級(jí)教程),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
Android智能指針輕量級(jí)Light Pointer初識(shí)
這篇文章主要為大家介紹了Android智能指針輕量級(jí)Light Pointer初識(shí)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Android使用BroadcastReceiver實(shí)現(xiàn)手機(jī)開(kāi)機(jī)之后顯示畫(huà)面的功能
這篇文章主要介紹了Android使用BroadcastReceiver實(shí)現(xiàn)手機(jī)開(kāi)機(jī)之后顯示畫(huà)面的功能,結(jié)合實(shí)例形式分析了BroadcastReceiver的具體使用技巧及實(shí)現(xiàn)開(kāi)機(jī)畫(huà)面的相關(guān)功能代碼,需要的朋友可以參考下2016-01-01

