Android 使用 Git 作為代碼管理工具,開發了 Gerrit 進行代碼審核以便更好的對代碼進行集中式管理,還開發了 Repo 命令行工具,對 Git 部分命令封裝,將百多個 Git 庫有效的進行組織。
1.1 清單庫文件介紹
一個清單庫可以包含多個清單文件和多個分支,每個清單文件和分支都有對應的版本。清單文件以xml格式組織的。舉個例子:
Ø remote元素,定義了名為korg的遠程版本庫,其庫的基址為git://172.16.1.31/
Ø default元素,設置各個項目默認遠程版本庫為korg,默認的的分支為gingerbread-exdroid-stable。當然各個項目(project元素)還可以定義自己的remote和revision覆蓋默認的配置
Ø project元素,用於定義一個項目,path屬性表示在工作區克隆的位置,name屬性表示該項目的遠程版本庫的相對路徑
Ø project元素的子元素copyfile,定義了項目克隆后的一個附件動作,從src拷貝文件到dest
1.2 下載repo代碼
$mkdir android2.3.4
$cd android2.3.4
$git clone git://172.16.1.31/repo.git
於是在android目錄下便有repo文件夾,里面包含了repo的源代碼,里面有個repo腳本,用它來執行repo指令。
在本地開發的用戶需要下載repo代碼,在172.16.1.7服務器上開發的用戶則不用下載repo代碼,因為已經把repo腳本添加到了環境變量,執行repo init 就會附加的下載repo代碼。
2 repo常用指令
備注:“*”表示新添加的指令
2.1 repo init (下載repo並克隆manifest)
Usage:
repo init –u URL [OPTIONS]
Options:
l -u:指定一個URL,其連接到一個maniest倉庫
l -m:在manifest倉庫中選擇一個xml文件
l -b:選擇一個maniest倉庫中的一個特殊的分支
命令repo init 要完成如下操作:
Ø 完成repo工具的完整下載,執行的repo腳本只是引導程序
Ø 克隆清單庫manifest.git (地址來自於-u 參數)
Ø 克隆的清單庫位於manifest.git中,克隆到本地.repo/manifests.清單.repo/manifest.xml只是符號鏈接,它指向.repo/manifests/default.xml
Ø 如果manifests中有多個xml文件,repo init 可以任意選擇其中一個,默認選擇是default.xml
Example:
repo init -u git://172.16.1.31/manifest.git
![]() |
在android2.3.4目錄下面出現了.repo文件夾。
repo init -u git://172.16.1.31/manifest.git –m android.xml
選擇的是android.xml里面的配置,.repo/manifest.xml便指向.repo/manifests/android.xml
2.2 repo sync(下載代碼)
Usage:
repo sync [<project>…]
用於參照清單文件.repo/manifest.xml克隆並同步版本庫。如果某個項目版本庫尚不存在,則執行repo sync 命令相當於執行git clone,如果項目版本庫已經存在,則相當於執行下面的兩條指令:
l git remote update
相當於對每一個remote源執行了fetch操作
l git rebase origin/branch
針對當前分支的跟蹤分支執行rebase操作。
Example:
repo sync
也可以選擇克隆其中的一個項目:
repo sync platform/build
2.3 repo start(創建並切換分支)
Usage:
repo start <newbranchname> [--all | <project>…]
剛克隆下來的代碼是沒有分支的,repo start實際是對git checkout –b 命令的封裝。為指定的項目或所有項目(若使用—all參數),以清單文件中為設定的分支,創建特性分支。這條指令與git checkout –b 還是有很大的區別的,git checkout –b 是在當前所在的分支的基礎上創建特性分支,而repo start是在清單文件設定分支的基礎上創建特性分支。
Example:
repo start stable --all
假設清單文件中設定的分支是gingerbread-exdroid-stable,那么執行以上指令就是對所有項目,在gingerbread-exdroid-stable的基礎上創建特性分支stable。
repo start stable platform/build platform/bionic
假設清單文件中設定的分支是gingerbread-exdroid-stable,那么執行以上指令就是對platform/build、platform/bionic項目,在gingerbread-exdroid-stable的基礎上創建特性分支stable
2.4 repo checkout(切換分支)
Usage:
repo checkout <branchname> [<project>…]
實際上是對git checkout 命令的封裝,但不能帶-b參數,所以不能用此命令來創建特性分支。
Example:
repo checkout crane-dev
repo checkout crane-dev platform/build platform/bionic
2.5 repo branches(查看分支)
Usage:
repo branches [<project>…]
Example:
repo branches
repo branches platform/build platform/bionic
2.6 repo diff(查看工作區文件差異)
Usage:
repo diff [<project>…]
實際是對git diff 命令的封裝,用於分別顯示各個項目工作區下的文件差異。
Example:
repo diff ---查看所有項目
repo diff platform/build platform/bionic ---只查看其中兩個項目
2.7 repo stage(把文件添加到index表中)
實際是對git add --interactive命令的封裝、用於挑選各個項目工作區中的改動以加入暫存區。
Usage:
repo stage -i [<project>…]
-i代表git add --interactive命令中的--interactive,給出個界面供用戶選擇
2.8 repo prune(刪除已經合並分支)
實際上是對git branch –d命令的封裝,該命令用於掃面項目的各個分支,並刪除已經合並的分支,用法如下:
repo prune [<project>…]
2.9 repo abandon(刪除指定分支)
實際上是對git branch –D 命令的封裝,用法如下:
repo abandon <branchname> [<project>…]
2.10 repo status(查看文件狀態)
實際上是對git diff-index、git diff-filse命令的封裝,同時顯示暫存區的狀態和本地文件修改的狀態
$repo/repo status platform/bionic
以上的實例輸出顯示了platform/bionic項目分支的修改狀態
Ø 每個小節的首行顯示羡慕名稱,以及所在分支的名稱
Ø 第一個字母表示暫存區的文件修改狀態
l -:沒有改變
l A:添加(不在HEAD中,在暫存區中)
l M:修改(在HEAD中,在暫存區中,內容不同)
l D:刪除(在HEAD中,不在暫存區)
l R:重命名(不在HEAD中,在暫存區,路徑修改)
l C:拷貝(不在HEAD中,在暫存區,從其他文件拷貝)
l T:文件狀態改變(在HEAD中,在暫存區,內容相同)
l U:未合並,需要沖突解決
Ø 第二個字母表示工作區文件的更改狀態
l -:新/未知(不在暫存區,在工作區)
l m:修改(在暫存區,在工作區,被修改)
l d:刪除(在暫存區,不在工作區)
Ø 兩個表示狀態的字母后面,顯示文件名信息。如果有文件重名還會顯示改變前后的文件名及文件的相似度
2.11 *repo remote(設置遠程倉庫)
Usage:
repo remote add <remotename> <url> [<project>…]
repo remote rm <remotename> [<project>…]
Example:
repo remote add org ssh://172.16.1.31/git_repo
這個指令是根據xml文件添加的遠程分支,方便於向服務器提交代碼,執行之后的build目錄下看到新的遠程分支org:
刪除遠程倉庫:
$repo remote rm org
2.12 *repo push
repo push org
這是新添加的指令,用於向服務器提交代碼,使用方法:
repo push <remotename> [--all |<project>…]
repo會自己查詢需要向服務器提交的項目並提示用戶。
2.13repo forall
Usage:
repo forall [<project>…] –c <command>
迭代器,可以在所有指定的項目中執行同一個shell指令
Options:
l -c:后面所帶的參數着是shell指令
l -p:在shell指令輸出之前列出項目名稱
l -v:列出執行shell指令輸出的錯誤信息
additional environment variables:
l REPO_PROJECT:指定項目的名稱
l REPO_PATH:指定項目在工作區的相對路徑
l REPO_REMOTE:指定項目遠程倉庫的名稱
l REPO_LREV:指定項目最后一次提交服務器倉庫對應的哈希值
l REPO_RREV:指定項目在克隆時的指定分支,manifest里的revision屬性
另外,如果-c后面所帶的shell指令中有上述環境變量,則需要用單引號把shell指令括起來。
3.13.1 添加的環境變量
repo forall –c ‘echo $REPO_PROJECT’
![]() |
$repo forall –c ‘echo $REPO_PATH’
3.13.2 merge(合並多個分支)
把所有項目多切換到master分支,執行以下指令將topic分支合並到master分支
repo forall –p –c git merge topic
3.13.3 tag(打標簽)
在所有項目下打標簽
repo forall –c git tag crane-stable-1.6
3.13.4 remote (設置遠程倉庫)
引用環境變量REPO_PROJECT添加遠程倉庫:
repo forall –c ‘git remote add korg ssh://xiong@172.16.31/$REPO_PROJECT.git’
刪除遠程倉庫:
repo forall –c git remote add korg
3.13.5 branch(創建特性分支)
repo forall –c git branch crane-dev
repo forall –c git checkout –b crane-dev
3 repo的額外命令集
3.1 repo grep
相當於對git grep 的封裝,用於在項目文件中進行內容查找
3.2 repo manifest
顯示manifest文件內容
Usage:
repo manifest –o android.xml
3.3 repo version
顯示repo的版本號
3.4 repo upload
repo upload相當於git push,但是又有很大的不同。它不是將版本庫改動推送到克隆時的遠程服務器,而是推送到代碼審核服務器(Gerrit軟件架設)的特殊引用上,使用SSH協議。代碼審核服務器會對推送的提交進行特殊處理,將新的提交顯示為一個待審核的修改集,並進入代碼審查流程,只有當審核通過后,才會合並到官方正式的版本庫中。
因為全志沒有代碼審核服務器,所以這條指令用不到。
Usage:
repo upload [--re --cc] {[<project>]… | --replace <project>}
Options:
l -h, --help:顯示幫助信息
l -t:發送本地分支名稱到Gerrit代碼審核服務器
l --replace:發送此分支的更新補丁集
l --re=REVIEWERS:要求指定的人員進行審核
l --cc=CC:同時發送通知到如下郵件地址
3.5 repo download
主要用於代碼審核者下載和評估貢獻者提交的修訂
Usage
repo download {project change [patchset]}…
3.6 repo selfupdate
用於repo自身的更新