多倉庫管理工具——Repo

Repo 是創建在 Git 上的一個多倉庫管理工具,能夠組織多個倉庫的上傳和下載。html

Repo 是創建在 Git 上的一個多倉庫管理工具,能夠組織多個倉庫的上傳和下載。Repo 是 Google 用 Python 腳本寫的調用 Git 的腳本,主要幫助咱們管理多個 Git 存儲倉庫,將其上傳到咱們的版本控制系統,並自動執行 Android 開發工做流程的某些部分。Repo 並非要取代 Git,而是爲了在 Android 環境下更加方便的使用 Git。下面來看看 Repo 的具體用法吧!android

安裝 Repo

在安裝 Repo 時,必須先要確保已經安裝了 Git 工具,以及 Python2.7 + 的環境,下面是在 Mac 下安裝的流程:git

一、確保主目錄下有一個 bin/ 目錄,而且該目錄包含在路徑中:github

mkdir ~/bin
PATH=~/bin:$PATH
複製代碼

二、下載 Repo 工具,並確保它可執行:shell

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

Windows 下沒有 curl 工具能夠下載,地址是 curl.se/windows/dl-…。不過也能夠直接訪問 storage.googleapis.com/git-repo-do… 網址,直接把內容複製到~/bin/repo效果是同樣的。另外若是 googleapis.com 沒法訪問的話也能夠替換爲 Github 的 Repo 地址:windows

curl https://raw.githubusercontent.com/esrlabs/git-repo/stable/repo > ~/bin/repo
複製代碼

對於 Linux 安裝過程能夠參考 github.com/esrlabs/git… 這個倉庫的 README 其實說得很清楚了。api

Repo 的背景

使用 Repo 以前,最好先熟悉 Git,關於 Git 的推薦資料:git-scm.com/book/zh/v2。其實 Repo 最開始是用來管理 Android 源代碼庫的,Android 源代碼位於由 Google 託管的 Git 代碼庫中。Git 代碼庫中包含 Android 源代碼的元數據,其中包括與對源代碼進行的更改以及更改日期相關的元數據。並且 Android 版本庫衆多,版本庫太大以及 Git 不能部分檢出,若是全部的東西都放在一個庫中,而某個開發團隊比較關心可能只是某個小組件或者插件而已,可是卻要下載如此龐大的版本庫,因此這一切交給了 Repo 去管理。服務器

那麼 Repo 如何管理多個代碼倉庫的呢?markdown

Repo 的組成

Repo 主要包括兩部分:Repo 引導腳本(Google 稱之爲 Repo launcher)和 Repo 命令的主體部分。那麼 Repo 倉庫究竟有些什麼東西呢,在咱們初始化 Repo 倉庫以後,會出現一個. repo 的文件夾,裏面有以下內容:網絡

changlinzou@mac work % tree .repo -L 1
.repo
├── manifest.xml -> manifests/default.xml
├── manifests
├── manifests.git
├── project-objects
├── project.list
├── projects
└── repo

5 directories, 2 files
複製代碼

當執行 repo init 命令來初始化倉庫的時候首先執行的就是 Repo 的引導腳本,該腳本會到咱們指定的地方去下載 Manifest 倉庫,以及 Repo 命令主體部分。下載好以後就放在當前目錄下面的.repo目錄下,其中:

文件夾 用途
manifests 清單文件的倉庫
manifests.git 清單文件的 Git 裸倉庫,不帶工做區
manifest.xml 這是一個連接文件,指向你的用於初始化工做區的清單文件,即manifests/default.xml
project.list 一個文本文件,裏面包含全部項目名字的列表
projects 該文件夾下包含全部 git project 的裸倉庫,文件夾的層次結構跟工做區的佈局同樣
repo 這是 repo 命令的主體,其中也包含最新的 repo 命令,推薦使用這裏面的 repo 命令

對於 Manifests 文件相信每個 Android 開發中都不陌生,Android 項目中 Manifests 聲明瞭四大組件,就像列出的項目組件的清單同樣。因此其實很容易類比,在這裏 manifests 是清單文件的 git 倉庫,這些 xml 文件中包含了各個 git project 的名稱,檢出的 reversion,檢出到哪一個目錄等等信息。Repo 就是利用這些 manifest 文件去分別獲取各個 project,好比這樣一個 manifest 文件:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <remote  />
    <default remote="origin" revision="master" sync-j="4" />
    <project  />
    <project  />
    <project  />
    ......
</manifest>
複製代碼

下面是 Repo 的 manifest 文件中元素的意義:

