北京网站建设开发公司新型互联网项目代理
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:05
当前位置: 首页 > news >正文
北京网站建设开发公司,新型互联网项目代理,wordpress如何给主题加密,网站建设1影响力公司文章目录 1. 概要2. 工作原理2.1 项目清单库(.repo/manifests)2.2 repo脚本库(.repo/repo)2.3 仓库目录和工作目录2.4 repo 目录结构分析 3. 使用介绍3.1 init3.2 sync3.3 upload3.4 download3.5 forall3.6 prune3.7 start3.8 status 4. 使用实践4.1 对项目清单文件进行定制4.2… 文章目录 1. 概要2. 工作原理2.1 项目清单库(.repo/manifests)2.2 repo脚本库(.repo/repo)2.3 仓库目录和工作目录2.4 repo 目录结构分析 3. 使用介绍3.1 init3.2 sync3.3 upload3.4 download3.5 forall3.6 prune3.7 start3.8 status 4. 使用实践4.1 对项目清单文件进行定制4.2 解决无法下载Android源码4.3 更快更省的下载远程代码4.4 避免在匿名分支上工作4.5 使用upload提交代码4.6 定期删除已经合并的开发分支4.7 同时操作多个git库 1. 概要 repo是Android为了方便管理多个git库而开发的Python脚本。repo的出现并非为了取代git而是为了让Android开发者更为有效的利用git。 Android源码包含数百个git库仅仅是下载这么多git库就是一项繁重的任务所以在下载源码时Android就引入了repo。 Android官方推荐下载repo的方法是通过Linux curl命令下载完后为repo脚本添加可执行权限 \( curl https://storage.googleapis.com/git-repo-downloads/repo ~/bin/repo \) chmod ax ~/bin/repo由于国内Google访问受限所以上述命令不一定能下载成功。其实我们现在可以从很多第三方渠道找到repo脚本只需要取下来确保repo可以正确执行即可。
- 工作原理
repo需要关注当前git库的数量、名称、路径等有了这些基本信息才能对这些git库进行操作。通过集中维护所有git库的清单repo可以方便的从清单中获取git库的信息。 这份清单会随着版本演进升级而产生变化同时也有一些本地的修改定制需求所以repo是通过一个git库来管理项目的清单文件的这个git库名字叫manifests。
当打开repo这个可执行的python脚本后发现代码量并不大(不超过1000行)难道仅这一个脚本就完成了AOSP数百个git库的管理吗并非如此。 repo是一系列脚本的集合这些脚本也是通过git库来维护的这个git库名字叫repo。
在客户端使用repo初始化一个项目时就会从远程把manifests和repo这两个git库拷贝到本地但这对于Android开发人员来说又是近乎无形的(一般通过文件管理器是无法看到这两个git库的)。 repo将自动化的管理信息都隐藏根目录的.repo子目录中。
2.1 项目清单库(.repo/manifests)
AOSP项目清单git库下只有一个文件default.xml是一个标准的XML描述了当前repo管理的所有信息。
AOSP的default.xml的文件内容如下
?xml version1.0 encodingUTF-8?
manifestremote nameaospfetch..reviewhttps://android-review.googlesource.com/ /default revisionmasterremoteaospsync-j4 /project pathbuild nameplatform/build groupspdk,tradefed copyfile srccore/root.mk destMakefile //projectproject pathabi/cpp nameplatform/abi/cpp groupspdk /project pathart nameplatform/art groupspdk /…project pathtools/studio/translation nameplatform/tools/studio/translation groupsnotdefault,tools /project pathtools/swt nameplatform/tools/swt groupsnotdefault,tools /
/manifest描述了远程仓库的基本信息。name描述的是一个远程仓库的名称通常我们看到的命名是origin;fetch用作项目名称的前缘在构造项目仓库远程地址时使用到;review描述的是用作code review的server地址default标签的定义的属性将作为标签的默认属性在标签中也可以重写这些属性。属性revision表示当前的版本也就是我们俗称的分支;属性remote描述的是默认使用的远程仓库名称即标签中name的属性值;属性sync-j表示在同步远程代码时并发的任务数量配置高的机器可以将这个值调大每一个repo管理的git库就是对应到一个标签path描述的是项目相对于远程仓库URL的路径同时将作为对应的git库在本地代码的路径; name用于定义项目名称命名方式采用的是整个项目URL的相对地址。 譬如AOSP项目的URL为https://android.googlesource.com/命名为platform/build的git库访问的URL就是https://android.googlesource.com/platform/build
如果需要新增或替换一些git库可以通过修改default.xml来实现repo会根据配置信息自动化管理。但直接对default.xml的定制可能会导致下一次更新项目清单时与远程default.xml发生冲突。 因此repo提供了一个种更为灵活的定制方式local_manifests:所有的定制是遵循default.xml规范的文件名可以自定义譬如local_manifest.xml, another_local_manifest.xml等 将定制的XML放在新建的.repo/local_manifests子目录即可。repo会遍历.repo/local_manifests目录下的所有*.xml文件最终与default.xml合并成一个总的项目清单文件manifest.xml。
local_manifests的修改示例如下
\( ls .repo/local_manifests
local_manifest.xml
another_local_manifest.xml\) cat .repo/local_manifests/local_manifest.xml
?xml version1.0 encodingUTF-8?
manifestproject pathmanifest nametools/manifest /project pathplatform-manifest nameplatform/manifest /
/manifest2.2 repo脚本库(.repo/repo)
repo对git命令进行了封装提供了一套repo的命令集(包括init, sync等)所有repo管理的自动化实现也都包含在这个git库中。 在第一次初始化的时候repo会从远程把这个git库下载到本地。
2.3 仓库目录和工作目录
仓库目录保存的是历史信息和修改记录工作目录保存的是当前版本的信息。一般来说一个项目的Git仓库目录默认为.git目录是位于工作目录下面的但是Git支持将一个项目的Git仓库目录和工作目录分开来存放。 对于repo管理而言既有分开存放也有位于工作目录存放的:
manifests 仓库目录有两份拷贝一份位于工作目录(.repo/manifests)的.git目录下另一份独立存放于.repo/manifests.gitrepo仓库目录位于工作目录(.repo/repo)的.git目录下project所有被管理git库的仓库目录都是分开存放的位于.repo/projects目录下。同时也会保留工作目录的.git但里面所有的文件都是到.repo的链接。这样即做到了分开存放也兼容了在工作目录下的所有git命令。
既然.repo目录下保存了项目的所有信息所有要拷贝一个项目时只是需要拷贝这个目录就可以了。repo支持从本地已有的.repo中恢复原有的项目。
2.4 repo 目录结构分析 .repo 此为repo目录可用于提取相应项目工作目录到外面的repo工作目录。 .repo/manifests.git 此为repo配置信息的git库不同版本包含不同配置信息。每个repo项目初始化后也会有自己的git仓库的repo也会建立一个Git仓库用来记录当前Android版本下各个子项目的Git仓库分别处于哪一个分支这个仓库通常叫做manifest仓库。 .repo/manifests 此为repo配置信息的工作目录将配置信息的工作目录和相应的实际git目录分离管理并且配置信息中的.git目录实际只是指向实际git库的软连接。此目录中可能包含一个或多个xml文件描述的配置。每个xml文件是独立的一套配置配置内容包括当前repo工作目录包含哪些git项目、所有git项目所处的默认公共分支、以及远端地址等。 .repo/manifest.xml repo工作目录中的内容同一时刻只能采用manifests中的一个xml文件做为其配置该文件就是其软连接通过init的-m选项指定采用哪个文件另外同一xml文件也可能处于manifests库的不同版本或者不同分支通过init的-b选项指定使用manifests中的哪个分支每次init命令都会从服务器更新最新的配置。这里通过-m指定的manifests中的xml文件中。 .repo/repo 此为repo脚本集的git库用于repo管理所需的各种脚本repo的所有子命令就是其中的对应脚本实现。这些脚本也通过git管理.repo/repo/.git为对其应的git目录用git进行版本管理。
- 使用介绍 repo命令的使用格式如下所示 \( repo COMMAND OPTIONS可选的的有help、init、sync、upload、diff、download、forall、prune、start、status每一个命令都有实际的使用场景 下面我们先对这些命令做一个简要的介绍 3.1 init \) repo init -u URL [OPTIONS]-u指定manifests这个远程git库的URLmanifests库是整个项目的清单。默认情况这个git库只包含了default.xml一个文件其内容可以参见Android的样本-m –manifest-name指定所需要的manifests库中的清单文件。默认情况下会使用maniftests/default.xml-b –manifest-branch指定manifest.xml文件中的一个版本也就是俗称的“分支” 运行该命令后会在当前目录下新建一个.repo子目录 .repo ├── manifests # 一个git库包含default.xml文件用于描述repo所管理的git库的信息 ├── manifests.git # manifest这个git库的实体manifest/.git目录下的所有文件都会链接到该目录 ├── manifest.xml # manifests/default.xml的一个软链接 └── repo # 一个git库包含repo运行的所有脚本 这些本地的目录是如何生成的呢执行repo命令时可以通过–trace参数来看实际发生了什么。 \( repo --trace init -u \)URL -b \(BRANCH -m \)MANIFEST——————–mkdir .repo; cd .repogit clone –bare \(URL manifests.gitgit clone https://android.googlesource.com/tools/repomkdir -p manifests/.git; cd manifests/.gitfor i in ../../manifests.git/*; do ln -s \)ı .; donecd ..git checkout \(BRANCH -- .cd ..ln -s manifests/\)MANIFEST manifest.xml首先在当前目录下创建.repo子目录后续所有的操作都在.repo子目录下完成; 然后clone了两个git库其中一个是-u参数指定的manifests本地git库的名称是manifest.git;另一个是默认的repo后面我们会看到这个URL也可以通过参数来指定; 接着创建了manifest/.git目录里面的所有文件都是到manifests.git这个目录的链接这个是为了方便对manifests目录执行git命令紧接着就会将manifest切换到-b参数指定的分支; 最后在.repo目录下创建了一个软链接链接到-m参数制定的清单文件默认情况是manifests/default.xml。 这样就完成了一个多git库的初始化之后就可以执行其他的repo命令了。 我们还介绍几个不常用的参数在国内下载Android源码时会用到 –repo-url指定远程repo库的URL默认情况是https://android.googlesource.com/tools/repo但国内访问Google受限会导致这个库无法下载从而导致repo init失败所以可以通过该参数指定一个访问不受限的repo地址–repo-branch同manifest这个git库一样repo这个git库也是有版本差异的可以通过该参数来指定下载repo这个远程git库的特定分支–no-repo-verify在下载repo库时会对repo的源码进行检查。通过–repo-url指定第三方repo库时可能会导致检查不通过所以可以配套使用该参数强制不进行检查 3.2 sync \( repo sync [PROJECT_LIST]下载远程代码并将本地代码更新到最新这个过程称为“同步”。如果不使用任何参数那么会对所有repo管理的进行同步操作;也可以PROJECT_LIST参数指定若干要同步的PROJECT。 根据本地git库代码不同同步操作会有不同的行为 当本地的git库是第一次触发同步操作时那么该命令等价于git clone会将远程git库直接拷贝到本地当本地已经触发过同步操作时那么该命令等价于git remote update git rebase origin/就是当前与本地分支所关联的远程分支 代码合并可能会产生冲突当冲突出现时只需要解决完冲突然后执行git rebase --continue即可。 当sync命令正确执行完毕后本地代码就同远程代码保持一致了。在一些场景下我们会用到sync命令的一些参数 -j开启多线程同步操作这会加快sync命令的执行速度。默认情况下使用4个线程并发进行sync-c, –current-branch只同步指定的远程分支。默认情况下sync会同步所有的远程分支当远程分支比较多的时候下载的代码量就大。使用该参数可以缩减下载时间节省本地磁盘空间-d, –detach脱离当前的本地分支切换到manifest.xml中设定的分支。在实际操作中这个参数很有用当我们第一次sync完代码后往往会切换到dev分支进行开发。如果不带该参数使用sync 则会触发本地的dev分支与manifest设定的远程分支进行合并这会很可能会导致sync失败-f, –force-broken当有git库sync失败了不中断整个同步操作继续同步其他的git库–no-clone-bundle在向服务器发起请求时为了做到尽快的响应速度会用到内容分发网络(CDN, Content Delivery Network)。同步操作也会通过CDN与就近的服务器建立连接 使用HTTP/HTTPS的 U R L / c l o n e . b u n d l e 来初始化本地的 g i t 库 c l o n e . b u n d l e 实际上是远程 g i t 库的镜像通过 H T T P 直接下载这会更好的利用网络带宽加快下载速度。当服务器不能正常响应下载 URL/clone.bundle来初始化本地的git库clone.bundle实际上是远程git库的镜像通过HTTP直接下载这会更好的利用网络带宽加快下载速度。 当服务器不能正常响应下载 URL/clone.bundle来初始化本地的git库clone.bundle实际上是远程git库的镜像通过HTTP直接下载这会更好的利用网络带宽加快下载速度。当服务器不能正常响应下载URL/clone.bundle但git又能正常工作时可以通过该参数配置不下载\)URL/clone.bundle而是直接通过git下载远程git库 3.3 upload \( repo upload [PROJECT_LIST]从字面意思理解upload就是要上传将本地的代码上传到远程服务器。upload命令首先会找出本地分支从上一次同步操作以来发生的改动然后会将这些改动生成Patch文件上传至Gerrit服务器。 如果没有指定PROJECT_LIST那么upload会找出所有git库的改动;如果某个git库有多个分支upload会提供一个交互界面提示选择其中若干个分支进行上传操作。 upload并不会直接将改动合并后远程的git库而是需要先得到Reviewer批准。Reviewer查看改动内容、决定是否批准合入代码的操作都是通过Gerrit完成。 Gerrit服务器的地址是在manifests中指定的打开.repo/manifest.xml这个XML TAG中的review属性值就是Review服务器的URL: remote nameaospfetch..reviewhttps://android-review.googlesource.com/ /Gerrit的实现机制不是本文讨论的内容但有几个与Gerrit相关的概念是需要代码提交人员了解的 Reviewer代码审阅人员可以是多个是需要人为指定的。Gerrit提供网页的操作可以填选Reviewer。当有多个git库的改动提交时为了避免在网页上频繁的填选Reviewer这种重复劳动 upload提供了–re, –reviewer参数在命令行一次性指定ReviewerCommit-IDgit为了标识每个提交引入了Commit-ID是一个SHA-1值针对当次提交内容的一个Checksum可以用于验证提交内容的完整性Change-IDGerrit针对每一个Review任务引入了一个Change-ID每一个提交上传到Gerrit都会对应到一个Change-ID 为了区分于Commit-IDGerrit设定Change-ID都是以大写字母 “I” 打头的。 Change-ID与Commit-ID并非一一对应的每一个Commit-ID都会关联到一个Change-ID但Change-ID可以关联到多个Commit-IDPatch-Set当前需要Review的改动内容。一个Change-ID关联多个Commit-ID就是通过Patch-Set来表现的当通过git commit --amend命令修正上一次的提交并上传时 Commit-ID已经发生了变化但仍可以保持Change-ID不变这样,在Gerrit原来的Review任务下就会出现新的Patch-Set。修正多少次就会出现多少个Patch-Set 可以理解只有最后一次修正才是我们想要的结果所以在所有的Patch-Set中只有最新的一个是真正有用的能够合并的。 3.4 download \) repo download TARGET CHANGEupload是把改动内容提交到Gerritdownload是从Gerrit下载改动。与upload一样download命令也是配合Gerrit使用的。 指定要下载的PROJECT譬如platform/frameworks/base, platform/packages/apps/Mms指定要下载的改动内容。这个值不是Commit-ID也不是Change-ID而是一个Review任务URL的最后几位数字。 譬如AOSP的一个Review任务https://android-review.googlesource.com/#/c/23823/其中23823就是。 3.5 forall \( repo forall [PROJECT_LIST] -c COMMAND对指定的git库执行-c参数制定的命令序列。在管理多个git库时这是一条非常实用的命令。PROJECT_LIST是以空格区分的譬如 \) repo forall frameworks/base packages/apps/Mms -c git status表示对platform/frameworks/base和platform/packages/apps/Mms同时执行git status命令。 如果没有指定PROJECT_LIST那么会对repo管理的所有git库都同时执行命令。 该命令的还有一些其他参数 -r, –regex 通过指定一个正则表达式只有匹配的PROJECT才会执行指定的命令-p输出结果中打印PROJECT的名称 3.6 prune $ repo prune [PROJECT_LIST]删除指定PROJECT中已经合并的分支。当在开发分支上代码已经合并到主干分支后使用该命令就可以删除这个开发分支。 随着时间的演进开发分支会越来越多在多人开发同一个git库多开发分支的情况会愈发明显假设当前git库有如下分支
- masterdev_feature1_201501 # 已经合并到masterdev_feature2_201502 # 已经合并到masterdev_feature3_201503 # 正在开发中还有改动记录没有合并到master那么针对该git库使用prune命令会删除dev_feature1_201501和dev_feature2_201502。 定义删除无用的分支能够提交团队的开发和管理效率。prune就是删除无用分支的”杀手锏“。 3.7 start \( repo start BRANCH_NAME [PROJECT_LIST]在指定的PROJECT的上切换到BRANCH_NAME指定的分支。可以使用–all参数对所有的PROJECT都执行分支切换操作。 该命令实际上是对git checkout命令的封装BRANCH_NAME是自定义的它将追踪manifest中指定的分支名。 当第一次sync完代码后可以通过start命令将git库切换到开发分支避免在匿名分支上工作导致丢失改动内容的情况。 3.8 status \) repo status [PROJECT_LIST]status用于查看多个git库的状态。实际上是对git status命令的封装。
- 使用实践 Android推荐的开发流程是 repo init初始化工程指定待下载的分支repo sync下载代码repo start将本地git库切换到开发分支(TOPIC BRANCH)在本地进行修改验证后提交到本地repo upload上传到服务器等待review 在实际使用过程中我们会用到repo的一些什么子命令和参数呢哪些参数有助于提高开发效率呢下面我们以一些实际场景为例展开说明。 4.1 对项目清单文件进行定制 通过local_manifest机制能够避免了直接修改default.xml不会造成下次同步远程清单文件的冲突。 CyanogenMod(CM)适配了上百款机型不同机型所涉及到的git库很可能是有差异的。以CM对清单文件的定制为例通过新增local_manifest.xml内容如下 manifest!– add github as a remote source –remote namegithub fetchgit://github.com /!– remove aosp standard projects and replace with cyanogenmod versions –remove-project nameplatform/bootable/recovery /remove-project nameplatform/external/yaffs2 /remove-project nameplatform/external/zlib /project pathbootable/recovery nameCyanogenMod/android_bootable_recovery remotegithub revisioncm-10.1 /project pathexternal/yaffs2 nameCyanogenMod/android_external_yaffs2 remotegithub revisioncm-10.1 /project pathexternal/zlib nameCyanogenMod/android_external_zlib remotegithub revisioncm-10.1 /!– add busybox from the cyanogenmod repository –project pathexternal/busybox nameCyanogenMod/android_external_busybox remotegithub revisioncm-10.1 //manifestlocal_manifest.xml会与已有的default.xml融合成一个项目清单文件manifest.xml实现了对一些git库的替换和新增。 可以通过以下命令导出当前的清单文件最终snapshot.xml就是融合后的版本 \( repo manifest -o snapshot.xml -r在编译之前保存整个项目的清单有助于问题的回溯。当项目的git库发生变更需要回退到上一个版本进行验证的时候只需要重新基于snapshot.xml初始化上一个版本即可 \) cp snapshot.xml .repo/manifests/ \( repo init -m snapshot.xml # -m 参数表示自定义manifest \) repo sync -d # -d 参数表示从当前分支脱离切换到manifest中定义的分支4.2 解决无法下载Android源码 在repo init的时候会从远程下载manifests和repo这两个git库默认情况下这两个git库的地址都是写死在repo这个python脚本里面的。对于AOSP而言这两个git库的地址显然是google提供的。 但由于google访问受限的缘故会导致init时无法下载manifests和repo。这时候可以使用init的-u和–repo-url参数自定义这两个库的地址辅以–no-repo-verify来绕过代码检查。 \( repo init --repo-url [PATH/TO/REPO] -u [PATH/TO/MANIFEST] -b [BRANCH] --no-repo-verify \) repo sync4.3 更快更省的下载远程代码 repo默认会同步git库的所有远程分支的代码但实际开发过程中用到的分支是有限的。使用sync的-c参数可以只下载manifest中设定的分支这会节省代码下载时间以及本地的磁盘空间 \( repo sync -c如果实际开发过程中需要用到另外一个分支而又不想被其他分支干扰可以在已有的工程根目录下使用如下命令 \) repo manifest -o snapshot.xml -r \( repo init -u [PATH/TO/MANIFEST] -b [ANOTHER_BRANCH] \) repo sync -c -d以上命令序列相当更新了manifest而且仅仅只下载ANOTHER_BRANCH的代码这样本地只保存了两个分支的代码。利用保存的snapshot.xml还能将所有git库方便的切换回原来的分支。 如果本地已经有一份Android源码假设路径为~/android-exsit想要下载另一份新的Android源码通过–reference参数在数分钟以内就能将代码下载完毕 \( mkdir ~/android-new cd ~/android-new \) repo init –reference~/android-exsit -u [PATH/TO/MANIFEST] -b [BRANCH] \( repo sync -c4.4 避免在匿名分支上工作 在sync完代码后所有git库默认都是在一个匿名分支上(no branch)很容易会由于误操作导致丢失代码修改。可以使用如下命令将所有的git库切换到开发分支 \) repo start BRANCH –all4.5 使用upload提交代码 开发人员可能同时在多个git库甚至多个分支上同时进行修改针对每个git库单独提交代码是繁琐的。可以使用如下命令一并提交所有的修改 \( repo upload不用担心会漏提交或者误提交upload会提供一个交互界面开发人员选择需要提交的git库和分支即可。 如果需要省去Gerrit上填写reviewer的操作可以使用–reviewer参数指定Reviewer的邮箱地址 \) repo upload –reviewerR.E.viewergoogle.com4.6 定期删除已经合并的开发分支 Git鼓励在修复Bug或者开发新的Feature时都创建一个新的分支。创建Git分支的代价是很小的而且速度很快因此不用担心创建Git分支的成本而是尽可能多地使用分支。 随着时间的演进开发分支会越来越多而一些已经合并到主干的开发分支是没有存在价值的可以通过prune命令定期删除无用的开发分支 \( repo prune [PROJECT_LIST]4.7 同时操作多个git库 对于部分开发人员而言同时操作多个git库是常态如果针对每个git库的操作命令都是相同的那么可以使用如下命令一次性完成所有操作: \) repo forall -c git branch | grep tmp | xargs git branch -D; git branch参数-c指定的命令序列可以很复杂多条命令只需要用“;”间隔。 更详细的在这里Android源代码仓库及其管理工具Repo分析详解 参考https://www.jb51.net/article/232003.htm
- 上一篇: 北京网站建设建站网站空间和云服务器
- 下一篇: 北京网站建设联系电话科学小制作小发明
相关文章
-
北京网站建设建站网站空间和云服务器
北京网站建设建站网站空间和云服务器
- 技术栈
- 2026年03月21日
-
北京网站建设价格天外链吧官网
北京网站建设价格天外链吧官网
- 技术栈
- 2026年03月21日
-
北京网站建设技术托管余姚网站建设公司
北京网站建设技术托管余姚网站建设公司
- 技术栈
- 2026年03月21日
-
北京网站建设联系电话科学小制作小发明
北京网站建设联系电话科学小制作小发明
- 技术栈
- 2026年03月21日
-
北京网站建设联系电话泉州seo代理商
北京网站建设联系电话泉州seo代理商
- 技术栈
- 2026年03月21日
-
北京网站建设哪便宜温州seo服务
北京网站建设哪便宜温州seo服务
- 技术栈
- 2026年03月21日






