repo工具介紹

轉自文章《Android內核開發:理解和掌握repo工具》和《Repo的理解和用法小結2》

1. repo是什麼?

repo是一種代碼版本管理工具,它是由一系列的Python腳本組成,封裝了一系列的Git命令,用來統一管理多個Git倉庫。

2. 爲什麼要用repo?

因爲Android源碼引用了很多開源項目,每一個子項目都是一個Git倉庫,每個Git倉庫都有很多分支版本,爲了方便統一管理各個子項目的Git倉庫,需要一個上層工具批量進行處理,因此repo誕生。

repo也會建立一個Git倉庫,用來記錄當前Android版本下各個子項目的Git倉庫分別處於哪一個分支,這個倉庫通常叫做:manifest倉庫。

3. 怎麼安裝repo?

官方的repo腳本下載方法:

curl http://commondatastorage.googleapis.com/git-repo-downloads/repo >  ./repo

由於官網被牆,目前可以使用的repo腳本下載方法如下(兩者選一):

$ git clone git://git.omapzoom.org/git-repo.git
$ git clone git://aosp.tuna.tsinghua.edu.cn/android/git-repo.git/  

$ cp git-repo/repo  ./repo

或者修改手頭已有的被牆的repo文件:

REPO_URL = ‘git://git.omapzoom.org/git-repo.git‘
REPO_URL = ‘git://aosp.tuna.tsinghua.edu.cn/android/git-repo‘ 

REPO_REV = ‘stable‘

當然,你也可以去我的GitHub下載這個repo文件,地址:

https://github.com/Jhuster/AOSP/blob/master/repo

4. 怎麼下載源碼?

上面說過,Android源碼分支其實由一個叫manifest倉庫來管理起來的,因此,下載源碼首先要clone這個manifest倉庫。這個倉庫裏面有一個XML文件,其實就是一個文件清單,列出了本代碼倉庫依賴哪些代碼,該去哪下載,分支是什麼。

一般用repo init命令來clone這個manifest倉庫,例如,如果要下載Android源碼,則方法如下:

$ repo init -u https://android.googlesource.com/platform/manifest

當然,上面的官網被牆了,因此,推薦如下鏡像(兩者選一):

$ repo init -u git://git.omapzoom.org/platform/manifest.git
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest

初始化完畢後,你會在本地的.repo文件夾中看到manifest倉庫的內容,這個文件夾中最重要的文件是manifest.xml(有的倉庫用的是default.xml,然後指向具體的xml),它就是上面說到的文件清單。

如果要選擇特定版本的Android源碼,或者在已下載的源碼基礎上切換到其他版本,則可以使用-b選項:

$ repo init -u git://git.omapzoom.org/platform/manifest.git -b android-5.0.2_r1 
$ repo init -u git://aosp.tuna.tsinghua.edu.cn/android/platform/manifest -b android-5.0.2_r1

然後使用 repo sync 命令進行同步即可下載好全部的Android源碼了。

5. manifest.xml文件清單的組成

上面提到了repo init需要初始化一個manifest倉庫,倉庫中含有一個很重要的manifest.xml文件清單,其實這個manifest.xml並不複雜的,它就是用XML文件的格式記錄了本項目依賴的各個Git倉庫的名稱、地址,以及分支等信息。常用的元素如下所示:

(1) manifest 最頂層的XML元素

(2) remote  設置遠程git服務器的屬性,如名稱、根URL地址等

(3) project 需要clone的Git倉庫,path表示本機路徑,name表示遠程版本庫的相對路徑

(4) copyfile 執行拷貝操作,把URL/$src地址的文件拷貝到./$dest

其實,如果不使用repo工具,也是可以對照manifest.xml文件清單直接使用“git clone”的方式一個project一個project的下載的,然後對每個project進行git checkout特定的分支。

7. 常用repo命令

這一塊網上文章很多,我就不詳細講解了,只列出常用命令。