元素 詳情
manifest 元素 xml 文件的根元素
remote 元素 能夠存在一個或者多個 remote 元素,remote 元素指定了使用 repo upload 命令的時候,會將改變提交到哪一個服務器
default 元素 default 元素中指定的屬性都是一些缺省的屬性。即若是 project 元素中不存在該屬性,則使用在 default 元素中指定的屬性。revision:Git 分支的名字。若是 project 元素沒有指定 revision 屬性,那麼就使用 default 元素的該屬性。revision 屬性的值能夠是一個 git branch,git tag,也能夠是一個 commit id。sync-j:sync 的時候,並行工做的任務數。sync-c:若是設置爲 true,則在同步代碼的時候,將只會同步 project 元素中 revision 屬性中指定的分支。若是 project 元素沒有指定 revision 屬性,則使用 default 元素的 revision 屬性。
project 元素 xml 文件中能夠指定一個或者多個 project 元素。 每個 project 元素都描述了一個須要 pull 到本地的 git 倉庫。project 元素中有不少可使用的屬性,在此只介紹幾個咱們常用的屬性。name:git project 的名字,path:該 project 的本地工做區的路徑,revision:該 project 要跟蹤的分支的名字。名字能夠是相對於 refs/heads 命名空間的,如:master,或者絕對的,如:refs/heads/master。標籤或者 48 位的 SHA-1 值理論上也能夠工做。若是沒有提供該屬性,則使用 default 元素中的 revision 屬性。

Repo 命令

下面的內容來自 Google 的官方文檔:source.android.com/source/usin…

使用 Repo 需遵循的格式以下:

repo <COMMAND> <OPTIONS>
複製代碼

可選元素顯示在方括號 [ ] 中。例如,許多命令會將項目列表用做參數。您能夠爲項目指定項目列表,做爲名稱列表或本地源代碼目錄的路徑列表:

repo sync [<PROJECT0> <PROJECT1> <PROJECTN>]
repo sync [</PATH/TO/PROJECT0> ... </PATH/TO/PROJECTN>]
複製代碼

help

安裝 Repo 後,您能夠經過運行如下命令找到最新文檔(開頭是包含全部命令的摘要):

repo help
複製代碼

您能夠經過在 Repo 樹中運行如下命令來獲取有關某個命令的信息:

repo help <COMMAND>
複製代碼

例如,如下命令會生成 Repo init 參數的說明和選項列表,該參數會在當前目錄中初始化 Repo。(要了解詳情,請參閱 init。)

repo help init
複製代碼

init

$ repo init -u <URL> [<OPTIONS>]
複製代碼

在當前目錄中安裝 Repo。這會建立一個 .repo/ 目錄,其中包含用於 Repo 源代碼和標準 Android 清單文件的 Git 代碼庫。該 .repo/ 目錄中還包含 manifest.xml,這是一個指向 .repo/manifests/ 目錄中所選清單的符號連接。

選項:

  • -u:指定要從中檢索清單代碼庫的網址。您能夠在 https://android.googlesource.com/platform/manifest 中找到常見清單
  • -m:在代碼庫中選擇清單文件。若是未選擇任何清單名稱,則會默認選擇 default.xml。
  • -b:指定修訂版本,即特定的清單分支。

注意:對於其他的全部 Repo 命令,當前工做目錄必須是 .repo/ 的父目錄或相應父目錄的子目錄。

sync

repo sync [<PROJECT_LIST>]
複製代碼

下載新的更改並更新本地環境中的工做文件。若是您在未使用任何參數的狀況下運行 repo sync,則該操做會同步全部項目的文件。

運行 repo sync 後,將出現如下狀況:

  • 若是目標項目從未同步過,則 repo sync 至關於 git clone。遠程代碼庫中的全部分支都會複製到本地項目目錄中。

  • 若是目標項目已同步過,則 repo sync 至關於如下命令:

    git remote update
    git rebase origin/<BRANCH>
    複製代碼

    其中 *<BRANCH>* 是本地項目目錄中當前已檢出的分支。若是本地分支沒有在跟蹤遠程代碼庫中的分支,則相應項目不會發生任何同步。

  • 若是 git rebase 操做致使合併衝突,那麼您須要使用普通 Git 命令(例如 git rebase --continue)來解決衝突。

repo sync 運行成功後,指定項目中的代碼會與遠程代碼庫中的代碼保持同步。

選項:

  • -d:將指定項目切換回清單修訂版本。若是項目當前屬於某個主題分支,但只是臨時須要清單修訂版本,則此選項會有所幫助。
  • -s:同步到當前清單中清單服務器元素指定的一個已知的良好版本。
  • -f:即便某個項目同步失敗,系統也會繼續同步其餘項目。

upload

repo upload [<PROJECT_LIST>]
複製代碼

對於指定的項目,Repo 會將本地分支與最後一次 repo sync 時更新的遠程分支進行比較。Repo 會提示您選擇一個或多個還沒有上傳以供審覈的分支。

您選擇一個或多個分支後,所選分支上的全部提交都會經過 HTTPS 鏈接傳輸到 Gerrit。您須要配置一個 HTTPS 密碼以啓用上傳受權。要生成新的用戶名 / 密碼對以用於 HTTPS 傳輸,請訪問密碼生成器

當 Gerrit 經過其服務器接收對象數據時,它會將每項提交轉變成一項更改,以便審覈者能夠單獨針對每項提交給出意見。要將幾項 「檢查點」 提交合併爲一項提交,請使用 git rebase -i,而後再運行 repo upload。

