Android repo代码仓库推送到公司的git服务器管理

Android repo代码仓库上传到公司的git服务器修改记录

参考地址

0x00 首先从供应商那里拿到了一份AOSP的源码,比如我拿到的是Android8.1的源代码。

比如我的拿到的部分代码,只有一个.repo文件夹,文件夹大小为39G(Android8.1)的代码。

在这里插入图片描述

0x01 然后同步供应商的代码。

使用repo sync -l 同步供应商的代码,如图同步完成相关的代码。(repo 命令应之前已经安装好,不懂的自己百度哈)

在这里插入图片描述

0x02 获取项目源码中每个代码仓的位置

使用命令获取代码整个项目的每个git的代码仓库,然后把他生成到文档中。
	 #使用命令如下,把qcom_source源码仓中所有的.git 项目路径都写到git_pro.txt文件中
	 find qcom_source/ -type d -name '.git' > git_pro.txt

1、如图所示,我的项目中一共有五百多个git项目。
在这里插入图片描述
2、然后使用命令把项目的头尾去掉,然后只留下项目的相对路径。

#命令,其中13是每行开头到相对路径的字符个数,根据自己的路径进行修改
cat git_pro.txt | cut -c 13- | sed 's/.....$//' > path.txt

结果如图所示
在这里插入图片描述

0x03 repo使用的是manifest.xml来管理整个repo的代码仓的,所以需要我们生成自己的manifest.xml文件,当然使用供应商提供的manifest.xml来使用也是一样的,需要修改部分代码,我自己生成自己的xml文件;

1、上面使用相关的步骤后,就生成了一个path.txt文件了,然后我们使用这个path.txt文件生成default.xml文件。repo会把这个default.xml文件后面和manifest.xml关联起来,不用我们手动关联。
使用刚刚的path.txt文件和shell脚本来生成default.xml文件,暂时文件名定为gen_xml.sh,如下:

#!/bin/bash
echo -e "
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<manifest>
  <remote  name=\"origin\" fetch=\".\"/>
  <default remote=\"origin\" sync-j=\"4\" revision=\"main\" />" >>$1

while read line; do
        echo "  <project path=\"$line\" name=\"$line\" />" >>$1
done
echo -e "\n</manifest>" >>$1
#使用shell脚本生成xml文件
cat path.txt | sh gen_xml.sh default.xml

执行后生成的xml文件如图:
在这里插入图片描述

0x04 default.xml文件概述


<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote  name="origin" fetch="."/>
  <default remote="origin" sync-j="4" revision="main" />
  <project path="cts" name="cts" /> #往下是相关项目的信息
  <project path="kernel/msm-3.18" name="kernel/msm-3.18" />
  <project path="packages/services/Telephony" name="packages/services/Telephony" />
  <project path="packages/services/BuiltInPrintService" name="packages/services/BuiltInPrintService" />
  <project path="packages/services/Car" name="packages/services/Car" />
  <project path="packages/services/NetworkRecommendation" name="packages/services/NetworkRecommendation" />
  <project path="packages/services/Telecomm" name="packages/services/Telecomm" />
  <project path="packages/services/Mms" name="packages/services/Mms" />
  <project path="packages/apps/SnapdragonMusic" name="packages/apps/SnapdragonMusic" />
  <project path="packages/apps/TV" name="packages/apps/TV" />
  <project path="packages/apps/Launcher3" name="packages/apps/Launcher3" />
  <project path="packages/apps/QuickSearchBox" name="packages/apps/QuickSearchBox" />
  <project path="packages/apps/Nfc" name="packages/apps/Nfc" />
  <project path="packages/apps/HTMLViewer" name="packages/apps/HTMLViewer" />
  <project path="packages/apps/StorageManager" name="packages/apps/StorageManager" />
  <project path="packages/apps/BasicSmsReceiver" name="packages/apps/BasicSmsReceiver" />
  <project path="packages/apps/Phone" name="packages/apps/Phone" />
  <project path="packages/apps/Exchange" name="packages/apps/Exchange" />
  <project path="packages/apps/EmergencyInfo" name="packages/apps/EmergencyInfo" />
  <project path="packages/apps/SnapdragonGallery" name="packages/apps/SnapdragonGallery" />
  <project path="packages/apps/Launcher2" name="packages/apps/Launcher2" />
  <project path="packages/apps/PackageInstaller" name="packages/apps/PackageInstaller" />
  <project path="packages/apps/SmartCardService" name="packages/apps/SmartCardService" />
  <project path="packages/apps/OneTimeInitializer" name="packages/apps/OneTimeInitializer" />
  <project path="packages/apps/Car/Media" name="packages/apps/Car/Media" />
  <project path="packages/apps/Car/Messenger" name="packages/apps/Car/Messenger" />
  <project path="packages/apps/Car/Hvac" name="packages/apps/Car/Hvac" />
  <project path="packages/apps/Car/SystemUpdater" name="packages/apps/Car/SystemUpdater" />
  <project path="packages/apps/Car/Settings" name="packages/apps/Car/Settings" />
  <project path="packages/apps/Car/LatinIME" name="packages/apps/Car/LatinIME" />
