1. 同类技术方案对比

  1. git submodule/git subtree,都是把代码当做一个单一的大仓库,进行管理处理
  2. repo,是把所有的代码当做一个工程处理,各个模块可以是独立的仓库,而 repo 只是一个执行 git 命令的脚本,方便组织各个 git 仓库,repo 的最佳实践就是 AOSP 源码的管理

注: 此处只对比了 submodulerepo 部分内容,subtreesubmodule 差不多,核心区别是一个是引用仓库,一个是导入仓库,会增大 .git 文件容量

核心部分对比 git submodule Repo
管理方式 查看 .gitmodules 文件可以看到所有 submodule 介绍,知己用,无须维护 manifest 文件管理,需要根据分支维护
更新方式 子仓库更新,父级也要更新,容易出现坑 各个仓库独立更,无坑
命令工具方面 git 的展示效果 更多批量效果,具体可以看本文后续的几个命令介绍

2. Repo 的使用

repo 配置

  1. 下载 repo 脚本
    brew install repo	
    
  2. 修改镜像地址,避免墙的问题, .zshrc 或者 .bashrc 加入
    export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
    

项目中使用

  1. 初始化设置 manifest 文件

    • 放置位置

      1. 主项目 git 仓库中
      2. 另开一个git 仓库

      项目 git 仓库数量不大,频繁新增修改切出分支时,manifest 独立仓库不具有优势,

      嵌入主仓库有明显的优势,在 develop 中,改动 mainifest 文件,快速切出对应的工作分支

    • 文件内容

      repo manifest 参数文档

      <?xml version="1.0" encoding="UTF-8"?>
      <manifest>
        <!-- remote 指定远程分支,name 是远程分支的名字,fetch 拉去地址的 host,sync-j 是指同步拉去线程数量 -->
          <remote name="taofen8" fetch="http://gitlab.taofen8.com/"  sync-j="1"/>
      	<!-- default 是配置默认的参数,默认情况下,拉去 master,用远程名字叫 taofen8 的地址-->  
          <default revision="master" remote="taofen8"/>
        <!-- 此处配置项目仓库地址,name 是指在 remote 的 host 之后,补充上对应的名字即可,path 是指本地的配置路径地址-->
        <!-- 注意,第一个 project 没有指定 remote,就会使用 default 中的配置参数了-->
          <project name="taofen8_app/b_taofen8_flutter" path="b_taofen8_flutter"/>
          <project name="taofen8_app/b-taofen8_phone-iOS" remote="taofen8" path="b-taofen8_phone-iOS"/>
      </manifest>
      
  2. 拉取同步仓库

    # 该步骤指,拉取 manifest 文件,
    # -u 指定 manifest 文件所在的仓库地址,-b 指定 manifest 仓库的分支
    # 如果要拉取 develop 的分支,就 -b develop 就可以
    # 此处把 manifest 文件放置在 flutter 主项目中
    ➜ repo init -u http://gitlab.taofen8.com/taofen8_app/b_taofen8_flutter -b master
    # 该步骤指,根据 manifest 文件进行 git pull 对应分支,放置到对应位置
    ➜ repo sync
    
  3. 切出分支

    # 根据 manifest 文件 revision 中指定的分支,切出分支,进行开发
    # 当前栗子中,feature/flutter 的 head 和 master head 是相同的
    # 因为 manifest 中 default 的 revision 值是 master
    ➜ repo start feature/flutter --all
    # 查看当前仓库的分支
    ➜ repo branch
    *  feature/flutter              | in all projects
    
  4. 几个特别命令介绍

    # 查看各个仓库的状态
    ➜ repo status
    project b-taofen8_phone-iOS/                    branch feature/flutter
    project b_taofen8_flutter/                      branch feature/flutter
    
    # 当有改动以后
    ➜ repo status
    project b-taofen8_phone-iOS/                    branch feature/flutter
     -m     README.md
    project b_taofen8_flutter/                      branch feature/flutter
    
    # 所有的仓库执行同一个命令
    # repo forall -c "git push" 等等
    ➜ repo forall -c "pwd"
    /Users/dove/Documents/code/work/taofen8/b-taofen8_phone-iOS
    /Users/dove/Documents/code/work/taofen8/b_taofen8_flutter
    
  5. local manifest 使用
    有时候会出现本地临时新增一些仓库进去,或者移除部分仓库,但又不需要更新到 manifest 中,这个时候 local manifest 就有作用了。
    在对应目录新增 .repo/local_manifests/default.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <manifest>
        <project name="taofen8_app/b-taofen8-Android" remote="taofen8" path="b-taofen8-Android"/>
    </manifest>
    

    执行 repo sync, 执行会拉取新增的项目

    ➜ repo sync
    warning: redirecting to http://gitlab.taofen8.com/taofen8_app/b_taofen8_flutter.git/
    Fetching project taofen8_app/b_taofen8_flutter
    warning: redirecting to http://gitlab.taofen8.com/taofen8_app/b_taofen8_flutter.git/
    Fetching projects:  50% (1/2)
    Fetching project taofen8_app/b-taofen8-Android
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
    curl: (22) The requested URL returned error: 401 Unauthorized
    Server does not provide clone.bundle; ignoring.
    warning: redirecting to http://gitlab.taofen8.com/taofen8_app/b-taofen8-Android.git/
    ....
    ....
    

    此处简单解释下原理,repo 会合并 default.xmllocal_manifest/default.xml

    再去拉取合并后的 manifest 的内容,具体可以 参考该文章