赞
踩
一. repo简介
repo是Google开发的用于管理Android版本库的一个工具,repo是使用Python对git进行了一定的封装,并不是用于取代git,它简化了对多个Git版本库的管理。用repo管理的版本库都需要使用git命令来进行操作。
1 介绍清单库文件
<manifest>
<remote fetch="ssh://10.XX.XX.XX" name="origin" review="10.XX.XX.XX:8090"/>
<default remote="origin" revision="develop" sync-j="4"/>
<project groups='all' name="XXX/XXX" path="XXX/XXX" remote="origin" revision="develop">
<linkfile dest="XX/XX/" src="../.."/>
<copyfile dest="XX/XX/XX.txt" src="./xx.txt"/>
</project>
<project name="XXX/repohooks" path="XXX/XXX" remote="origin" revision="develop"/>
<repo-hooks enabled-list="post-sync" in-project="XXX/repohooks"/>
</manifest>
清单文件是以xml的格式组织的,一个清单库可以包含多个清单文件和多个分支,每个清单文件和分支都有对应的版本。
常用参数:
1.1 remote 描述了远程仓库的基本信息
name:远程仓库的名称,通常我们看到的命名是origin
fetch:git库地址
review:用作code review的server地址
1.2 project: 每一个repo管理的git库,就是对应到一个标签
path:把代码下载到指定目录下
name:该项目远程版本库的相对路径
groups:该项目远程版本库所属组
revision:单独指定分支
remote:单独指定远程版本库名称
1.3 default元素: default标签定义的属性,将作为标签的默认属性,在标签中,也可以重写这些属性
revision:默认分支
remote:默认的远程版本库名称
sync -j:表示在同步远程代码时,并发的任务数量
1.4 :project元素下的子元素copyfile,定义clone后从src到dest拷贝操作。
1.5 :project元素下的子元素linkfile,定义clone后dest到src的软连接。
1.6 :repo钩子,in-project下面应该有一个与钩子同名的python文件。因此,如果您想支持预上传钩子,您需要创建一个名为post-sync.py的文件。Repo将在处理钩子时动态加载该模块,然后调用其中的主函数。
in-project:定义挂钩的项目。该值必须与先前定义的元素的name属性(而不是属性)匹配。
enabled-list:要使用的钩子列表,空格或逗号分隔。
1.7 remove-project
从内部的manifest表中删除指定的project。经常用于本地的manifest文件,用户可以替换一个project的定义。
2 下载repo代码
新建项目存放的文件夹
mkdir mstar648
进入到项目文件夹
cd mstar648
执行代码拉取的命令
repo init -u ssh://ppgerrit.com/Mstar648/manifest.git -b 648_cultraview -m ppos4.5.0_cultraview.xml
此时会在当前目录下生成一个.repo的文件。
二.repo常用命令
1 解析拉取代码的命令(repo init)
Usage:
repo init -u URL [OPTIONS]
Options:
-u:指定manifest项目清单库地址。
-m,–manifest-name:指定manifests库中的清单文件,默认为maniftests/default.xml。
-b, –manifest-branch:指定manifest仓的分支,默认为master分支。
-g:指定manifests库中的组来下载代码,默认为all。
不常用参数:
–-repo-url:指定远程repo库地址,当引导脚本中的地址不可访问时,可以通过该参数指定可访问的repo地址。
–-repo-branch:同manifest这个git库一样,repo这个git库也是有版本差异的,可以通过该参数来指定下载repo这个远程git库的特定分支。
–-no-repo-verify:在下载repo库时,会对repo的源码进行检查。通过–repo-url指定第三方repo库时,可能会导致检查不通过,所以可以配套使用该参数,强制不进行检查。
--depth {number}:限制下载记录次数,加速代码下载。
例如我们拉取代码的时候的命令如下:
repo init -u ssh://ppgerrit.com/Mstar648/manifest.git -b 648_cultraview -m ppos4.5.0_cultraview.xml
repo init要完成如下操作:
完成repo工具的完整下载,执行的repo脚本只是引导程序
clone清单库manifest.git (地址是-u后面的参数)
clone的清单库位于manifest.git中,clone到本地.repo/manifest中,.repo/manifest.xml只是符号链接,它指向的是.repo/manifests/default.xml
如果manifest中有多个xml文件,repo init可以任意选择其中一个,默认选择的是default.xml。
上面的拉取代码示例选择的是ppos4.5.0_cultraview.xml里面的配置,那么.repo/manifest.xml指向.repo/manifests/ppos4.5.0_cultraview.xml
2 同步代码(repo sync)
Usage:
repo sync [<project>...]
常用参数:
-j:开启多线程同步操作,这会加快sync命令的执行速度。该参数在default.xml中有默认设置。
-c, –current-branch:只同步指定的远程分支。默认情况下,sync会同步所有的远程分支。
不常用参数:
-d, –detach:脱离当前的本地分支,切换到manifest.xml中设定的分支。
-f, –force-broken:当有git库sync失败了,不中断整个同步操作,继续同步其他的git库。
–no-clone-bundle:在向服务器发起请求时,为了做到尽快的响应速度,会用到内容分发网络(CDN, Content Delivery Network)。
执行了repo init 命令后,我们需要执行如下命令同步代码:
repo sync -c -q -j8
命令说明:
下载远程代码,并将本地代码更新到最新,这个过程称为“同步”。如果不使用任何参数,那么会对所有repo管理的git仓进行同步操作;也可以通过使用PROJECT_LIST参数,指定若干要同步的PROJECT。 根据本地git库代码不同,同步操作会有不同的行为:
1> 当本地的git库是第一次触发同步操作时。该命令等价于git clone,会将远程git库直接拷贝到本地。
2> 当本地已经触发过同步操作时。该命令等价于git remote update && git rebase origin/,就是当前与本地分支所关联的远程分支。在代码合并时可能会产生冲突,当冲突出现时,只需要解决完冲突,然后执行git rebase --continue即可。
git remote update
相当于对每一个remote源执行了fetch操作
git rebase origin/branch
对当前分支的跟踪分支执行rebase操作
3.repo upload 上传代码
repo upload [PROJECT_LIST]
命令说明:
将本地的新增或者修改代码上传到远程服务器。upload命令首先会找出本地分支从上一次同步操作以来发生的改动,然后会将这些改动生成Patch文件,上传至Gerrit服务器。 如果没有指定PROJECT_LIST,那么upload会找出所有git库的改动;如果某个git库有多个分支,upload会提供一个交互界面,提示选择其中若干个分支进行上传操作。
执行repo upload之前,需保证代码已经commit。
不常用参数:
-re
当有多个git库的改动提交时,为了避免在网页上频繁的填选Reviewer这种重复劳动, upload提供了–re, –reviewer参数,在命令行一次性指定Reviewer。
4 创建并切换分支(repo start)
Usage:
repo start <BRANCH_NAME> [<PROJECT_LIST>]
repo start 的实质就是对git checkout -b 的封装
常用参数:
--all:对所有的PROJECT都执行分支切换操作
刚clone下来的代码是没有分支的,例如:
repo start 的实质就是对git checkout -b 的封装,可以为单个项目或所有项目以清单文件中已设定的分支为基础,在本地创建新的分支。
repo start 与 git checkout -b 的区别:
repo start 是在清单文件设定的分支基础上创建新的分支
git checkout -b 是在当前所在分支的基础上创建新的分支
如果清单文件中设定的分支是remoteBranchName,创建新的分支localBranchName。
**单个项目创建localBranchName分支的命令如下:**
repo start localBranchName 项目绝对路径
**为所有项目创建localBranchName分支的命令如下:**
repo start localBranchName --all
5 查看分支(repo branches)
Usage:
repo branches [<project>...]
本文下面所有的命令都是在单个项目中运行!!!
例如查看上面拉取的mstar648项目下各模块的分支信息
在mstar648项目下运行如下命令:
repo branches
6 切换分支(repo checkout)
Usage:
repo checkout <branch name> [<project>...]
该命令实际是对git checkout命令的封装。检出之前由repo start创建的分支。
切换分支语法:
repo checkout brancnName
7.查看工作区文件差异(repo diff)
Usage:
repo diff [<project>...]
Example:
repo diff ---查看所有项目
repo diff platform/build platform/bionic ---只查看其中两个项目
实际是对git diff命令的封装,用于分别显示各个项目工作区下的文件差异。
8 repo stage(把文件添加到index表中)
实际是对git add –interactive命令的封装、用于挑选各个项目工作区中的改动以加入暂存区。
Usage:
repo stage -i [<project>…]
-i代表git add –interactive命令中的–interactive,给出个界面供用户选择。
9 repo prune(删除已经合并分支)
实际上是对git branch –d命令的封装,该命令用于扫面项目的各个分支,并删除已经合并的分支,用法如下:
repo prune [<project>…]
命令说明:
删除指定PROJECT中,已经合并的分支。当在开发分支上代码已经合并到主干分支后,使用该命令就可以删除这个开发分支。随着时间的演进,开发分支会越来越多,在多人开发同一个git库,多开发分支的情况会愈发明显,假设当前git库有如下分支:
master
dev_feature1_201501 # 已经合并到master
dev_feature2_201502 # 已经合并到master
dev_feature3_201503 # 正在开发中,还有改动记录没有合并到master
那么,针对该git库使用prune命令,会删除dev_feature1_201501和dev_feature2_201502。
10. 查看文件状态(repo status)
该命令实际上是对git diff-index 和git diff-filse命令的封装,同时显示暂存区的状态和本地文件修改的状态
查看文件状态语法:
repo status [<PROJECT_LIST>] 其中: 每个小节的第一行显示的是项目名称和所在的分支名称 每个小节的第二行的第一个字母表示暂存区文件修改的状态 -:没有改变 A:添加(不在HEAD中,在暂存区中) M:修改(在HEAD中,在暂存区中,内容不同) D:删除(在HEAD中,不在暂存区) R:重命名(不在HEAD中,在暂存区,路径修改) C:拷贝(不在HEAD中,在暂存区,从其他文件拷贝) T:文件状态改变(在HEAD中,在暂存区,内容相同) U:未合并,需要冲突解决 每个小节的第二行的第二个字母表示工作区文件的更改状态 -:新/未知(不在暂存区,在工作区) m:修改(在暂存区,在工作区,被修改) d:删除(在暂存区,不在工作区
11. 删除指定分支(repo abandon)
该命令实质是对git branch -D的封装,语法如下:
repo abandon branchName
12 设置远程仓库(repo remote)
语法如下:
repo remote addd remoteName url
例如:
repo remote add org ssh://172.16.1.31/git_repo
该命令是根据xml文件添加的远程分支,方便于向服务器提交代码,执行后的build目录下看到新的远程分支是org。
13 遍历当前项目下的所有git仓库(repo forall)
该命令相当于一个迭代器,会遍历当前项目下所有的git仓库,在所有指定的项目中执行同一个shell命令。
语法如下: repo forall [PROJECT_LIST] -c <COMMAND> 其中,参数有: -c:后面可以带的任何可以被系统支持的shell命令(ls,cp,pwd等) -p:在shell命令输出之前列出项目名称 -v:列出执行shell指令输出的错误信息 该命令还可以添加环境变量: 环境变量的参数有如下几种: REPO_PROJECT:指定项目的名称 REPO_PATH:指定项目在工作区的相对路径 REPO_REMOTE:指定项目远程仓库的名称 REPO_LREV:指定项目最后一次提交服务器仓库对应的哈希值 REPO_RREV:指定项目在克隆时的指定分支,manifest里的revision属性 如果-c后面的shell指令是上述的环境变量,则需要用单引号把shell指令括起来。
语法如下:
repo forall –c ‘echo $REPO_PROJECT’
14.添加环境变量
repo forall –c ‘echo $REPO_PROJECT’
repo forall –c ‘echo $REPO_PATH’
15 合并多个分支(merge)
例如将所有项目都切换到master分支。
repo forall -p -c git merge local
上面的命令就是将local分支合并到master分支上
16 打标签(tag)
在所有项目下打标签的命令如下:
repo forall -c git tag 标签名
17 显示版本号(repo version)
repo安装后,可以通过repo version命令查看版本号。
15.branch(创建特性分支)
repo forall –c git branch crane-dev
repo forall –c git checkout –b crane-dev
18.repo download 下载代码
repo download <TARGET> <CHANGE>
命令说明:
download是从Gerrit下载改动代码。
<TARGET>:指定要下载的PROJECT,譬如Tapp/eCommApp
<CHANGE>:指定要下载的改动内容的change_number。
19.repo manifest 查看manifest
repo manifest -r -o %s_manifest.xml
常用参数:
-r:保存当前分支revisions。
-o NAME.xml:输出xml文件名。
命令说明:
用于显示manifest文件内容。
三.实际需求:
1.repo重新与服务器同步(仅适用于只修改了文件,没有增加文件和变换文件存放位置)
repo forall -c git reset --hard HEAD
repo sync -c -q -j8
2.当我们repo init通过-b指定一个分支时,比如主分支maindev,但是具体仓库下面可能是其他分支情况。
可以通过.repo/manifests下查找对应的分支情况。
grep -nr “当前本地分支” ./
具体结果解析为:
name: gerrit服务器上远程分支名
path: 本地仓库实际路径
upstream:当前对应分支名
3.repo忽略本地修改,强制恢复初始
# 将HEAD强制指向manifest的库,而忽略本地的改动。 repo sync -d # Remove all working directory (and staged) changes. repo forall -c 'git reset --hard' # Clean untracked files repo forall -c 'git clean -f -d' # 拉代码 repo sync -c -q -j16 此时拉下来的代码,没有指向具体分支。 HEAD detached at d928195607 nothing to commit, working tree clean 需要使用如下命令 创建本地分支并切换到该分支上去。 repo start master-branch --all 这个master-branch名字即是远程分支名也是本地分支名字。
4.查看当前仓库对应的分支
1.repo init 下载repo
2.cd .repo/manifests/submanifests/ 查看对应的xml,
如android_aosp.xml android_platform.xml
3.grep -nr "vendor/external/ffmpeg" *
4.可以得出该仓库对应的远程分支名
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。