您的位置:首页 > 其它

怎么针对自己项目工程建立Repo管理多个git仓库?

2017-12-05 11:19 543 查看
作者: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文件是什么样的。

<?xml version="1.0" encoding="UTF-8"?>

<manifest>

<remote fetch="git://http://xxx.xxx.xxx"
name="origin" review="
http://xxx.xxx.xxx:8080"/>

<default remote="origin" revision="main_dev"/>

<project name="platform/mediatek/modem/buildscript" path="buildscript">

<copyfile dest="m" src="m"/>

<copyfile dest="Make.bat" src="Make.bat"/>

<copyfile dest="make.pl" src="make.pl"/>

<copyfile dest="make.sh" src="make.sh"/>

<copyfile dest="M.bat" src="M.bat"/>

<copyfile dest="BuildMMAA.pl" src="BuildMMAA.pl"/>

</project>

<project name="platform/mediatek/modem/driver" path="driver"

revision="352b1d8fb184a0169c6a17b5f6a858730fc51966"

upstream="main_release" />

<project name="platform/mediatek/modem/make" path="make"

revision="main_release" />

<project name="platform/mediatek/modem/middleware" path="middleware"

revision="tag_20160316" />

<project name="platform/mediatek/modem/modem" path="modem" />

<project name="platform/mediatek/modem/mtk_rel" path="mtk_rel"/>

<project name="platform/mediatek/modem/custom" path="custom"/>

<project name="platform/mediatek/modem/tools" path="tools"/>

<project name="platform/mediatek/modem/interface" path="interface"/>

<project name="platform/mediatek/modem/service" path="service"/>

</manifest>

先看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。

<?xml version="1.0" encoding="UTF-8"?>

<manifest>

<remote fetch="git://http://xxx.xxx.xxx"
name="origin" review="
http://xxx.xxx.xxx:8080"/>

<default remote="origin" revision="master"/>

<project name="platform/Hello" path="Hello">

<copyfile dest="Make.mk" src="Make.mk"/>

<copyfile dest="ProjectConfig.mk" src="ProjectConfig.mk"/>

</project>

<project name="platform/World" path="World"/>

<project name="platform/Nihao" path="Nihao"/>

</manifest>

这份manifest描述了以下信息:这份代码由3个git(里面的3个project)组成;Hello/底下的2个mk文件在repo sync后会被拷贝到代码根目录下;这3个git用的都是default revision中描述的分支master。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  repo git 管理