文章目錄
- 概述
- .repo 目錄結構
- manifests/default.xml
- Manifest 文件的作用
- default.xml 文件內容示例
- linkfile 介紹
- .repo/projects 子目錄
- 配置和管理
- config
- HEAD
- hooks
- info/exclude
- objects
- rr-cache
- 工作區中的對應目錄
概述
repo
是一個由 Google 開發的版本控制工具,它建立在 Git 之上,用于管理多個 Git 倉庫的工作。它經常被用于管理大型項目,如 Android 操作系統開發,其中涉及許多單獨的 Git 倉庫。repo
工具使得在這些倉庫之間進行協調、同步和提交變得更加簡單。
在使用 repo
初始化一個工作區(workspace)后,會創建一個名為 .repo
的隱藏目錄。這個目錄包含了 repo
工具運行所需的配置文件和腳本。.repo
目錄的結構對于理解 repo
如何管理多個 Git 倉庫很重要。
.repo 目錄結構
.repo
目錄通常包含以下子目錄和文件:
manifests/
:包含了manifest
文件,這些 XML 文件定義了項目中所有倉庫的配置,如遠程倉庫的URL、分支、路徑等。manifests.git/
:一個 Git 倉庫,包含manifests
目錄中的所有manifest
文件的版本歷史。projects/
:包含了所有被repo
管理的 Git 倉庫的實際內容。每個倉庫在這個目錄中有其對應的子目錄。
manifests/default.xml
.repo/manifests/default.xml
是一個核心文件,它定義了項目的默認 manifest(清單)。Manifest 文件是用 XML 格式編寫的,并且描述了項目的倉庫配置,包括哪些倉庫應該被包含在項目中、倉庫的遠程地址、要檢出的分支、路徑以及任何特定的版本信息。
Manifest 文件的作用
Manifest 文件指導 repo
工具如何初始化和同步項目中的各個倉庫。這個文件告訴 repo
:
- 哪些遠程倉庫需要被克隆(包括遠程倉庫的URL)。
- 各個倉庫應該檢出哪個分支。
- 各個倉庫在本地工作區中的相對路徑。
- 如果有必要,固定特定的提交或標簽。
- 包含其他 manifest 文件(如有)以組織或繼承配置。
default.xml 文件內容示例
一個典型的 default.xml
文件內容可能如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<manifest> <remote name="origin" fetch="https://example.com/" />
<default revision="master" remote="origin" sync-j="4" /> <project path="libraries/Library" name="Library.git" /> <project path="apps/App" name="App.git" />
</manifest>
在上述示例中:
<remote>
元素定義了一個遠程倉庫的名稱和 URL。在這個例子中,有一個名為origin
的遠程倉庫,其基礎 URL 為https://example.com/
。<default>
元素設置了所有項目的默認配置,例如默認的revision
(分支或標簽),在這里是master
,默認的遠程倉庫remote
是之前定義的origin
,以及sync-j
參數,它指定了同步操作中并行下載的數量,這里是4
。<project>
元素定義了具體要包含在工作區中的倉庫。每個項目都有一個path
,指定了倉庫在本地工作區中的位置,以及name
,指定了遠程倉庫的名稱。在這個例子中,包括了Library.git
和App.git
兩個倉庫,它們分別位于工作區中的libraries/Library
和apps/App
路徑下。
當運行 repo init
命令時,repo
會使用 .repo/manifests/default.xml
文件(或者如果指定了其他文件,則使用該文件)來初始化項目。之后,當運行 repo sync
命令時,repo
將根據 manifest 文件中的配置同步項目的所有倉庫。
default.xml
只是一個默認的 manifest 文件名稱。在不同的項目中,可能會有不同的 manifest 文件用于不同的目的,例如維護多個產品線或分支。可以通過 repo init -m
命令來指定使用特定的 manifest 文件。
linkfile 介紹
` 元素用來創建符號鏈接,即在文件系統中的一個位置創建指向另一個位置的引用。這在組織和訪問文件時非常有用,尤其是當你希望在不復制文件的情況下,在項目的不同部分之間共享文件或目錄時。
<linkfile>
的 src
(source,源)屬性指定了鏈接的源文件或目錄的路徑,而 dest
(destination,目標)屬性指定了要創建符號鏈接的目標路徑。src
路徑是相對于包含該 <linkfile>
標簽的 <project>
目錄的,而 dest
路徑則是相對于工作區的根目錄的。
假設我們有以下的 manifest 文件片段:
<manifest> <project path="apps/App1" name="App1.git"> <linkfile src="shared/config.xml" dest="config.xml" /> </project> <project path="apps/App2" name="App2.git"> <linkfile src="shared/config.xml" dest="config.xml" /> </project>
</manifest>
在這個例子中:
- 我們有兩個項目,
App1.git
和App2.git
,它們都位于apps
目錄下的不同子目錄中。 - 在每個項目中,我們希望有一個符號鏈接,指向共享的
config.xml
文件。假設這個共享文件位于每個項目目錄下的shared
子目錄中。 <linkfile>
標簽定義了從shared/config.xml
(源)到config.xml
(目標)的符號鏈接。對于App1
,這將在apps/App1
目錄下創建一個指向apps/App1/shared/config.xml
的config.xml
符號鏈接。對于App2
,也是類似的情況。
當你執行 repo sync
命令時,repo
工具會處理 manifest 文件中的 <linkfile>
指令,并在對應的位置創建符號鏈接。
.repo/projects 子目錄
.repo/projects/
子目錄內包含了每個被檢出 Git 倉庫的具體數據。當你使用 repo sync
命令同步項目時,repo
會根據 manifests
中的配置檢出正確的版本到這些子目錄中。
例如,如果你的項目包含了名為 Library
和 App
的兩個 Git 倉庫,那么 .repo/projects/
目錄可能如下所示:
.repo/projects/
Library.git/
App.git/
這里的 Library.git
和 App.git
目錄分別對應它們的 Git 倉庫,而 .git
后綴表示它們是裸倉庫(bare repositories),即不包含工作目錄的 Git 倉庫。
配置和管理
.repo/projects/device.git$ ls
branches COMMIT_EDITMSG config description FETCH_HEAD HEAD hooks index info logs MERGE_RR objects
ORIG_HEAD packed-refs refs rr-cache
config
config
文件包含了特定 Git 倉庫的配置設置。這些設置可能包括遠程倉庫的URL、分支信息、合并策略、鉤子腳本路徑等。在 repo
管理的項目中,部分配置會由 repo
工具自動設置。
HEAD
HEAD
文件是一個引用(ref),指向當前的工作分支或提交。當你在工作目錄中執行檢出(checkout)操作時,HEAD
會更新為指向新的活動分支或提交。它是 Git 用來知道當前工作狀態的重要指標。
hooks
hooks
目錄包含 Git 鉤子(hooks)腳本。這些腳本是在執行特定 Git 命令(如 commit
, push
, receive
等)時自動運行的。repo
可能會使用這些鉤子來執行額外的操作,比如在提交前進行代碼風格檢查或在推送后觸發持續集成(CI)流程。
info/exclude
- 作用:
exclude
文件類似于.gitignore
文件,但它是特定于一個倉庫的本地配置。它用于排除(忽略)特定的文件或目錄,使這些條目不被 Git 跟蹤。這些排除規則僅在本地有效,不會隨著倉庫一起被提交或同步。
objects
- 作用:
objects
目錄是 Git 對象數據庫的存放地,其中包含了所有的 Git 對象,如提交(commits)、樹(trees)、blobs(文件內容)和標簽(tags)。這些對象以一種特殊的格式存儲,使 Git 能夠快速檢索和管理版本歷史。
rr-cache
rr-cache
目錄是 “Reused Recorded” 緩存的一部分,它是 Git 用來優化補丁應用(如合并和復制操作)的特征。Git 會在這個目錄中保存曾經計算過的補丁結果,以便在將來的操作中重用,從而加快處理速度。
工作區中的對應目錄
雖然 .repo/projects/
中包含了 Git 倉庫的數據,但工作區的頂層目錄下通常還會有與這些倉庫對應的目錄。這些目錄是從 .repo/projects/
中的裸倉庫檢出的工作目錄。repo
會設置 Git 的 worktree
路徑,使得這些工作目錄能夠與 .repo/projects/
中的裸倉庫關聯。
例如,你可能會在工作區的根目錄下看到如下結構:
Library/
App/
在這里,Library/
和 App/
目錄是從 .repo/projects/Library.git/
和 .repo/projects/App.git/
中檢出的,你可以在這些目錄中編輯文件,然后使用 Git 和 repo
命令來提交更改。