本文須要有對git repo gerrit的基本使用,
這裏不說起過多的基本用法.html
建議至少把 第2章 git基礎 看一遍python
建議僅看repo gerrit相關的章節android
Android式多版本庫協同git
Gerrit代碼審覈服務器sql
Android版本庫衆多的緣由,主要緣由是版本庫太大以及Git不能部分檢出。
若是全部的東西都放在一個庫中,而某個開發團隊感興趣的可能就是某個驅動,
或者是某個應用,卻要下載如此龐大的版本庫,是有些說不過去。
git也有submodule供多個庫下載,但這功能使用不方便,
其侷限性和麻煩可參看
http://www.worldhello.net/got...服務器
若是是你,有什麼方案來管理這麼多的庫?網絡
Repo是Google開發的用於管理Android版本庫的一個工具。
Repo並非用於取代Git,是用Python對Git進行了必定的封裝,簡化了對多個Git版本庫的管理。
對於repo管理的任何一個版本庫,都仍是須要使用Git命令進行操做
<?xml version="1.0" encoding="UTF-8"?> <manifest> <remote name="aosp" fetch=".." /> <default revision="refs/tags/android-7.1.0_r4" remote="aosp" sync-j="4" /> <project path="build" name="platform/build" groups="pdk,tradefed" > <copyfile src="core/root.mk" dest="Makefile" /> </project> <project path="build/blueprint" name="platform/build/blueprint" groups="pdk,tradefed" /> ......
從上看出,repo用清單文件來管理, 其內容爲版本的地址,默認分支名,遠程庫和本地路徑對應關係。
一個project對應一個庫,path爲本地切出來的工做目錄的路徑,也就是咱們看到的代碼路徑,
name爲對應的遠程git庫的名字/路徑。
注意,通常說來,一套安卓代碼都由好幾百個庫組成,上面只截取了一部分。app
關於manifests更多的信息可查看你代碼根目錄的
.repo/repo/docs/manifest-format.txtssh
這裏只說下revision,ide
revision的值多是分支/tag/commitID等形式
生成的一個例子:
<project name="device/qcom/common" revision="3a83da1dff148dd709caac602693d3295bd0a18b" upstream="refs/heads/省略">
$repo init --help Usage: repo init [options] Options: ...... Manifest options: -u URL, --manifest-url=URL manifest repository location -b REVISION, --manifest-branch=REVISION manifest branch or revision -m NAME.xml, --manifest-name=NAME.xml initial manifest file --mirror create a replica of the remote repositories rather than a client working directory --reference=DIR location of mirror directory --depth=DEPTH create a shallow clone with given depth; see git clone ...... repo Version options: --repo-url=URL repo repository location --repo-branch=REVISION
repo init用法如上, 咱們通常下載code的方式爲
repo init -u xxx -b yyy -m zzz.xml repo sync -c
注意
repo init命令執行後主要乾了兩件事
對於第一步你們可能比較疑問,不是已經有個repo了嗎?爲何還在下載repo?
實際上,咱們執行的repo命令只是至關於個當函數,真正的執行命令(如repo sync)
都是.repo/repo/subcmds裏的,
該子命令都用python寫的, 因此當有須要,或者執行出錯時想查看源碼的話可在此目錄下查看.
讓咱們想個問題,假設你一套代碼有100G,
固然咱們這隻講repo自己提供的方法,
--reference 經過引用已下載的mirror或者代碼加快下載速度,經常使用使用場景:
具體操做爲
先經過
repo init .... --mirror
創建一個本地的鏡像,
而後下載代碼時引用這個鏡像
repo init .... --reference=鏡像路徑 repo sync -c
若是此時主服務器庫容量增長到120G,而你的鏡像沒更新,
那麼理論上新下載代碼只須要下載20G的數據,
N套代碼佔用的空間爲100G(鏡像的) + 20G*N (新代碼)
你們可用
du -sh .repo/
命令統計.
注意:
不用擔憂你用reference下的代碼和主服務器的不一樣步,
git會自動進行三方對比的,保證能獲取到-u 指定的地址裏的代碼是最新的.
graph TD; title(repo gerrit簡單工做流程); init(repo init/sync) --> start(repo start xxx --all); start --> gitmodify(單個庫的修改和git流程同樣); gitmodify --> upload(上傳到Gerrit repo upload/git push); upload --> review(審覈 +1 +2); review-- 經過 --> submit(Gerrit submit); review-- 不經過 --> gitmodify;
Change-Id由git commit時調用.git/hooks/commit-msg鉤子生成的,
gerrit靠該id來區分同一分支下是否爲同一個提交,
事實上,只要gerrit未submit,能夠在本地git commit XX --amend修正提交後,
能夠再次提交,成爲新的patchset,但提交號不變.
repo upload時默認是用配置的郵箱前綴作爲push的用戶名,
若是您的郵箱前綴和gerrit帳戶名不一致,須要作以下配置
$ cat ~/.gitconfig [review "您的地址"] username = 您的賬號名
該功能可能SCM用得多,用於實現批處理腳本.
此處只看下用法
$ ssh -p 端口號 用戶名@地址 gerrit Available commands of gerrit are: apropos Search in Gerrit documentation ban-commit Ban a commit from a project's repository create-account Create a new batch/role account create-branch Create a new branch create-group Create a new account group create-project Create a new project and associated Git repository flush-caches Flush some/all server caches from memory gc Run Git garbage collection gsql Administrative interface to active database ls-groups List groups visible to the caller ls-members List the members of a given group ls-projects List projects visible to the caller ls-user-refs List refs visible to a specific user plugin query Query the change database receive-pack Standard Git server side command for client side git push rename-group Rename an account group review Verify, approve and/or submit one or more patch sets set-account Change an account's settings set-members Modify members of specific group or number of groups set-project Change a project's settings set-project-parent Change the project permissions are inherited from set-reviewers Add or remove reviewers on a change show-caches Display current cache statistics show-connections Display active client SSH connections show-queue Display the background work queues stream-events Monitor events occurring in real time test-submit version Display gerrit version See 'gerrit COMMAND --help' for more information.
這個可看下git書箱學習下,工做中也用得多,提升效率.
-n -l參數解釋以下:
-l, --local-only only update working tree, don't fetch -n, --network-only fetch only, don't update working tree
其實repo sync = repo sync -n + repo sync -l
若是你只想獲取更新到.repo庫裏, 不更新本地代碼, 可加上 -n參數
若是你以前已經獲取了更新,只有一兩個庫更新出錯,
而你從新repo sync -c一次都得半小時,
那能夠先repo sync -l, 而後單獨的更新出錯的庫.
我通常更新都用命令
repo sync -c -f repo sync -c -l
備註:
再運行次加-l主要是更新時可能信息不少,中間有些出錯,
而我有不想慢慢看終端找出錯信息,因此乾脆再讓他更新下
本地工做目錄,這樣方便查找出錯信息.
試想一下這樣一個場景, 您的代碼下載自A服務器, 如今要往B服務器push代碼,該咋辦?
固然, 您可用git remote添加遠程信息,而後再用git push 新添加的遠程名 ...
我這裏講另外一個方法,就是pushInsteadOf,
eg:
vi ~/.gitconfig [url "testB_address"] pushInsteadOf = testA_address
即,咱們僅須要在gitconfig裏配置一下,
push的時候用B服務器的地址,替換A服務器的地址,
這樣咱們push的時候,代碼就提交到B服務器了.
同理,可用
pullInsteadOf 替換 pull時的地址
InsteadOfpush 替換 push和pull時的地址
BTW,對 ~/.gitconfig文件的修改,您也可用命令
eg: git config --global url.testB_address.insteadOf testA_address
有時候有些運行命令出錯了,可加--trace參數查看更多信息
(git的調試方法請查看progit一書)
eg:
repo --trace sync -c
新下載代碼後,分支處於no branch狀態,建議下載代碼後用
repo start 本地分支名 --all
建個分支,該分支名爲本地分支名,可任意取名
該分支僅用於和服務同步,更新代碼,要修改的話用repo start xx創建個新分支
否則你本地在修改,服務器也修改,會形成歷史記錄很亂,
有時致使編譯出來的代碼有啥隱含bug.
固然,您也可用
git pull --rebase