1 什么是repo
repo只是google用Python脚本写的调用git的一个脚本,主要是用来下载、管理Android项目的软件仓库。既然repo是google用来管理Android的工具,那跟我们有什么关系呢?好用,所以就拿过来呗,反正不要钱。使用repo还是因为我们的版本控制迁移到了git上来管理,由于git的一些局限性,如果没有repo,要管理项目仓库会很繁琐。
2 repo在公司项目上的使用
2.0 git的安装
Ubuntu上直接sudo apt-getinstall git-core git-doc就ok了,git-core就是git,git-doc是帮助文档。
2.1 获取repo
标准的repo当然是在google家了,我们这里需要用公司修改定制的repo。
这个实际上就是一个脚本,我们获取的repo可以说只是一个引导脚本,整个repo是一系列的脚本,我们将会在后面看到。将这个repo放到你的/usr/local/bin下,chmod a+x repo 加上可执行权限。
2.2 ssh密钥生成
我们的项目git共享仓库采用ssh协议传输,这里生成一对ssh密钥,将公钥加到服务器上,就可以实现免密码了。
生成pub key:
执行ssh-keygen -t rsa,一直回车
会在你的home目录的.ssh/目录下生成id_rsa.pub(公钥)和id_rsa(私钥)。
将id_rsa.pub发送给系统管理员就可以了。
当我们用ssh协议和服务器通信的时候,就使用这一对密钥进行认证,这样就不用每次都输入密码了。
2.3 使用repo初始化本地仓库
有了以上的基础工作后,我们就可以使用repo来初始化本地仓库了。
作为演示,这里创建一个test的目录
创建一个test目录
zenghui@ubuntu:~/git$ mkdir test
zenghui@ubuntu:~/git$ cd test/
使用repo初始化:
zenghui@ubuntu:~/git/test$ repo init -u git@svn.sys.sunniwell.net:linux-sunniwell.git/projects/huawei-base-manifest.git-b develop
-u参数指定url
-b 参数指定分支,你需要用哪个分支就写哪个分支,从之后的命令可以看出我们现在有以下的分支:
* [new branch] ctc30 -> origin/ctc30
*[new branch] develop -> origin/develop
*[new branch] ipv6 -> origin/ipv6
*[new branch] master -> origin/master
*[new branch] widening -> origin/widening
我们这里使用的就是develop分支。
命令的执行结果如下:
Getting repo ...
from git@svn.sys.sunniwell.net:linux-sunniwell.git/git-repo
remote: Counting objects: 1130, done.
remote: Compressing objects: 100%(418/418), done.
remote: Total 1130 (delta 763), reused 1003(delta 689)
Receiving objects: 100% (1130/1130), 321.78KiB | 186 KiB/s, done.
Resolving deltas: 100% (763/763), done.
From svn.sys.sunniwell.net:linux-sunniwell.git/git-repo
*[new branch] master -> origin/master
*[new branch] stable -> origin/stable
Getgit@svn.sys.sunniwell.net:linux-sunniwell.git/projects/huawei-base-manifest.git
remote: Counting objects: 136, done.
remote: Compressing objects: 100%(105/105), done.
remote: Total 136 (delta 34), reused 0(delta 0)
Receiving objects: 100% (136/136), 448.55KiB | 184 KiB/s, done.
Resolving deltas: 100% (34/34), done.
Fromsvn.sys.sunniwell.net:linux-sunniwell.git/projects/huawei-base-manifest
*[new branch] ctc30 -> origin/ctc30
*[new branch] develop -> origin/develop
*[new branch] ipv6 -> origin/ipv6
*[new branch] master -> origin/master
*[new branch] widening ->origin/widening
Your identity is: zenghui<zenghui@sunniwell.net>
If you want to change this, please re-run'repo init' with --config-name
repo initialized in /home/zenghui/git/test
命令结果输出解释:
Getting repo ...
from git@svn.sys.sunniwell.net:linux-sunniwell.git/git-repo
--》更新repo,上面这个地址是/usr/local/bin/repo里面配置的
REPO_URL='git@svn.sys.sunniwell.net:linux-sunniwell.git/git-repo'
这个repo不是标准的,而是根据公司的实际情况作了修改。
Getgit@svn.sys.sunniwell.net:linux-sunniwell.git/projects/huawei-base-manifest.git
--》这里才开始初始化清单库
*[new branch] ctc30 -> origin/ctc30
*[new branch] develop -> origin/develop
*[new branch] ipv6 -> origin/ipv6
*[new branch] master -> origin/master
*[new branch] widening -> origin/widening
--》以上是所有分支,我们这里用的是develop分支
repo initialized in /home/zenghui/git/test
--》初始化完成
初始化完成了,我们看看目录下面有什么变化:
zenghui@ubuntu:~/git/test$ ls -a
. .. .repo
多了一个.repo的隐藏文件夹
再看看.repo里面都有些啥:
zenghui@ubuntu:~/git/test$ ls -al .repo/
total 20
drwxr-xr-x 5 zenghui zenghui 40962012-06-05 14:48 .
drwxr-xr-x 3 zenghui zenghui 40962012-06-05 14:47 ..
drwxr-xr-x 3 zenghui zenghui 40962012-06-05 14:48 manifests //里面只有一个清单库default.xml
drwxr-xr-x 9 zenghui zenghui 40962012-06-05 14:48 manifests.git //mainfest库的克隆
lrwxrwxrwx 1 zenghui zenghui 21 2012-06-05 14:48 manifest.xml ->manifests/default.xml //清单库的链接
drwxr-xr-x 7 zenghui zenghui 40962012-06-05 14:47 repo //repo实现的克隆,里面藏着repo的所有脚本
2.4 repo init都干了些啥
实际上repo init只是下载了项目的清单库,我们来看看这个清单库长啥样儿吧。
zenghui@ubuntu:~/git/test/.repo$ catmanifests/default.xml
<?xml version="1.0"encoding="UTF-8"?>
<manifest>
<remote name="origin" //远程版本库
fetch="ssh://git@svn.sys.sunniwell.net/linux-sunniwell.git/" //版本库的基址
review="review.sys.sunniwell.net" /> //代码审核服务器
<default revision="develop" remote="origin" /> //默认分支为"develop",远程版本库"origin"
<project name="build" path="swapi/build" /> //这以后的都是定义project,name指向远程版本库的相对路径,path指明工作区克隆的路径。
<project name="swapi/pub/swapi-pub-base"path="swapi/pub/base" />
<projectname="swapi/src/swapi-src-base" path="swapi/src/base" />
<project name="swapi/pub/swapi-pub-common"path="swapi/pub/common" />
<project name="swapi/src/swapi-src-common"path="swapi/src/common" />
<project name="swapi/pub/swapi-pub-network"path="swapi/pub/network" />
<project name="swapi/src/swapi-src-network"path="swapi/src/network"/>
<project name="swapi/pub/swapi-pub-media"path="swapi/pub/media" />
<project name="swapi/src/swapi-src-media"path="swapi/src/media" />
<project name="swapi/pub/swapi-pub-extdev"path="swapi/pub/extdev" />
<project name="swapi/src/swapi-src-extdev"path="swapi/src/extdev" />
<project name="swapi/pub/swapi-pub-platform"path="swapi/pub/platform" />
<project name="swapi/src/swapi-src-platform" path="swapi/src/platform"/>
<project name="swapi/pub/swapi-pub-upgrade"path="swapi/pub/upgrade" />
<project name="swapi/src/swapi-src-upgrade"path="swapi/src/upgrade" />
<project name="modules/pub/modules-pub"path="modules/pub" />
<project name="modules/src/modules-src"path="modules/src" />
<project name="linux/pub/linux-pub"path="linux/pub" />
<project name="parts/pub/parts-pub"path="parts/pub" />
<project name="tools/pub/tools-pub"path="tools/pub" />
<project name="tools/src/tools-src"path="tools/src" />
<project name="resources/resource-base-zh-hd"path="resource/base-zh-hd"/>
<project name="resources/resource-base-en-hd"path="resource/base-en-hd"/>
<project name="resources/resource-base-zh-sd"path="resource/base-zh-sd"/>
<project name="resources/resource-base-en-sd"path="resource/base-en-sd"/>
<project name="applications/huawei-swapp-base"path="swapp" />
<project name="middlewares/huawei-base-middleware"path="middleware"/>
</manifest>
这里面包含了develop分支的所有版本库。
2.5 repo sync 仓库添砖加瓦
初始化完成之后就可以用repo sync来同步项目了。
也可以用repo sync project_name来只同步名为project_name的项目。
这里的project_name应该是上面的default.xml中project元素的name指向名称,也就是远程版本库的路径。以<project name="build" path="swapi/build"/>为例,我们只想同步这个project就应该用:
zenghui@ubuntu:~/git/test$ repo sync build
remote: Counting objects: 95, done.
remote: Compressing objects: 100% (95/95),done.
remote: Total 95 (delta 52), reused 0(delta 0)
Unpacking objects: 100% (95/95), done.
Fromssh://svn.sys.sunniwell.net/linux-sunniwell.git/build
*[new branch] develop -> origin/develop
*[new branch] recovery -> origin/recovery
再看看,工作区中多了swapi的目录,里面还有一个build的目录。
zenghui@ubuntu:~/git/test$ tree
.
`-- swapi
`-- build
|-- bcm7213.Makefile
|-- bcm7401.Makefile
|-- bcm7403.Makefile
|-- bcm7405.Makefile
|-- common.Makefile
|-- core.Makefile
|-- em8620.Makefile
|-- hi3560e.Makefile
|-- hi3560.Makefile
|-- hi3716.Makefile
|-- hi3716M.Makefile
|-- porting.Makefile
|-- sigma.Makefile
|-- st7105.Makefile
|-- x86linux.Makefile
`-- x86win32.Makefile
2 directories, 16 files
这里只是为了演示一下repo sync,没有整个项目sync,也正好演示了对单个project的同步。
如果我们这这里给整个项目repo sync,那么就掩盖了一些git的知识。
让我们来看看抛开repo,我们应该怎样来下载(?还是叫checkout?实际应该叫clone)一个项目呢?
我们需要使用到git clone命令,为什么叫clone,而不是像svn那样叫checkout呢,关于这个在讲git的时候再表。
zenghui@ubuntu:~/git/test$git clonessh://git@svn.sys.sunniwell.net/linux-sunniwell.git/swapi/pub/swapi-pub-networkswapi/pub/network
Initialized empty Git repository in/home/zenghui/git/test/swapi/pub/network/.git/
remote: Counting objects: 331, done.
remote: Compressing objects: 100%(315/315), done.
remote: Total 331 (delta 162), reused 0(delta 0)
Receiving objects: 100% (331/331), 3.02 MiB| 354 KiB/s, done.
Resolving deltas: 100% (162/162), done.
warning: remote HEAD refers to nonexistentref, unable to checkout.
第一个参数是远程版本库的路径,第二个参数是本地仓库的路径。
看看命令执行完我们的工作目录有什么变化:
zenghui@ubuntu:~/git/test/swapi/pub/network$ls -a
. .. .git
只是多了一个.git的目录,我的项目文件呢???不要着急,我们的远程版本库是一个裸版本库(bare),没有工作区,所以克隆下来也没有工作区,需要我们checkout出来。
zenghui@ubuntu:~/git/test/swapi/pub/network$git checkout -t origin/develop
Branch develop set up to track remotebranch develop from origin.
Switched to a new branch 'develop'
再看看目录有什么变化:
zenghui@ubuntu:~/git/test/swapi/pub/network$ls -a
. .. .git .gitignore include libs
好神奇啊,我们的项目文件马上就出来了,但是我们明明看到是git clone的时候有下载3.02M的文件,而git checkout的时候并没有网络操作,这是为什么呢?其实clone的时候已经将仓库下载下来了,.git这个目录就是仓库,checkout的时候只是将这个仓库里的内容checkout到你的工作区。听起来有点儿浆糊了吧,先糊着吧,这个还得讲git的时候才能讲的清。
到这里你可能还是不知道repo到底有啥用,我们敲一个reposync,repo就会根据default.xml的内容,遍历的讲里面的project全部clone并且checkout到你的工作区,repo实际上就是讲git的命令做了一些封装,便于管理多个代码仓库。如果不用repo,我们就需要将default.xml里面的几十个project一个一个的clone,checkout,你肯定在心里嘀咕“你傻啊,写个脚本不就完了吗”,写个脚本?你才傻呢,repo就是一系列的脚本,人家都写好了,我为什么要去重复造轮子呢,我还没信息自己造的轮子比别人的好,况且repo并不仅仅是用来clone仓库那么简单,它封装了很多git命令来进行git的操作。
2.6 repo常用命令
用repo help查看repo的常用命令:
zenghui@ubuntu:~/git/test/swapi/pub/network$repo help
usage: repo COMMAND [ARGS]
The most commonly used repo commands are:
abandon Permanently abandon adevelopment branch
branch View current topicbranches
branches View current topicbranches
checkout Checkout a branch fordevelopment
cherry-pick Cherry-pick a change.
diff Show changes between commit and working tree
download Download and checkouta change
grep Print lines matchinga pattern
init Initialize repo inthe current directory
list List projects andtheir associated directories
prune Prune (delete)already merged topics
rebase Rebase local brancheson upstream branch
smartsync Update working treeto the latest known good revision
stage Stage file(s) forcommit
start Start a new branchfor development
status Show the working treestatus
sync Update working treeto the latest revision
upload Upload changes forcode review
See 'repo help <command>' for moreinformation on a specific command.
See 'repo help --all' for a complete listof recognized commands
这些命令基本上都是git命令的封装。
repo status是比较常用的,但是没有讲git的话这个命令的输出我们没法儿讲。
讲一下repo forall吧:
repo forall 迭代器,可以对repo管理的项目进行迭代,最常用的用法大概就是看log了。
repo froall –c git log可以迭代查看log。
Repo讲解就先到这儿吧。