若是您在未使用任何參數的狀況下運行 repo upload,則該操做會搜索全部項目中的更改以進行上傳。

要在更改上傳以後對其進行修改,您應該使用 git rebase -igit commit --amend 等工具更新您的本地提交。修改完成以後,請執行如下操做:

  • 進行覈對以確保更新後的分支是當前已檢出的分支。

  • 對於相應系列中的每項提交,請在方括號內輸入 Gerrit 更改 ID:

    # Replacing from branch foo
    [ 3021 ] 35f2596c Refactor part of GetUploadableBranches to lookup one specific...
    [ 2829 ] ec18b4ba Update proto client to support patch set replacments
    # Insert change numbers in the brackets to add a new patch set.
    # To create a new change record, leave the brackets empty.
    複製代碼

上傳完成後,這些更改將擁有一個額外的補丁程序集。

diff

repo diff [<PROJECT_LIST>]
複製代碼

使用 git diff 顯示提交與工做樹之間的明顯更改。

download

repo download <TARGET> <CHANGE>
複製代碼

從審覈系統中下載指定更改,並放在您項目的本地工做目錄中供使用。

例如,要將更改 23823 下載到您的平臺 / 編譯目錄,請運行如下命令:

$ repo download platform/build 23823
複製代碼

repo sync 應該能夠有效移除經過 repo download 檢索到的任何提交。或者,您能夠將遠程分支檢出,例如 git checkout m/master

注意:因爲全球的全部服務器均存在複製延遲,所以某項更改(位於 Gerrit 中)出如今網絡上的時間與全部用戶可經過 repo download 找到此項更改的時間之間存在些許的鏡像延遲。

forall

repo forall [<PROJECT_LIST>] -c <COMMAND>
複製代碼

在每一個項目中運行指定的 shell 命令。經過 repo forall 可以使用下列額外的環境變量:

  • REPO_PROJECT 可設爲項目的具備惟一性的名稱。
  • REPO_PATH 是客戶端根目錄的相對路徑。
  • REPO_REMOTE 是清單中遠程系統的名稱。
  • REPO_LREV 是清單中修訂版本的名稱,已轉換爲本地跟蹤分支。若是您須要將清單修訂版本傳遞到某個本地運行的 Git 命令,則可以使用此變量。
  • REPO_RREV 是清單中修訂版本的名稱,與清單中顯示的名稱徹底一致。

選項:

  • -c:要運行的命令和參數。此命令會經過 /bin/sh 進行求值,它以後的任何參數都將做爲 shell 位置參數傳遞。
  • -p:在指定命令輸出結果以前顯示項目標頭。這經過如下方式實現:將管道綁定到命令的 stdin、stdout 和 sterr 流,而後經過管道將全部輸出結果傳輸到一個頁面調度會話中顯示的連續流中。
  • -v:顯示該命令向 stderr 寫入的消息。

prune

repo prune [<PROJECT_LIST>]
複製代碼

刪減(刪除)已合併的主題。

start

repo start <BRANCH_NAME> [<PROJECT_LIST>]
複製代碼

從清單中指定的修訂版本開始,建立一個新的分支進行開發。

*<BRANCH_NAME>* 參數應簡要說明您嘗試對項目進行的更改。若是您不知道,則不妨考慮使用默認名稱。

*<PROJECT_LIST>* 指定了將參與此主題分支的項目。

注意:「.」 是一個很是實用的簡寫形式,用來表明當前工做目錄中的項目。

status

repo status [<PROJECT_LIST>]
複製代碼

對於每一個指定的項目,將工做樹與臨時區域(索引)以及此分支 (HEAD) 上的最近一次提交進行比較。在這三種狀態存在差別之處顯示每一個文件的摘要行。

要僅查看當前分支的狀態,請運行 repo status。系統會按項目列出狀態信息。對於項目中的每一個文件,系統使用兩個字母的代碼來表示:

在第一列中,大寫字母表示臨時區域與上次提交狀態之間的不一樣之處。

字母 含義 說明
- 無更改 HEAD 與索引中相同
A 已添加 不存在於 HEAD 中,但存在於索引中
M 已修改 存在於 HEAD 中,但索引中的文件已修改
D 已刪除 存在於 HEAD 中,但不存在於索引中
R 已重命名 不存在於 HEAD 中,但索引中的文件的路徑已更改
C 已複製 不存在於 HEAD 中,已從索引中的另外一個文件複製
T 模式已更改 HEAD 與索引中的內容相同,但模式已更改
U 未合併 HEAD 與索引之間存在衝突;須要解決方案

在第二列中,小寫字母表示工做目錄與索引之間的不一樣之處。

字母 含義 說明
- 新 / 未知 不存在於索引中,但存在於工做樹中
m 已修改 存在於索引中,也存在於工做樹中(但已修改)
d 已刪除 存在於索引中,不存在於工做樹中

參考資料

一、source.android.com/source/usin…

二、git-scm.com/book/zh/v2

相關文章
相關標籤/搜索