(1) repo init   // 初始化repo倉庫

(2) repo sync   // 下載源碼

(3) repo start  // 創建分支

(4) repo checkout //切換分支

(5) repo branches //查看分支

(6) repo status   //查看文件狀態

下面對其中的命令進行詳細介紹:

1. repo init

repo init -u manifest_git_path -m manifest_file_name -b branch_name --repo-url=repo_url --no-repo-verify
  • 1

  在當前目錄下安裝 Repo。這會產生一個 .repo/ 目錄,目錄包括裝 Repo 源代碼和標準 Android 清單文件的 Git 倉庫。.repo/ 目錄還包括 manifest.xml,是一個在 .repo/manifests/ 目錄選擇清單的符號鏈接。

  選項:

-u: 指定Manifest庫的Git訪問路徑。 
-m: 指定要使用的Manifest文件。 
-b: 指定要使用Manifest倉庫中的某個特定分支。 
–repo-url: 指定要檢查repo是否有更新的遠端repoGit庫的訪問路徑。 
–no-repo-verify: 指定不檢查repo庫是否需要更新。

2. repo sync

repo sync [project_name]
  • 1

  用於參照清單文件克隆並同步版本庫。可以使用repo sync project_name的形式只克隆某個項目。。

  實現參照清單.repo/manifests.xml克隆並同步版本庫,如果版本庫不存在,則相當於執行

git clone
  • 1

  如果版本庫已經存在,則相當於執行

#對每個remote源進行fetch操作
git remote update
#針對當前分支的跟蹤分支進行rebase操作
git rebase/origin/branch
  • 1
  • 2
  • 3
  • 4

  選項:

-d:切換指定項目回到清單修正。如果該項目目前是一個主題分支那就有幫助,但清單修正是暫時需要。 
-s:同步到一個已知的構建 manifest-server 在當前清單指定的元素。 
-f:繼續同步其他項目,即使有項目同步失敗。

3. repo start

repo start <newbranchname> [--all|<project>...]
  • 1

  創建並切換分支。剛克隆下來的代碼是沒有分支的,repo start實際是對git checkout -b命令的封裝。 
  爲指定的項目或所有的項目(若使用-all),以清單文件中爲設定的分支,創建特定的分支。 
  這條指令與git checkout -b 還是有很大區別的。 
  · git checkout -b 是在當前所在的分支的基礎上創建特性分支。 
  · 而repo start 是在清單文件設定的分支的基礎上創建特性分支。

repo start stable --all
  • 1

  假設清單文件中設定的分支是gingerbread-exdroid-stable,那麼執行以上指令就是對所有項目,在gingerbread-exdroid-stable的基礎上創建特性分支stable。

repo start stable platform/build platform/bionic
  • 1

  假設清單文件中設定的分支是gingerbread-exdroid-stable,那麼執行以上指令就是對platform/build、platform/bionic項目,在gingerbread-exdroid-stable的基礎上創建特性分支stable。

4. repo checkout

 <branchname> [<rpoject>...]{{{
   repo checkout <branchname> [<project>...]
 }}} 
  • 1
  • 2
  • 3

  切換分支。 實際上是對git checkout命令的封裝,但不能帶-b參數,所以不能用此命令來創建特性分支。

  示例:

repo checkout liuq-dev
repo checkout liuq-dev skipper/build platform/bionic
  • 1
  • 2

5. repo branches

repo branches [<project>...]
  • 1

  查看分支。 
  示例:

repo branches
repo branches skipper/build skipper/release
#查看可切換的分支
cd .repo/manifests
git branch -a | cut -d / -f 3
  • 1
  • 2
  • 3
  • 4
  • 5

6. repo diff

repo diff [<project>...]
  • 1

  查看工作區文件差異。實際是對git diff命令的封裝,用於分別顯示各個項目工作區下的文件差異。在 commit 和工作目錄之間使用 git diff 顯示明顯差異的更改。 
  示例:

