这里以N1-8386项目为例.
在编译服务器上新建一个N1_no_build的目录,再在这个目录下新建sourcecode目录,sourcecode目录等会用来存取拉取待上传的的代码,我们使用.23N1编译文档.pdf的步骤拉取N1的代码,然后切换到相应的分支上。
因为我们一般拉取代码的地方是编译服务器,gerrit创建仓库等操作需要gerrit管理员账号才能执行,所以我们把编译服务器的用户的.ssh/id_rsa.pub也添加到gerrit管理账号的ssh-key集合中,这样我们就可以使用admin的权利在编译服务器上进行一些管理操作,例如创建、推送仓库。
repo是使用manifest文件来管理所有的project仓库的。例如,在aosp中一般存在800多个子仓库,这些子仓库都会被声明在.repo/manitests/default.xml中,当我们拉取的时候,只需要通过repo init拉取manifest仓库就可以拉取所有的子仓库文件下来,所以我们需要首先在远端gerrit服务器上创建manifest仓库,并拉取到本地,然后提交我们的default.xml.
我们在N1_no_build的目录下执行:
ssh -p 29418 admin@192.168.0.251 gerrit create-project --empty-commit N1_8386/manifest
上面的命令将会使用gerrit管理员身份创建manifest仓库,这里我们把N1的项目都统一放到N1_8386目录下,一会我们推送真正的项目源码时也是放到这个目录下
然后还是在当前目录下将刚创建的远程manifest仓库拉取下来,添加我们修改后的default.xml文件并提交
git clone ssh://admin@192.168.0.251:29418/N1_8386/manifest.git
然后进入目录,将我们源码中的manifest中的xml拷贝过来:
cd manifest
cp ../sourcecode/.repo/manifest/* .
vim default.xml
N1的defaut.xml跟aosp的还是有一定差别的,我们首先要弄懂我们要修改的地方,先看下default.xml的内容:
default.xml中一般都是由path和name字段组成,name表示远程git仓库的名字,path表示实际的代码的路径。后面我们将会在相应的path路径下创建名字为name的git仓库并推送到远程。
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="aosp" # 远程仓库的别名
fetch="."
review="https://android-review.googlesource.com/" />
<default revision="refs/heads/cherry" # 默认拉取的分支
remote="aosp" # 默认远程仓库的别名
sync-j="4" # 默认repo sync的线程数
sync-c="true" />
<project path="build/make" name="platform/build" groups="pdk" >
<copyfile src="core/root.mk" dest="Makefile" />
<linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
....
<project path="tools/tradefederation/contrib" name="platform/tools/tradefederation/contrib" groups="pdk,tradefed" />
<repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
<include name="mstar.xml" /> # 这里是通过include标签导入了我们自定义的仓库,所以提交的时候我们要把我们的自定义的xml文件
<include name="costar.xml" />
我们使用gerrit管理以后,默认分支使用master, 其他的可以保持不变,所以我们的修改就是:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="aosp"
fetch="."
review="https://android-review.googlesource.com/" />
<default revision="master" # 改为master
remote="aosp"
sync-j="4"
sync-c="true" />
<project path="build/make" name="platform/build" groups="pdk" >
<copyfile src="core/root.mk" dest="Makefile" />
<linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
....
<project path="tools/tradefederation/contrib" name="platform/tools/tradefederation/contrib" groups="pdk,tradefed" />
<repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
<include name="mstar.xml" />
<include name="costar.xml" />
保存退出,然后提交所有的xml文件
git add .
git commit -m"add manifest xml by zhuhongxi."
git push origin master
到此,我们的manifest仓库就创建完成了。
从上一步的default.xml中我们知道,我们需要在对应的代码路径下创建相应的git仓库并推到远程,后续的源码上传就是推送到相应的仓库。那我们现在要做的就是遍历每个path去创建name仓库,思路有两个:
default.xml文件,拿出path和name字段,然后cd到对应path下,使用创建manifest仓库同样的方式创建git仓库。repo forall -c和$REPO_PROJECT、$REPO_PATH命令循环遍历所有仓库,并将变量的结果写入文件,再解析文件.这里因为default.xml中存在include标签,会去引用其他的xml文件,所以方案1不适合,我们使用方案2.
首先先将每一个仓库的name和path信息输出到文件:
cd sourcecode
repo forall -c 'echo $REPO_PROJECT' | tee pro_name.log
repo forall -c 'echo $REPO_PATH' | tee pro_path.log
编写创建仓库脚本gerrit_create.sh:
#!/bin/bash
USER_NAME="admin"
SERVER_IP="192.168.0.251"
SERVER_PORT="29418"
PROJECT_DIR="N1_8386"
function creatEmptyGerritProject()
{
for i in `cat pro_name.log`;
do
echo $i
echo "ssh -p $SERVER_PORT $USER_NAME@$SERVER_IP gerrit create-project --empty-commit $PROJECT_DIR/$i"
ssh -p $SERVER_PORT $USER_NAME@$SERVER_IP gerrit create-project --empty-commit $PROJECT_DIR/$i
done
}
creatEmptyGerritProject
执行这个脚本就可以创建出每一个仓库对应的的远程仓库
. gerrit_create.sh
仓库创建完成后,下一步就是将源码推送到对应的远程仓库。编写源码上传脚本gerrit_push.sh:
#!/bin/bash
USER_NAME="admin"
SERVER_IP="192.168.0.251"
SERVER_PORT="29418"
PROJECT_DIR="N1_8386"
function pushGerritProject()
{
file1="pro_name.log"
file2="pro_path.log"
lines_1=`cat $file1 | wc -l`
lines_2=`cat $file1 | wc -l`
for ((i=1;i<=$lines_1;i++))
do
line1=`awk 'NR=="'$i'"{print $0}' $file1`
line2=`awk 'NR=="'$i'"{print $0}' $file2`
cd $line2
echo `pwd`
rm -rf .git
# rm -rf .gitignore
git init
git remote add aosp ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_DIR/$line1.git
git pull aosp master
git add -A .
git commit -am "init commit"
git push aosp master
cd -
done
}
pushGerritProject
在上传代码之前,注意,我们还需要考虑,我们在上传代码的时候,需要进行git add操作,name就会涉及到对.gitignore文件的排除规则,我们希望能够上传所有应该上传的文件到服务器上,同时又不破坏.gitignore的规则,所以我们需要先把.gitignore改名,然后上传所有源码文件到服务器,然后再将.gitignore名字改回来然后提交到服务器,这样就可以实现每一个文件我们都能上传且不破坏规则,那么我们写个脚本,到每一个path(源码路径)下找出.gitignore并改名,同样的这里的path还是之前我们读出来的pro_path.log:
#!/bin/bash
function modifiedGitIgnoreFileName()
{
for i in `cat pro_path.log`;
do
cd $i
echo `pwd`
FILES=$(find -name .gitignore)
for file in ${FILES}
do
echo $file
mv $file $file"_temp"
done
cd -
done
}
modifiedGitIgnoreFileName
然后执行修改:
. gerrit_modified_gitignore.sh
现在开始上传源码:
. gerrit_push.sh
我们前面改了.gitignore的名字,源码上传完以后,需要将名字改回来并上传,同样的写个脚本gerrit_restore_gitignore.sh:
function restoreGitIgnoreFileName()
{
for i in `cat pro_path.log`;
do
cd $i
echo `pwd`
FILES=$(find -name .gitignore_temp)
for file in ${FILES}
do
echo $file
mv $file ${file%_temp}
git add *
git commit -m"restore .gitignore by zhuhongxi"
git push aosp master
done
cd -
done
}
restoreGitIgnoreFileName
mkdir N1_8386 && cd N1_8386
hirepo -u init ssh://admin@192.168.0.251:29418/N1_8386/manifest
hirepo sync -q
hirepo start master --all