【嵌入式开发 Linux 常用命令系列 4.2 -- .repo 各个目录介绍】
文章目录
- 概述
- .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
命令来提交更改。