# 不止这些

0x05 由于不只是一个git代码仓库,所以不可能手动来创建仓库,所以我们只能使用脚本来创建远程的代码仓库。

1、通过shell和生成的default.xml文件来创建git远程厂库。(注,一定要在主组下面创建,我不是在主组下创建会失败,有些项目无法完成,可能是因为权限的问题)
需要用的工具和build-git.py脚本
工具:python3 python-gitlab库
脚本:

#!/usr/bin/python3
import gitlab
import os
import re
import time
import sys


MANIFEST_XML = "default.xml"#其中这个是我们刚刚生成的default.xml文件
ROOT = os.getcwd()
ROOT_GROUP = "qcom-android"#这个是我们的主组
MANIFEST_XML_PATH_NAME_RE = re.compile(r"<project\s+path=\"(?P<path>[^\"]+)\"\s+name=\"(?P<name>[^\"]+)\"\s+/>",
                                       re.DOTALL)

gl = gitlab.Gitlab('http://ip/', private_token='xxxxxxxxxxxxxxxxxxx')#token是我的用户token 下面介绍
manifest_xml_project_paths = []


def parse_repo_manifest():
    with open(os.path.join(ROOT, MANIFEST_XML), "rb") as strReader:
        for line in strReader:
            if line is not None and len(line) != 0:
                this_temp_line = line.decode()
                #print(this_temp_line)
                if line.find("path".encode(encoding="utf-8")):
                    s = MANIFEST_XML_PATH_NAME_RE.search(this_temp_line)
                    #print(s)
                    if s is not None:
                        manifest_xml_project_paths.append(s.group("path"))

    print("manifest_xml_project_paths=" + str(manifest_xml_project_paths))
    print("manifest_xml_project_paths len=" + str(len(manifest_xml_project_paths)))


def create_group_and_project():
    all_groups = gl.groups.list(all=True)
    print("all_groups=" + str(all_groups))
    group_parent = None

    for g in all_groups:
        if g.name == ROOT_GROUP:
            group_parent = g
            break

    # print("**** get group parent=" + str(group_parent)) #查找父组

    for path in manifest_xml_project_paths: #解析文件夹
        print("path=" + path)
        paths = path.split("/")
        print("paths=" + str(paths))

        last_path_index = len(paths) - 1
        group = group_parent

        for index in range(0, last_path_index):
            p = paths[index] #取出每个文件夹
            print("ex p=" + p)
            # is the group exist
            print("build parent group=" + group.name)
            try:
                all_groups = group.subgroups.list(all=True)
            except AttributeError:
                all_groups = []
                print("AttributeError: clear all subgroups")

            is_group_exist = False
            for g in all_groups:
                if g.name == p:
                    is_group_exist = True
                    group = g
                    print("group exist=" + g.name)
                    break
            if is_group_exist:
                continue
            # create subgroup
            data = {
                "name": p,
                "path": p,
                "parent_id": group.id
            }
            #print("-------------->data:{}, name:{}".format(data, group.name))

            try:
                group = gl.groups.create(data)
                print("group create success name=" + p)
                time.sleep(1)
            except gitlab.exceptions.GitlabCreateError as e:
                if e.response_code == 400:
                    #print("=============> group name :" + p + " has already been created")
                    query_groups = gl.groups.list(all=True)
                    #print("-------------> query_groups:" + str(query_groups))
                    for query_group in query_groups:
                        if query_group.name == p and query_group.parent_id == group.id:
                            group = query_group
                            print("update exit group:" + group.name)
                            break
