git入门----repo的基本认识

1、定义

      Repo是谷歌用Python脚本写的调用git的一个脚本。主要是用来下载、多个Git仓库。

      而Android项目那是由多个git仓库组成的,它有非常多的分支。

      如:android/framework/base它就是一个git仓库。

          android/packages/apps/Camera(app下面的所有的应用都是单独的git仓库进行的管理)

          这样假如你不用repo进行统一管理的话,就说基本的你下载Android源码,难道要一个个的写每个仓库的url?然后下载完

     单独的配置每个仓库?单独初始化什么的?显然比较麻烦。

     repo 其实就是把相关的git操作命令进行了封装,方便一下操作好几个git仓库.

2、初始化

      安装下载repo脚本,在公司里直接按照公司给的步骤来的,此处不做整理。

      接下来就是初始化环境下载代码了。

      一般来说为了方便管理,你可以用合适的文件夹名称来存放你要下载的分支代码,然后用在这个文件夹内repo init

2.1、初始化repo工具脚本,并且从服务器端克隆manifest

     这个manifest很关键,repo就是按照它来管理多个git仓库的。

     repo init -u URL  -b branch_name : 这是最常用的URL就用公司的服务端地址,branch_name:就是你下载的代码的分

    支的名字,因为公司肯定会同时维护好几个分支的代码用于开发。

              这个命令就相当于对repo配置和repo脚本集进行git pull,但是它还额外做了更多的事情

      命令参数:

          -u:指定一个url然后连接到一个manifest库.这个manifest库里面会有所有分支的manifest文件。

          -b :选择manifest仓库的一个特殊的分支

          -m :选择manifest仓库中的某一个。当有很多个的时候默认default.xml.

   最终此命令完成repo工具的完整下载,克隆url对应的清单文件来克隆到本地的.repo/manifest.xml当中。注意 它只是一个连接

  符号,指向了.repo/manifets/default.xml.你要是用-m指向了别处,那么就会连接到对应的.repo/manifests/xxxxx.xml的manifest

  当中。

          其实,如果不使用repo工具,也是可以对照manifest.xml文件清单直接使用“git clone”的方式一个project一个project的下

载的,然后对每个project进行git checkout特定的分支。

2.2、manifest文件和.repo隐藏文件内的文件的初步介绍

               为了更好的理解repo工具很有必要了解一下上述两个概念。

               在你执行repo init -u的目录下,等你执行完命令,会有隐藏文件.repo.通过ls -a查看.

               如下:我是建在Projects/n-yoshino/目录下执行的文件

xp022430@cnbjlx24729:~/Projects/n-yoshino$ ls -a
. .repo ... //别的就不写了
xp022430@cnbjlx24729:~/Projects/n-yoshino$ cd .repo/
xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo$ ls -a
. .. manifests manifests.git manifest.xml ...//别的就省略了
xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo$ cd manifests
xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo/manifests$ ls -a
. .. default.xml .git
xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo/manifests$

.repo/manifest.xml是一个软连接就是指向了manifests/default.xml

default.xml的部分代码:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="git://review.sonyericsson.net/" name="origin" review="review.sonyericsson.net"/>
<manifest-server url="http://cmweb.sonyericsson.net/rpc?android"/>
<default remote="origin" revision="n-yoshino" sync-j="4"/>
<project name="device/common" revision="refs/tags/AU_LINUX_ANDROID_LA.UM.5.7.R1.07.01.01.253.084"/>
<project name="device/generic/arm64" revision="refs/tags/AU_LINUX_ANDROID_LA.UM.5.7.R1.07.01.01.253.084"/>
......
<project name="platform/frameworks/av" path="frameworks/av"/>
<project name="platform/frameworks/base" path="frameworks/base"/>
......
<project name="platform/build" path="build">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
......
</manifest>

<remote fetch="git://review.sonyericsson.net/" name="origin" review="review.sonyericsson.net"/>

           定义了名为origin的远程版本库,url = git://review.sonyericsson.net/

          <manifest-server url="http://cmweb.sonyericsson.net/rpc?android"/> <default remote="origin" revision="n-mr1-yoshino2" 

   sync-j="4"/>

           默认的远程版本库origin,revision代表分支默认的分支 n-mr1-yoshino2.就是你不指定revision的视乎就是它

           <project name="platform/frameworks/base" path="frameworks/base"/>

            project用于表示一个git项目,也就是git仓库。path:用于表示在工作区的位置,name表示该git仓库的远程相对路径。

  此处有个问题没有path的是不是就表示在工作区就没有?工作区ls -a显示的那个电脑上的区域。

            <project name="platform/packages/apps/Dialer" path="packages/apps/Dialer" 

                                         revision="15146fbef7ea3bbf23e20c6746a4b031fb2765a6" upstream="n-mr1-common"/>

            此处的和这个reversion是commitid 了,应该死代表某个分支的最新提交也就是这个分支,设置以后该分支的upstream

 就是默认的跟踪分支了!