#查看所有項目
repo diff
#只查看其中的兩個項目
repo diff skipper/build skipper/release
  • 1
  • 2
  • 3
  • 4

7. repo stage

repo stage -i [<project>...]
  • 1

  把文件添加到index表中。實際上是對git add –interactive命令的封裝,用於挑選各個項目中的改動以加入暫存區。 
  -i表示git add –interactive命令中的–interactive,給出一個界面供用戶選擇。

8. repo prune

repo prune [<project>...]
  • 1

  刪除已經合併分支。實際上是對git branch -d 命令的封裝,該命令用於掃描項目的各個分支,並刪除已經合併的分支。

9. repo abandon

repo abandon <branchname> [<rpoject>...]
  • 1

  刪除指定分支。實際是對git brance -D命令的封裝。

10. repo status

repo status [<project>...]
  • 1

  查看文件狀態。 
  示例:

#輸出skipper/build項目分支的修改狀態
repo status skipper/build
  • 1
  • 2

每個小節的首行顯示項目名稱,以及所在的分支的名稱。 
每個字母表示暫存區的文件修改狀態。

字母 含義 描述
- 無變化 沒有修改,在 HEAD 和在索引中是一樣的
A 添加 不在HEAD中,在暫存區中
M 修改 在HEAD中, 在暫存區中,內容不同
D 刪除 在HEAD中,不在暫存區
R 重命名 不在HEAD中,在暫存區中
C 拷貝 不在HEAD中,在暫存區,從其他文件拷貝
T 文件狀態改變 在HEAD中,在暫存區,內容相同
U 未合併 需要衝突解決

第二個字符表示工作區文件的更改狀態。

字母 含義 描述
- 新/未知 不在暫存區,在工作區
m 修改 在暫存區,在工作區,被修改
d 刪除 在暫存區,不在工作區

兩個表示狀態的字母后面,顯示文件名信息。如果有文件重名還會顯示改變前後的文件名及文件的相似度。

11. repo remote

repo remote add <remotename> <url> [<project>...]
repo remote rm <remotename> [<project>...]
  • 1
  • 2

  設置遠程倉庫。 
  示例:

repo remote add org ssh://10.11.10.11/git_repo
  • 1

  這個指令根據xml文件添加的遠程分支,方便於向服務器提交代碼,執行之後的build目錄下看到新的遠程分支org。

#刪除遠程倉庫
repo remote rm org
  • 1
  • 2

12. repo push

repo push <remotename> [--all|<project>...]
  • 1

  向服務器提交代碼。repo會自己查詢需要向服務器提交的項目並提示用戶。 
  示例:

repo push org
  • 1

13. repo forall

repo forall [<project>...] -c <command>
  • 1

  迭代器,可以在所有指定的項目中執行同一個shell指令。 
  選項:

-c 後面所帶的參數是shell指令,即執行命令和參數。命令是通過 /bin/sh 評估的並且後面的任何參數就如 shell 位置的參數通過。 
-p 在shell指令輸出之前列出項目名稱,即在指定命令的輸出前顯示項目標題。這是通過綁定管道到命令的stdin,stdout,和 sterr 流,並且用管道輸送所有輸出量到一個連續的流,顯示在一個單一的頁面調度會話中。 
-v 列出執行shell指令輸出的錯誤信息,即顯示命令寫到 sterr 的信息。

  附加環境變量:

REPO_PROJECT 指定項目的名稱 
REPO_PATH 指定項目在工作區的相對路徑 
REPO_REMOTE 指定項目遠程倉庫的名稱 
REPO_LREV 指定項目最後一次提交服務器倉庫對應的哈希值 
REPO_RREV 指定項目在克隆時的指定分支,manifest裏的revision屬性

  如果-c後面所帶的shell指令中有上述環境變量,則需要用單引號把shell指令括起來。

13.1. 添加環境變量