# '''
        project = paths[last_path_index]
        print("group project list group=" + group.name)
        real_group = gl.groups.get(group.id, lazy=True)
        all_projects = real_group.projects.list(all=True)
        print("group all projects=" + str(all_projects))
        is_project_exist = False
        for p in all_projects:
            if p.name == project:
                is_project_exist = True
                print("project exist=" + p.name)
                break
        if not is_project_exist:
            print("create project=" + project)
            gl.projects.create({'name': project, 'path': project, 'namespace_id': group.id})
            print("project create success name=" + project)
            time.sleep(1)

# '''

def test_create_project_with_dot_name():
    # need use path field, if don't use path, GitLab url will replace "." to "_"
    gl.projects.create({
    'name': "xxx.yy.xy", 'path': "xxx.yy.xy"})


if __name__ == '__main__':
    parse_repo_manifest()
    create_group_and_project()

1、首先登陆我们的git web,新建一个主组结构。
在这里插入图片描述
2、创建一个叫qcom-android的主组
在这里插入图片描述
3、由于脚本内写死了父组名(qcom-android),这个组需要在 GitLab 网页中自行创建。同样 url 和 token 需要更换为你自己的,生成 token 是在 GitLab Settings -> Access Tokens -> Add a personal access token。如图,在名称中随便加一个名字,然后生成token。然后复制放到上面的脚本中。
在这里插入图片描述
使用上面的build-git.py脚本,然后通过正则表达式解析 default.xml 中的 project 标签拿到 path,根据 path 创建 group (包括 subgroup),最后再创建 project。
4、执行完build-git.py脚本的结果如图
在这里插入图片描述
在这里插入图片描述
我只拿了三个项目来做测试,如图是创建完成后的代码仓库。

0x06 给git服务器新建一个manifest的git仓库,然后把default.xml上传上去

1、比如我在qcom-android组下面新建一个manifest项目
在这里插入图片描述
2、然后把default.xml文件上传到服务器
使用如下命令在上面生成的default.xml文件夹下面执行如下命令(根据你的项目路径使用不同的命令,我这个是新建项目的时候在项目里生成的相关命令,你的根据需要就行修改)
在这里插入图片描述
3、添加完成
在这里插入图片描述

0x07 push本地已经有的代码到远程代码仓中

一、使用的工具有,python3、python-gitlab、push_git.py
二、首先需要确定的事你的ssh已经生成相关的公共密钥,并且已经绑定到git服务器。不然你执行下一步的脚本会出错。

	1、先在Ubuntu上安装 Git
	sudo apt-get install git
	2、安装成功后键入命令可以查看 Git 版本,有版本提示说明已经安装成功。
	git --version
	3、配置全局git的用户名和邮箱
	git config --global user.name "xxx" # xxx 是你的用户名
	git config --global user.email "user email address" # 后面这个是你的邮箱名字
	4、使用生成 SSH key
	ssh-keygen -t rsa -C "user email address" # 是你的邮箱
	5、然后再用户目录下会生成一个.ssh,然后里面有两个问文件

在这里插入图片描述
6、打开id_rsa.pub文件,复制里面的内容然后填写到git webview面别的
在这里插入图片描述

在这里插入图片描述

三、push_git.py脚本
这需要开发一个脚本执行,这里还是用 python 实现。

#!/usr/bin/python3
import time
import os
import re

MANIFEST_XML = "default.xml" #我们生成的defualt.xml文件
ROOT = os.getcwd()
LOG_FILE_PATH = os.path.join(ROOT, "log-push.log")
MANIFEST_XML_PATH_NAME_RE = re.compile(r"<project\s+path=\"(?P<path>[^\"]+)\"\s+name=\"(?P<name>[^\"]+)\"\s+/>",
                                       re.DOTALL)

SOURCE_CODE_ROOT = "/work/qcom_source/" #你源代码路径,这个是供应商提供的代码
REMOTE = "git@192.168.1.100:qcom-android/" #你的git服务器地址和主目录路径

manifest_xml_project_paths = []

def parse_repo_manifest():
    with open(os.path.join(ROOT, MANIFEST_XML), "rb") as strReader:
        for line in strReader:
            if line is not None and len(line) != 0:
                this_temp_line = line.decode()
                if line.find("path".encode(encoding="utf-8")):

                    s = MANIFEST_XML_PATH_NAME_RE.search(this_temp_line)

                    if s is not None:
                        manifest_xml_project_paths.append(s.group("path"))

    print("manifest_xml_project_paths=" + str(manifest_xml_project_paths))
    print("manifest_xml_project_paths len=" + str(len(manifest_xml_project_paths)))