copyfile 执行拷贝操作,把URL/$src地址的文件拷贝到./$dest

         <copyfile dest="Makefile" src="core/root.mk"/>

          至于.repo下面的其它文件我们接下来讨论。

3、下载代码

      repo sycn按照.repo/manifest.xml指向的那个xml开始克隆并同步远程版本库中的代码.此时两种情况

              1)、如果是第一次克隆本地不存在上面的版本库,那么就相当于git clone.

               2)、如果版本库已经存在相当于

                         git remote update  这个命令对于每一个remote的远程分支进行执行了fetch.

                         git rebase orignl/branch :对当前所在的分支执行rebase.

    repo sync -c 是指当前分支。可以加快下载速度。

    也可以克隆某个指定的git仓库,但注意单独克隆的一般没法编译因为它会依赖别的git库或者缺少mk。所以可能编译不成功

    repo sycn  URL. 这个URL就是manifest中指定的name.

    如:repo sycn platform/packages/apps/Nfc (-j8) :platform/packages/apps/Nfc是project的name.

   总结来说:在repo目录(即.repo)之外,根据repo配置(即.repo/manifest.xml文件),从.repo/projects/*中提取出指定分支

   的各个git项目(即.repo/projects中git项目的子集)的工作目录,形成repo工作目录,可供开发使用。

   执行完如上的命令后:

工作区:
xp022430@cnbjlx24729:~/Projects/n-yoshino$ ls -a
. Android.bp bootable build.sh dalvik device frameworks
libcore ndk pdk .repo system vendor
.. art bootstrap.bash buildspec.mk developers docs hardware
libnativehelper out platform_testing sdk toolchain
abi bionic build cts development external kernel
Makefile packages prebuilts shortcut-fe tools

可以看到完整的一个Android源码工程,也是我们repo的工作区,再进入到.repo看看其它文件

xp022430@cnbjlx24729:~/Projects/n-yoshino$ cd .repo/
xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo$ ls -a
. .. manifests manifests.git manifest.xml project.list project-objects projects
repo .repopickle_fetchtimes

         下面我们先大概了解一下重要的几个目录的含义:

          .repo:此为repo目录,可用于提取相应项目工作目录到外面的repo工作目录。

         .repo/manifests.git:此为repo配置信息的git库,不同版本包含不同配置信息。每个repo项目初始化后也会有自己的git仓

                                          库的repo也会建立一个Git仓库,用来记录当前Android版本下各个子项目的Git仓库分别处于哪一个分

                                          支,这个仓库通常叫做:manifest仓库。

         .repo/manifests:此为repo配置信息的工作目录(将配置信息的工作目录和相应的实际git目录分离管理,并且配置

                                     信息中的.git目录实际只是指向实际git库的软连接)。 

                                     此目录中可能包含一个或多个xml文件描述的配置。每个xml文件是独立的一套配置,配置内容包括当前

                                     repo工作目录包含哪些git项目、所有git项目所处的默认公共分支、以及远端地址等。

           .repo/manifest.xml:repo工作目录中的内容同一时刻只能采用manifests中的一个xml文件做为其配置,该文件就是其软

                                            连接,通过init的-m选项指定采用哪个文件;另外,同一xml文件也可能处于manifests库的不同版本

                                            或者不同分支,通过init的-b选项指定使用manifests中的哪个分支,每次init命令都会从服务器更新

                                           最新的配置。这里通过-m指定的manifests中的xml文件中。

           .repo/repo:此为repo脚本集的git库,用于repo管理所需的各种脚本,repo的所有子命令就是其中的对应脚本实现。这

                               些脚本也通过git管理,.repo/repo/.git为对其应的git目录,用git进行版本管理。

xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo/repo$ ls -a
. command.py editor.py .git git_config.py git_refs.pyc ... wrapper.py
.. command.pyc editor.pyc .gitattributes git_config.pyc git_ssh ... wrapper.pyc
color.py COPYING error.py git_command.py .gitignore hooks ... trace.py
color.pyc docs error.pyc git_command.pyc git_refs.py main.py ... trace.pyc

 注意:三个点的表示省略号,此处省略了一部分的显示,可以看到都是repo的脚本还有.git版本库

           .repo/projects:此为repo所管理的所有git项目集,包含repo当前配置所指定的所有git项目对应的git目录

            projects目录如下:

xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo/projects$ ls
abi bootable cts.git development.git external kernel ... tools
art.git build dalvik.git device frameworks libcore.git ... vendor
bionic.git build.git developers docs hardware libnativehelper.git ... toolchain
xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo/projects/packages/apps/Nfc.git$ ls
branches config description FETCH_HEAD HEAD hooks info logs objects packed-refs refs svn
xp022430@cnbjlx24729:~/Projects/n-yoshino/.repo/projects/packages/apps$ ls
BasicSmsReceiver.git CellBroadcastReceiver.git Email.git ... Stk.git
Bluetooth.git CertInstaller.git EmergencyInfo.git ... StorageManager.git
Browser2.git CMFileManager.git ExactCalculator.git ... Tag.git
Calculator.git ContactsCommon.git Gallery2.git ... Terminal.git
Calendar.git Contacts.git Gallery.git ... Test
Camera2.git DeskClock.git HTMLViewer.git ... TV.git
Camera.git DevCamera.git KeyChain.git ... TvSettings.git
CarrierConfig.git Dialer.git Launcher2.git ... UnifiedEmail.git

    注意其实工作区中每个git工作目录中的.git只是指向.repo/projects/*的软连接,在repo工作目录中的某个git工作目录更新

     相应的git库,其实最终会更新到.repo/projects中对应的git库。也就是此处才是真正存放版本库的地方。

     最后:刚刚repo sync之后,当前工作目录不处于任何分支,其中的修改只能本地保存无法提交至远端,若想提交工作,需

                 要先创建一个分支保存工作内容。如下(注意和在那个目录下没关系的)

xp022430@cnbjlx24729:~/Projects/n-mr1-yoshino2/packages/apps/Dialer$ git branch
* (no branch)

4、repo的使用。

     基本上所有的repo命令。

     如果只是:  repo   命令参数     那么就代表对所有的git仓库的执行,无论是在那个目录下。想想也是repo的配置是在工作

    目录的最外层配置的对上面来说就是~/Projects/n-mr1-yoshino2,这个目录下包含了所有的git仓库.

    当你向操纵某个指定的git仓库的时候,无论是不是在它目录下。执行 repo  命令参数  指定的本地仓库路径(也就是path对应)

   4.1、创建/切换分支。

          刚下载下来的代码是没有本地分支的。

xp022430@cnbjlx24729:~/Projects/n-mr1-yoshino2/packages/apps/Dialer$ git branch
* (no branch)
xp022430@cnbjlx24729:~/Projects/n-mr1-yoshino2/packages/apps/Bluetooth$ git branch
* (no branch)

         创建 :调用 repo start 分支名字  --all : 为全部的本地git仓库配置分支名字 

         然后在config里面会看到,自动关联了upstream根据manifet中的revision。

         如:

<project name="platform/packages/apps/Nfc" path="packages/apps/Nfc" revision="n-common-pn553"/>
branch.stable.remote=origin
branch.stable.merge=n-common-pn553

         repo start 名字   platform/packages/apps/Nfc :为指定的git仓库配置

         如:设置分支名字未table的时候

repo start stable platform/packages/apps/Nfc
xp022430@cnbjlx24729:~/Projects/n-yoshino/packages/apps/Nfc$ git branch
* stable

        切换:repo checkout branch_name [projects]

        查看分支:repo branches [projects]

        [projects] :代表可省略git仓库,此时会查看所有的git仓库

cnbjlx24729:~/Projects/n-mr1-yoshino2/packages/apps/Bluetooth$ repo branches
(no branches)
cnbjlx24729:~/Projects/n-mr1-yoshino2/packages/apps/Bluetooth$ repo branches .
(no branches)
cnbjlx24729:~/Projects/n-mr1-yoshino2/packages/apps/Bluetooth$ repo branches platform/packages/apps/Nfc
(no branches)

          repo abandon <branchname> [projects]: 删除指定的分支. 是对git branch -D的封装.

    4.2、比较差异

            repo diff [projects]:查看工作区的差异

            repo diff :查看所有

            repo diff project1 project2 :查看指定的project1、project2。

    4.3、repo stage [projects]

            相当于git add 把工作区内容加入到缓存区。

    4.5、repo status [projects]

            同时显示缓存区和工作区的文件的状态.

    4.6、repo push :一般用很少用

            repo push <remote name> [--all | [projects]]

猜你喜欢

转载自blog.csdn.net/clarkness/article/details/81194014