tools:对自己项目工程建立Repo管理多个git仓库?

作者:Elpie Kay
链接:https://www.zhihu.com/question/41440585/answer/91102156
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

通常repo通过以下两个命令来下载代码:
repo init -u git://http://xxx.xxx.xxx/platform/manifest -b $branch -m $manifest --reference=$mirror
repo sync

repo init会在当前目录下创建.repo文件夹,然后将git://http://xxx.xxx.xxx/platform/manifest从中心服务器上clone到.repo里生成manifests和manifests.git。platform/manifest是一个git,用来存放manifest文件。它的每个分支里都必须有一个名为default.xml的文件。因为-m $manifest这个参数是可以省略的,省略的话就相当于-m default.xml。之后repo sync会去解析-m指定的manifest,根据里面的配置去clone组成整个项目的各个git。--reference参数是可选的,后面接的是镜像代码库的路径,一般用不到这个。

 

下面举个实际的例子,看下manifest文件是什么样的。












revision="352b1d8fb184a0169c6a17b5f6a858730fc51966"
upstream="main_release" />
revision="main_release" />
revision="tag_20160316" />






 

先看remote部分,fetch是服务器地址,可以用“..”来代替;name是默认的remote name,就是git push origin里面那个origin;review是gerrit地址(这点是我猜的,不确定)。

 

然后是default部分,里面定义了默认的remote和revision。

 

下面是project部分,这部分定义了整包代码由哪些git组成。name是git在服务器上的相对路径,path是把代码下载下来后在本地的相对路径,path是可以省略的,如果省略那么就认为path和name一样,revision是指下载下来的代码要checkout到哪个revision上,这里的revision可以是commit id、branch name、tag name,反正本质上都是commit id。利用branch name的特性,revision写branch name的话,那总可以下载到并且checkout出该branch上最新的代码,default.xml中通常用branch name做revision。而commit id和tag name就是固定的某个commit了。如果revision用commit id的话,那后面必须跟上upstream,upstream的值是个branch name。revision部分如果省略的话,就等于使用default部分定义的revision。project还有个group属性,但我没实际用过,就不展开了。还有copyfile部分,这是用来处理一些无法或者不方便直接归类到某个git中去的文件的,譬如项目代码根目录下的几个零散文件,这几个文件所在目录做成一个git的话,等于把整包代码做成了一个git。虽然git是可以嵌套的,但这样不方便。repo的做法是将这些文件先放到某个已知git中去,本例就是先放到project buildscript里面去。当然,放到某个git里去的动作是由你来做的。然后下载完后再将它们copy到应该在的地方,本例就是根目录下。dest是相对于根目录的路径,src是相对于project path的路径。

 

这样一个manifest就可以定义一个完整的项目代码了。里面的值大致用于以下命令:
git clone $fetch/$name -b $upstream -- $path
git checkout $revision
cp $path/$src $dest

 

通过自由组合project和revision,就可以做出各种搭配的项目代码了。

 

常用的几个repo 命令:
repo sync -j 6 -m $manifest
sync时可以重新指定一个manifest,如果这个manifest在.repo/manifests里面,那么只要填它相对于.repo/manifests的路径,否则要填它的全路径。

 

repo manifest -r -o $name
根据当前代码生成一份manifest,这通常用于记录当前所有git的快照,这样以后或者别人、编译服务器可以根据这个manifest下载到那份代码。

 

repo forall -p -c '$command'
在每个project下执行一次command,-p会打印出当前在哪个project下,-p可选的。command的内容根据需求来写。

 

repo有个常用的环境变量$REPO_PROJECT,值是当前project的name。

 

譬如可以用repo forall -p -c 'git remote add server1 git://http://xxx.xxx.xxx/$REPO_PROJECT'来给每个git添加一个remote server1。

 

更新:

@Shreker

google repo本来是用于管理android系统源码的,这份源码不同的版本一般都由450个左右的git组成。现在将问题简化一下,假如有一份代码,目录结构如下:
myApp/
--Hello/
----hello.java
----Make.mk
----ProjectConfig.mk
--World/
----world.java
--Nihao/
----nihao.java
--Make.mk
--ProjectConfig.mk

 

将这份代码拆分成三个git,Hello, World和Nihao。现在要用repo将它们组织起来,组成一份完整的代码myApp。这3个git都有两个branch,master和release。下面是给master用的default.xml。服务器上还有一个git叫platform/manifest,对应的也建了2个branch,分别存放master和release相关的manifest。











这份manifest描述了以下信息:这份代码由3个git(里面的3个project)组成;Hello/底下的2个mk文件在repo sync后会被拷贝到代码根目录下;这3个git用的都是default revision中描述的分支master。

你可能感兴趣的:(tools)