博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Repo Gerrit进阶
阅读量:5996 次
发布时间:2019-06-20

本文共 6239 字,大约阅读时间需要 20 分钟。

本文需要有对git repo gerrit的基本使用,

这里不提及过多的基本用法.

00. Books

  • ProGit/ProGit 2nd

    建议至少把 第2章 git基础 看一遍

  • Git权威指南

    建议仅看repo gerrit相关的章节

    Android式多版本库协同

    Gerrit代码审核服务器

01. Repo 的产生

Android版本库众多的原因,主要原因是版本库太大以及Git不能部分检出。
如果所有的东西都放在一个库中,而某个开发团队感兴趣的可能就是某个驱动,
或者是某个应用,却要下载如此庞大的版本库,是有些说不过去。

git也有submodule供多个库下载,但这功能使用不方便,

其局限性和麻烦可参看

如果是你,有什么方案来管理这么多的库?

Repo是Google开发的用于管理Android版本库的一个工具。
Repo并不是用于取代Git,是用Python对Git进行了一定的封装,简化了对多个Git版本库的管理。
对于repo管理的任何一个版本库,都还是需要使用Git命令进行操作

02. Repo 如何组织这么多库 --manifest文件?

......

从上看出,repo用清单文件来管理, 其内容为版本的地址,默认分支名,远程库和本地路径对应关系。

一个project对应一个库,path为本地切出来的工作目录的路径,也就是我们看到的代码路径,
name为对应的远程git库的名字/路径。
注意,一般说来,一套安卓代码都由好几百个库组成,上面只截取了一部分。

关于manifests更多的信息可查看你代码根目录的

.repo/repo/docs/manifest-format.txt

这里只说下revision,

  • 你可以在project里通过revision指定与清单文件default里不一样的分支,

revision的值可能是分支/tag/commitID等形式

  • 你也可以用repo manifest -r命令生成带revision信息的清单文件,可用于代码发布

生成的一个例子:

03. repo init 在干什么?

$repo init --helpUsage: repo init [options]Options:......  Manifest options:    -u URL, --manifest-url=URL                        manifest repository location    -b REVISION, --manifest-branch=REVISION                        manifest branch or revision    -m NAME.xml, --manifest-name=NAME.xml                        initial manifest file    --mirror            create a replica of the remote repositories rather                        than a client working directory    --reference=DIR     location of mirror directory    --depth=DEPTH       create a shallow clone with given depth; see git clone......  repo Version options:    --repo-url=URL      repo repository location    --repo-branch=REVISION

repo init用法如上, 我们一般下载code的方式为

repo init -u xxx -b yyy -m zzz.xmlrepo sync -c

注意

  • -m 当有多个清单文件,可以指定清单库的某个清单文件为有效的清单文件

repo init命令执行后主要干了两件事

  • 下载repo到.repo/repo里
  • 下载并检出-u所指定的manifest库,并建立.repo/manifest.xml链接

对于第一步大家可能比较疑问,不是已经有个repo了吗?为什么还在下载repo?

实际上,我们执行的repo命令只是相当于个当函数,真正的执行命令(如repo sync)
都是.repo/repo/subcmds里的,
该子命令都用python写的, 所以当有需要,或者执行出错时想查看源码的话可在此目录下查看.

04. --mirror --reference作用

让我们想个问题,假设你一套代码有100G,

  • 你们是异地协作协作,如需要上海/北京两地办公,主服务器在北京,网络很慢,
    如何为上海的同事减少下代码时间? 如何缓解主服务器的压力?
  • 你们都在一个地办公,多人公用一个服务器, 如何节省下载代码时间? 节省服务器空间?
  • 你作为SCM,每天都要完全clean编译版本, 如何更快的构建?

当然我们这只讲repo本身提供的方法,

  • --mirror 建立和上游Android的版本库一模一样的镜像
  • --reference 通过引用已下载的mirror或者代码加快下载速度,常用使用场景:

    • DailyBuild
    • 一套代码兼容多个机型
    • 一套代码需要多个副本
    • 多个人共用服务器

具体操作为

先通过

repo init .... --mirror

建立一个本地的镜像,

然后下载代码时引用这个镜像

repo init .... --reference=镜像路径repo sync -c

如果此时主服务器库容量增加到120G,而你的镜像没更新,

那么理论上新下载代码只需要下载20G的数据,
N套代码占用的空间为100G(镜像的) + 20G*N (新代码)
大家可用

du -sh .repo/

命令统计.

注意:

不用担心你用reference下的代码和主服务器的不同步,
git会自动进行三方对比的,保证能获取到-u 指定的地址里的代码是最新的.

05. Gerrit Change-Id

graph TD;  title(repo gerrit简单工作流程);  init(repo init/sync) --> start(repo start xxx --all);  start --> gitmodify(单个库的修改和git流程一样);  gitmodify --> upload(上传到Gerrit repo upload/git push);  upload --> review(审核 +1 +2);  review-- 通过 --> submit(Gerrit submit);  review-- 不通过 --> gitmodify;

Change-Id由git commit时调用.git/hooks/commit-msg钩子生成的,

