GIT & REPO & GERRIT (三)

来源:互联网 发布:万国数据美国 上市 编辑:程序博客网 时间:2024/05/17 01:40

GIT & REPO & GERRIT (三)

 399人阅读 评论(0) 收藏 举报
REPO
为什么会有 repo 和 gerrit,还是要先回头说一下git:因为 git 在最初设计的时候,作者希望的是做一个SCM(Source Code Management)的核心,这样其他人就可以在这个核心上面开发各种 SCM。虽然他后来做着做着,就做成了一个功能完整的 SCM,但这并不影响其最初的设计:Google 于是在 git 的基础上开发了 repo 和 gerrit。

根据前面的介绍,管理代码改动都是由 git 完成的,repo 在整个系统中主要担任了什么角色呢?repo 在实际使用中主要担任2个角色:
  • 和主代码服务器(gerrit)进行交互
  • 根据前面提到的一个xml(manifest.xml)来管理多个 git 仓库

下面就从一个常见的工作流程来说明repo是如何工作的。(Google 的官方说明的链接:http://source.android.com/source/using-repo.html)

repo init -u url -b branchname
这个初始化命令主要干了两件事:
  • 在当前目录里面下载安装 repo:对你没看错,就是安装 repo。因为最初你从网上下载的那个 repo 文件并不是一个完整的 repo,它主要负责初始化工作,并且在初始化完成以后将命令移交给完整的 repo 来执行。
  • 根据命令中指定的地址(-u url)去下载项目的管理文件 manifest.xml。我们前面说过这个 manifest.xml 是用 git 管理起来的,在这里 -b branchname 就是指的 manifest.xml 的相应 branch。(有兴趣的可以去.repo/manifests/文件夹下面执行 $git branch -r 试试。)

初始化的时候,repo 会在当前目录下面建立一个 .repo 目录,然后把刚才提到的从网上下载下来的所有文件都放在这个目录里面。

repo sync
同步所有的项目,作为一个开发人员,通常只需要改某个项目,所以常用的是下面的命令。

repo sync project
在执行 repo sync (project)的时候,它干的第一件事就是先把 .repo/manifests/ 下面的内容同步到最新,然后再根据最新的 manifest.xml 里面指定的属性来执行下一步操作,下一步的操作主要有2种情况:
  • 第一次下载一个项目:在 .repo/manifest.xml 里面找到你想要下载的项目,然后使用这个命令下载整个项目,相当于 git clone。git 通常是把代码仓库放在相应的文件夹下面的 .git 目录里面,但是 repo 在管理 git 仓库的时候,为了统一管理,是将所有的 .git 目录都按照相应的目录结构放到了 .repo/projects/ 下面。
  • 同步项目到最新:这时候,有另外一种方法,就是在当前项目的目录下面,直接 $repo sync . 就可以同步当前项目。repo sync 在这种情况下,相当于执行了的 git pull (git fetch & git merge),从远端取回最新代码,并将当前 branch 更新到最新。所以你需要主要你当前所在的 branch。

需要注意的是在任何情况下,在执行 repo sync 的时候,它干的第一件事就是先把 .repo/manifests/ 下面的内容同步到最新,然后再根据最新的 manifest.xml 里面指定的属性来执行下一步操作。

很多时候,用“.”都可以指代当前位置的项目,比如 $repo sync . $repo start branch . $repo upload . 等等。

repo start branch project
上一篇我们讲过在 git 里面使用 branch,但配合 repo 使用的时候,我们就要注意,如果我们希望这个 branch 是被 repo 管理起来的,那么我们就要使用 repo start 命令来新建一个 branch。比如这个 branch 改好了后,你是需要上传到 gerrit 进行 review,那么你就该使用 repo start。如果只是一个临时实验性的分支的话,就无所谓了。反正使用 repo start 也不会有什么坏处,所以放心的使用。删除 branch 的时候,依然是使用 git branch -d branchname。

repo upload project
当你准备好一个 commit 以后,就需要把这个改动传到 gerrit 上面等待别人 review,就需要用到 repo upload 了。如果这时候你突然想起你这个 branch 并不是用 repo start 建的怎么办呢?那就先用 repo start 建一个新的 branch,然后使用命令 git cherry-pick commitid 把刚才你做好的改动拿到这个分支来。(为什么是 cherry-pick 呢?我是这样理解的:cherry 是樱桃的意思,因为樱桃是很脆弱的水果,所以摘樱桃的时候要额外的小心。而在将一个改动拿到另一个地方的时候也需要非常的小心才可以的。)

当一个项目有多个改动的时候,repo 会提示你选择要上传哪些改动。而已经上传过的改动 repo 得会样子记录,可以避免重复操作。

manifest.xml
一个 repo 所管理的所有项目都记录在这个 .repo/manifest.xml,而这个文件通常是指向 .repo/manifests/default.xml。里面主要有几个需要注意的东西,先是 default 这个标签,看起来像这样:
   <default remote="origin" revision="master" />
这个标签一是指定了使用哪一个远程的 git 仓库,二是指定了所有它所管理的 git 的默认远程 branch。作为一个开发人员,我们主要关心的是后面这个。根据实际的情况,服务器上的每个项目通常会有不止一个 branch,而我们本地同步下来的代码是以哪个 branch 为基准呢?就是这个默认指定的 revision 了。在这个例子中,默认指定的就是远端的 master branch,那么我们同步到本地的就是 远端的 master branch,而我们在上传代码到 gerrit 的时候,目标也是往远端的 master 分支上面提交代码(其实只有在 review 通过以后,merge 的时候,才是真正的把代码提到 master 上面, repo upload 并不是直接将改动提到 master 上面的)。

然后就是 project 标签:
   <project path="aaa/bbb/ccc" name="ddd/eee" revision="release-3" />
这个指定了 repo 所管理的项目的位置和相应的名字。在使用 repo sync project 的时候,可以用 path 也可以用 name。而且当你的这个项目用的不是 master 的时候(根据上面的例子,所有的项目默认使用 master branch),你可以在 project 标签里面的 revision 属性单独指定这个项目所使用的远端 branch。

local_manifest.xml
有时候我们需要在本地指定一些不同的项目的属性,那怎么办呢?我们可以直接修改 .repo/manifest.xml 但是这样的话,会影响 repo 更新 manifest.xml 文件,这时候就用到 local_manifest.xml 了。在老一点的版本里面,直接将它放在 .repo 目录下面就可以了。在新的 repo 里面,需要在 .repo 目录下建一个 local_manifests 目录: .repo/local_manifests/。然后将你的 local_manifest 放在这个文件夹下面,名字以.xml结尾就可以了。

通常是先将原项目移除掉,然后再添加一个项目,指定不同的属性,示例如下:
   <?xml version="1.0" encoding="UTF-8"?>
   <manifest>
       <remove-project name="aaa/bbb/ccc" />
       <project name="aaa/bbb/ccc" path="ddd/eee" revision="another-branch" />
   </manifest>
将 local_manifest 准备好以后再 repo sync 一下相应的项目。然后在该项目下面使用 git branch -r 来查看就会发现你已经指定好了新的远端 branch。

小结
从上面我们可以看出,其实 repo 主要就是用于管理多个 git 项目(manifest.xml),并完成和 gerrit 服务器的交互的操作(init,sync,start,upload)。虽然不在不了解其工作原理的时候也能使用它,但是在了解了它的工作原理以后,就能够更好的使用它。

0 0
原创粉丝点击