def push_source_code_by_folder(str_writer):
    for path in manifest_xml_project_paths:
        print("path=" + path)
        abs_path = SOURCE_CODE_ROOT + path
        print("abs_path:", abs_path)

        if os.path.exists(abs_path):
            # change current work dir
            os.chdir(abs_path + "/")
            dir_data = os.listdir(os.getcwd())
            cmd_list = []
            if len(dir_data) == 0:
                echo_cmd = "echo \"This is a empty repository.\" > ReadMe.md"
                str_writer.write("empty repository:" + abs_path)
                str_writer.write("\r\n")
                cmd_list.append(echo_cmd)

                git_init_cmd = "git init"
                cmd_list.append(git_init_cmd)

            #git_rename_origin_cmd  = "git remote rename origin origin-old"
            #cmd_list.append(git_rename_origin_cmd)

            git_remote_cmd = "git remote add origin " + REMOTE + path + ".git"
            print("******************************remote path:", git_remote_cmd)
            cmd_list.append(git_remote_cmd)
            git_push_cmd = 'git push -u origin --all'
            cmd_list.append(git_push_cmd)
            git_push_cmd = 'git push -u origin --tags'
            cmd_list.append(git_push_cmd)

            for cmd in cmd_list:
                print("--------------------->begin exec cmd:" + cmd)
                os.popen(cmd)
                time.sleep(1)
                print("====================>end exec cmd:" + cmd)
        else:
            print("abs_path=" + abs_path + " is not exist.")
            str_writer.write("folder not exist:" + abs_path)
            str_writer.write("\r\n")

def wrapper_push_source_code_write_log():
    with open(LOG_FILE_PATH, 'wb+') as strWriter:
        push_source_code_by_folder(strWriter)
        strWriter.close()

def test_only_dot_git_folder():
    subdir_and_file = os.listdir(os.getcwd())
    print("subdir_and_file=" + str(subdir_and_file))
    with open(LOG_FILE_PATH, 'wb+') as strWriter:
        strWriter.write(str(subdir_and_file))
        strWriter.write("\r\n")
        strWriter.write(str(subdir_and_file))
        strWriter.close()

if __name__ == '__main__':
    parse_repo_manifest()
    wrapper_push_source_code_write_log()


执行完脚本后嘚结果
在这里插入图片描述
至此,代码已经从供应商的git 地址推送到我们自己的git 服务器中了。接下来继续

0x08 repo 部署到服务器,这个 是必须的用于同步git的代码

1、把代码clone下来
git clone https://github.com/GerritCodeReview/git-repo.git
然后把项目里面的.git文件夹删除掉
2、在git webview上新建一个repo仓库,如图我的是这么做的。
在这里插入图片描述
3、把刚刚下载好的repo代码上传到新建的仓库中。
执行的命令如下
在这里插入图片描述
上传成功
在这里插入图片描述

0x09 客户端 repo 同步代码

执行命令:
1、同步服务器的代码

repo-admin init -u git@192.168.2.111:qcom-android/manifest.git --repo-url=git@192.168.2.111:qcom-android/repo.git --no-repo-verify

这时候执行repo sync可能会出现错误,可能是因为python版本或者是repo版本不对,需要最新的repo命令。(这个需要自己同步最新的repo应用,我服务器中存在两个repo ,一个命名成repo-admin 这个是最新版本的,另一个是repo 是比较旧的版本)
结果:
在这里插入图片描述

2、同步代码命令

repo-admin sync

同步完成后,就生成相关的项目文件了
在这里插入图片描述
由于我只测试了几个项目,所以才有三个项目被同步了过来。

错误

1、出现如下错误
在这里插入图片描述
如果错误,是因为repo脚本需要修改。
解决:一,我们打开我们的repo脚本
命令:sudo vi /user/repo-admin (其中repo-admin是我最新的repo版本,是通过repo重新命名成repo-admin的,你们看你们的应用名字)
修改 把REPO_REV修改成master
在这里插入图片描述

2 出现如图所示问题可能是因为你git远程仓库没用master分支,需要切换到对应分支

在这里插入图片描述
解决:
在执行完上面的第0x09步骤操作后,打开vi .repo/manifests/default.xml,把revision=master修改成你对应的分支名字,然后在执行repo sync操作。
在这里插入图片描述
至此完成了repo工程的创建和代码管理。有不足和写得不对的地方望大家留言指出,大家一起学习成长。谢谢~

本文参考tyyj90作者的相关博文,然后加以整理。
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值