repo forall -c 'echo $REPO_PROJECT'
repo forall -c 'echo $REPO_PATH'
  • 1
  • 2

13.2. 合併多個分支

repo forall -p -c git merge topic
  • 1

  把所有項目都切換到master分支,執行上述指令將topic分支合併到master分支。

13.3. 打標籤

repo forall -c git tag crane-stable-1.6
  • 1

  在所有項目下打標籤。

13.4. 設置遠程倉庫

repo forall -c 'git remote add korg ssh://[email protected]/$REPO_PROJECT.git'
  • 1

  引用環境變量REPO_PROJECT添加遠程倉庫。

#刪除遠程倉庫。
repo forall -c git remote rm korg
  • 1
  • 2

13.5. 創建特性分支

repo forall -c git branch crane-dev
repo forall -c git checkout -b crane-dev
  • 1
  • 2

14. repo grep

repo grep {pattern | -e pattern} [<project>...]
  • 1

  打印出符合某個模式的行。相當於對 git grep 的封裝,用於在項目文件中進行內容查找。 
  示例:

#要找一行, 裏面有#define, 並且有'MAX_PATH' 或者 'PATH_MAX':
repo grep -e '#define' --and -\( -e MAX_PATH -e PATH_MAX \)
#查找一行, 裏面有 'NODE'或'Unexpected', 並且在一個文件中這兩個都有的.
repo grep --all-match -e NODE -e Unexpected
  • 1
  • 2
  • 3
  • 4

15. repo manifest

repo manifest [-o {-|NAME.xml} [-r]]
  • 1

  manifest檢驗工具,用於顯示manifest文件內容。 
  選項:

-h, –help 顯示這個幫助信息後退出 
-r, –revision-as-HEAD 把某版次存爲當前的HEAD 
-o -|NAME.xml, –output-file=-|NAME.xml 把manifest存爲NAME.xml

16. repo version

repo version
  • 1

  顯示repo的版本號。 
  選項:

-h, –help 顯示這個幫助信息後退出.

17. repo upload

repo upload [--re --cc] {[<project>]...|--replace <project>}
  • 1

  repo upload 相當於git push,但是又有很大的不同。它不是將版本庫改動推送到代碼審覈服務器(Gerrit軟件架設)的特殊引用上,使用SSH協議。代碼審覈服務器會對推送的提交進行特殊處理,將新的提交顯示爲一個待審覈的修改集,並進入代碼審覈流程,只有當審覈通過後,纔會合併到官方正式的版本庫中。 
  選項:

-h, –help 顯示幫助信息 
-t 發送本地分支名稱到Gerrit代碼審覈服務器 
–replace 發送此分支的更新補丁集 
–re=REVIEWERS 要求指定的人員進行審覈 
–cc=CC 同時發送通知到如下郵件地址

18. repo download

repo download {project change[/patchset]}...
  • 1

  repo download命令主要用於代碼審覈者下載和評估貢獻者提交的修訂。 
  貢獻者的修訂在Git版本庫中refs/changes//引用方式命名(缺省的patchset爲1),和其他Git引用一樣,用git fetch獲取,該引用所指向的最新的提交就是貢獻者待審覈的修訂。 
  使用repo download命令實際上就是用git fetch獲取到對應項目的refs/changes//patchset>引用,並自動切換到對應的引用上。

19. repo selfupdate

repo selfupdate
  • 1

  用於 repo 自身的更新。如果有新版本的repo存在, 這個命令會升級repo到最新版本。通常這個動作在repo sync時會自動去做, 所以不需要最終用戶手動去執行。 
  選項:

-h, –help 顯示這個幫助信息後退出. 
–no-repo-verify 不要驗證repo源碼.

20. repo help

repo help [--all|command]
  • 1

  顯示命令的詳細幫助。 
  選項:

-h, –help 顯示這個幫助信息後退出 
-a, –all 顯示完整的命令列表





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章