使用一个git管理整个Android平台源码并且保留repo的同步功能

前言

谷歌或者第三方厂商提供的Android平台源码,大多数都是由repo来管理,我们知道其中包含了很多小的git工程。

如果我们开发团队规模比较小,我们很可能想直接使用一个git来维护这样比较方便,但这样就会导致repo功能丧失,就没办法过一段时间同步第三方厂商的代码了。

那该怎么解决?解决及实现思路如下

这只是本人个人尝试的解决方法,最终达到这个目的,经测试稳定无问题,如果大家有更好的方法,欢迎大家探讨改进。

注意:以下实现是在rk3399-industry-7.1上,不保证对所有都通用,但可以提供参考

思路

  1. 当我们创建一个大git的时候,能不能用一个简单脚本,删除所有小git工程中的.git和.gitignore,但是我们保留里面的.repo?
  2. 当我们需要同步第三方厂商最新修改的时候,我们再将这些小git工程中的.git再恢复回来,然后同步?(同步的时候可能会有冲突,可以手动解决掉冲突,实际上如果我们经常更新,是不会有很多冲突的。)
  3. 同步结束的时候,我们再重复第一个步骤,将所有小git中的.git和.gitignore删除掉。然后再在大git下使用git status就能看出来这次同步了哪些东西,再进行提交到我们本地服务器,就可以了。

实现步骤

  1. 首先创建自己本地服务器创建空的Android平台工程。(这个步骤比较简单,如果使用gerrit在上面create一个project就可以)
  1. 将已经repo sync的或者已经解压的第三方厂商提供的源码所有小git中的.git删除。

    这里提供一个脚本例子rm_git.sh

    1

    #!/bin/bash
    
    for filename in `find -L ./ -maxdepth 15 -name '.git' | sort`
    do
        if [ "$filename" != "./.git" -a "$filename" !=     "./.repo/manifests/.git" \
        -a "$filename" != "./.repo/repo/.git" ]; then
            echo "delete $filename"
            rm -rf $filename
        fi
    done
    
    for filename2 in `find -L ./ -maxdepth 15 -name '.gitignore' | sort`
    do
        if [[ $filename2 != "./.gitignore" && $filename2 != "./.repo/repo/.gitignore"
    &&  $filename2 != ./u-boot* &&  $filename2 != ./    kernel* ]]; then
            echo "delete $filename2"
            rm $filename2
        fi
    done
    
    rm "./frameworks/data-binding/integration-tests/App With Spaces/app/.gitignore"
    
    unset filename
    unset filename2    

    以上脚本比较简单,大概意图如下:

    1. 删除所有的.git,但下面这3个.git不能删。

      //这个.git是源码根目录的大git,第一次没有,等关联到你本地服务器,那就有了。
      ./.git
      //下面这两个是要以后用来repo sync的也不能删除
      ./.repo/manifests/.git
      ./.repo/repo/.git
    2. 删除所有的.gitignore。

      • 可能你会疑惑为什么要删除这个? ./repo的manifest.xml里可以具有拷贝文件的功能,因为目的文件在repo sync的时候会从其它地方拷贝,目的文件又被它加进了.gitignore里,你如果不把这个目的文件也放进你的大git里,那另一个人从你本地服务器中clone下面源码,是不会包含这个目的文件的,会导致编译不了。这里不好理解,也不好描述。

      • 如果删除了所有的.gitignore会不会把很多没有的编译生成的东西也搞进去?但我们之后会在顶层目录中创建一个大的.gitignore。会将这些过滤掉。并且之后这些小的.gitignore是可以被恢复回来的。不用担心

        同样它也有几个地方是不能删的,内核和u-boot里的不删。

        ./.gitignore
        ./.repo/repo/.gitignore
        ./u-boot*
        ./kernel*
        最后一个单独的rm是因为它的路径里有空格,上面批量删除不掉只好单独删除。

  2. 将u-boot/.gitignore中的*.elf删除(这只针对rockchip平台)

    //删除此项
    *.elf
  3. 创建顶层.gitignore

    这里提供一个模板,针对自己平台,要根据编译之后有哪些是每次编译之后都会有变化的,再将它们添加进来。
    
    *~
    *.swp
    *.swo
    *.bak
    /out/
    /rockdev/
    v8.log
    .repo
    rm_git.sh
    
    # cscope files
    cscope.*
    ncscope.*
    .tags*
    .svim
    
    build/tools/releasetools/blockimgdiff.pyc
    build/tools/releasetools/common.pyc
    build/tools/releasetools/rangelib.pyc
    build/tools/releasetools/sparse_img.pyc
    
    hardware/rockchip/librga/version.h
    hardware/rockchip/omx_il/include/rockchip/git_info.h
  4. 提交自己的本地服务器,因为.repo已经被加进.gitignore里它不会被提交进去。

  5. 同步第三方厂商代码。

    这个和之前没有任何区别,因为.repo在,只需要执行repo sync。
    那么之前被删除的所有.git和.gitignore都会再回来,并且可以将最新的修改同步下来。

    等同步结束,同步时可能会有冲突,可以将冲突文件拷贝到别的地方,先保证同步成功,之后再合并冲突,然后执行./rm_git.sh,再执行git status就能看出现在共同下面那些新的代码,并且也就提交到本地服务器了。

转载请注明出处:http://www.wolfnx.com/2020/06/21/Android-Repo-Git

作者 : wolfnx
邮箱 : wolfnx@outlook.com
邮箱2 : lostnx@gmail.com

Click Me