gerrit靠该id来区分同一分支下是否为同一个提交,
事实上,只要gerrit未submit,可以在本地git commit XX --amend修正提交后,
可以再次提交,成为新的patchset,但提交号不变.

06. repo upload时gerrit帐号名与邮箱前缀不一致

repo upload时默认是用配置的邮箱前缀做为push的用户名,

如果您的邮箱前缀和gerrit账户名不一致,需要做如下配置

$ cat ~/.gitconfig[review "您的地址"]    username = 您的帐号名

07. Gerrit command

该功能可能SCM用得多,用于实现批处理脚本.

此处只看下用法

$ ssh -p 端口号 用户名@地址 gerritAvailable commands of gerrit are:   apropos              Search in Gerrit documentation   ban-commit           Ban a commit from a project's repository   create-account       Create a new batch/role account   create-branch        Create a new branch   create-group         Create a new account group   create-project       Create a new project and associated Git repository   flush-caches         Flush some/all server caches from memory   gc                   Run Git garbage collection   gsql                 Administrative interface to active database   ls-groups            List groups visible to the caller   ls-members           List the members of a given group   ls-projects          List projects visible to the caller   ls-user-refs         List refs visible to a specific user   plugin   query                Query the change database   receive-pack         Standard Git server side command for client side git push   rename-group         Rename an account group   review               Verify, approve and/or submit one or more patch sets   set-account          Change an account's settings   set-members          Modify members of specific group or number of groups   set-project          Change a project's settings   set-project-parent   Change the project permissions are inherited from   set-reviewers        Add or remove reviewers on a change   show-caches          Display current cache statistics   show-connections     Display active client SSH connections   show-queue           Display the background work queues   stream-events        Monitor events occurring in real time   test-submit   version              Display gerrit versionSee 'gerrit COMMAND --help' for more information.

08. cherry-pick rebase

这个可看下git书箱学习下,工作中也用得多,提高效率.

09. repo sync (-n -l)

-n -l参数解释如下:

-l, --local-only      only update working tree, don't fetch  -n, --network-only    fetch only, don't update working tree

其实repo sync = repo sync -n + repo sync -l

如果你只想获取更新到.repo库里, 不更新本地代码, 可加上 -n参数
如果你之前已经获取了更新,只有一两个库更新出错,
而你重新repo sync -c一次都得半小时,
那可以先repo sync -l, 然后单独的更新出错的库.

我一般更新都用命令

repo sync -c -frepo sync -c -l

备注:

再运行次加-l主要是更新时可能信息很多,中间有些出错,
而我有不想慢慢看终端找出错信息,所以干脆再让他更新下
本地工作目录,这样方便查找出错信息.

10. git pushInsteadOf

试想一下这样一个场景, 您的代码下载自A服务器, 现在要往B服务器push代码,该咋办?

当然, 您可用git remote添加远程信息,然后再用git push 新添加的远程名 ...
我这里讲另一个方法,就是pushInsteadOf,
eg:

vi ~/.gitconfig[url "testB_address"]    pushInsteadOf = testA_address

即,我们仅需要在gitconfig里配置一下,

push的时候用B服务器的地址,替换A服务器的地址,
这样我们push的时候,代码就提交到B服务器了.

同理,可用

pullInsteadOf 替换 pull时的地址
InsteadOfpush 替换 push和pull时的地址

BTW,对 ~/.gitconfig文件的修改,您也可用命令

eg:git config --global url.testB_address.insteadOf testA_address

11. Debug

有时候有些运行命令出错了,可加--trace参数查看更多信息

(git的调试方法请查看progit一书)
eg:

repo --trace sync -c

12. 建议

  • 新下载代码后,分支处于no branch状态,建议下载代码后用

    repo start 本地分支名 --all

    建个分支,该分支名为本地分支名,可任意取名

  • 该分支仅用于和服务同步,更新代码,要修改的话用repo start xx建立个新分支

    不然你本地在修改,服务器也修改,会造成历史记录很乱,
    有时导致编译出来的代码有啥隐含bug.
    当然,您也可用

    git pull --rebase

转载地址:http://hgqlx.baihongyu.com/

你可能感兴趣的文章
21.这个看起来有点简单
查看>>
C++重载运算符
查看>>
ubuntu11.10下MySQL的安装
查看>>
为什么我设置了<a>标签target="_self"后,还是不能在当前窗口打开.
查看>>
Go语言学习
查看>>
图表开发控件JavaScript Charts v3.20.13发布|附下载
查看>>
archlinux-netinstall安装
查看>>
alpha版、beta版、rc版的意思
查看>>
我的友情链接
查看>>
android 软键盘处理
查看>>
ln 命令
查看>>
光纤故障判断
查看>>
HTML与XHTML的区别
查看>>
未来十年我们拼什么?
查看>>
linux-ubuntu txt乱码
查看>>
入门级----黑盒测试、白盒测试、手工测试、自动化测试、探索性测试、单元测试、性能测试、数据库性能、压力测试、安全性测试、SQL注入、缓冲区溢出、环境测试...
查看>>
[1252]进制转换 sdutOJ
查看>>
composer 安装 ubuntu 12.04
查看>>
Vue开发与调试工具
查看>>
DES加密解密
查看>>