转载请注明链接
环境:ubuntu14.04
此文章用以使用脚本批量上传项目至Gerrit服务器,并实现权限控制,整套流程如下:
一、Project上传脚本部分:
#!/bin/bash
#####################################################################################
##将本地代码全部上传到gerrit服务器进行管理
#####################################################################################
#git用户名字,gerrit服务器ip,gerrit服务器端口
USER_NAME="username"
SERVER_IP="10.1.2.3"
SERVER_PORT="29418"
#项目前缀
PROJECT_NAME_PREFIX="prefixprojects"
#项目分支名
BRANCH_NAME="project_test"
#项目的父项目,这是权限控制的关键,所有子项目继承此项目,而不是默认的继承自All-Projects,这样只需要给父项目配置权限即可
PARENT_NAME="parent_projectname"
LOCAL_PATH=`pwd`
#软链接.repo/manifest.xml的路径
MANIFEST_XML_FILE=$LOCAL_PATH/.repo/manifest.xml
#从default.xml中取到的项目列表
PROJECT_LISTS=()
OUTPUT_PROJECT_LIST_FILE_NAME=$LOCAL_PATH/project_list_name
OUTPUT_PROJECT_LIST_FILE_PATH=$LOCAL_PATH/project_list_path
#从.repo/manifests/manifest.xml中获取各个仓的名字和路径
function getNameAndPath()
{
echo "------------getNameAndPath---------------"
ignoreLine=false
i=0
while read LINE
do
# ignore line with comments end flag
if [ `echo $LINE | grep "\-\->"` ]
then
ignoreLine=false
continue
fi
# ignore line with comments start flag
if [ `echo $LINE | grep "<!--"` ]
then
ignoreLine=true
continue
fi
# ignore line between comments start flag and comments end flag
if [ "$ignoreLine" == true ]; then continue; fi
command_line=`echo $LINE | grep "<project"`
if [ "$command_line" ]
then
#echo $LINE
reposity_name_sec=${LINE#*name=\"}
reposity_path_sec=${LINE#*path=\"}
if [ "$reposity_name_sec" ] && [ "$reposity_path_sec" ]
then
reposity_name=${reposity_name_sec%%\"*}
reposity_path=${reposity_path_sec%%\"*}
echo "$reposity_name,$reposity_path"
PROJECT_LISTS[i]="$reposity_name,$reposity_path"
((i++))
fi
fi
done < $MANIFEST_XML_FILE
echo $i
}
#在远程gerrit服务器建立各个仓
function creatEmptyGerritProject()
{
echo "------------creatEmptyGerritProject---------------"
for item in ${PROJECT_LISTS[@]}
do
PROJECT_NAME=`echo "$item" | awk -F ',' '{print $1}'`
#在gerrit服务器创建空项目,注意--parent指定所有子项目的父项目,以便权限控制
echo "ssh -p $SERVER_PORT $USER_NAME@$SERVER_IP gerrit create-project $PROJECT_NAME --parent $PARENT_NAME"
ssh -p $SERVER_PORT $USER_NAME@$SERVER_IP gerrit create-project "$PROJECT_NAME" --parent "$PARENT_NAME"
sleep 2
done
}
#上传.repo/default.xml及manifest.xml软链接
function pushManifestsProject()
{
echo "------------pushManifestsProject---------------"
PROJECT_NAME="manifest"
PROJECT_PATH=".repo/manifests"
#在gerrit服务器创建空项目,注意--parent指定父项目,以便权限控制
echo "ssh -p $SERVER_PORT $USER_NAME@$SERVER_IP gerrit create-project $PROJECT_NAME_PREFIX/$PROJECT_NAME --parent $PARENT_NAME"
ssh -p $SERVER_PORT $USER_NAME@$SERVER_IP gerrit create-project $PROJECT_NAME_PREFIX/$PROJECT_NAME --parent "$PARENT_NAME"
sleep 2
cd "$LOCAL_PATH/$PROJECT_PATH"
#下面多分支的情况暂未用到,注释掉。
#echo `pwd`
#REMOTE_REPOSITY_NAME=`git remote`
#ALL_LOCAL_BRANCHS=`git branch -a | grep "remotes/$REMOTE_REPOSITY_NAME"`
#for branchLoop in `echo $ALL_LOCAL_BRANCHS`
#do
# BRANCH_NAME=${branchLoop#*$REMOTE_REPOSITY_NAME\/}
#建立.git目录
git init
#提交本地所以分支信息到远程分支
echo "git push ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME_PREFIX/$PROJECT_NAME HEAD:refs/heads/$BRANCH_NAME"
#首次提交,需要git add、commit
git add .
git commit -m "[Manifest][XXXX][add mainifest][1/1]"
git push ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME_PREFIX/$PROJECT_NAME HEAD:refs/heads/$BRANCH_NAME
sleep 5
#提交本地所以tag信息到远程分支
echo "git push --tag ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME_PREFIX/$PROJECT_NAME"
git push --tag ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME_PREFIX/$PROJECT_NAME
cd "$LOCAL_PATH"
#建立完整的.repo
repo init -u ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME_PREFIX/$PROJECT_NAME -b $BRANCH_NAME
#done
}
#推送本地仓库到服务器,包括本地仓库的所有branch分支信息和tag标签信息
function pushLocalReposityToRemote()
{
echo "------------pushLocalReposityToRemote---------------"
for item in ${PROJECT_LISTS[@]}
do
PROJECT_NAME=`echo "$item" | awk -F ',' '{print $1}'`
PROJECT_PATH=`echo "$item" | awk -F ',' '{print $2}'`
cd "$LOCAL_PATH/$PROJECT_PATH"
#echo `pwd`
#REMOTE_REPOSITY_NAME=`git remote`
#ALL_LOCAL_BRANCHS=`git branch -a | grep "remotes/$REMOTE_REPOSITY_NAME"`
#for branchLoop in `echo $ALL_LOCAL_BRANCHS`
#do
#BRANCH_NAME=${branchLoop#*$REMOTE_REPOSITY_NAME\/}
git init
#提交本地所以分支信息到远程分支
git add .
git commit -m "[$PROJECT_NAME][XXXX][add $PROJECT_NAME][1/1]"
echo "git push ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME HEAD:refs/heads/$BRANCH_NAME"
git push ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME HEAD:refs/heads/$BRANCH_NAME
sleep 5
#提交本地所以tag信息到远程分支
echo "git push --tag ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME"
git push --tag ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME
#done
done
}
getNameAndPath
creatEmptyGerritProject
pushManifestsProject
pushLocalReposityToRemote
二、Gerrit配置流程部分:
下面1-4步由Gerrit管理员操作。
-
Projects->Create New Project,输入parent_projectname,勾选下面空commit及仅作parent,作为所有子项目的父项目
-
执行上述shell脚本,创建各个子项目,并上传代码
-
People->Create New Group,创建人员权限组
-
Projects->List,点击parent_projectname父项目,点击Access,配置人员权限组的权限,具体配置此处不做解析。
-
需要下载代码的各个客户端登录Gerrit,注册mail,添加ssh pub key。
-
Gerrit管理员将人员添加至人员权限组
-
客户端执行repo config、init、repo sync下载代码。
三、default.xml:
下面是.repo下面的default.xml的样例,必须按照下面的格式配置
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="aosp"
fetch=".."
review="http://10.1.2.3:8088/" />
<default revision="refs/heads/project_test"
remote="aosp"
sync-j="4" />
<!--单个项目 -->
<project path="application/testapp" name="prefixprojects/application/testapp" />
……
<!--单个文件 -->
<copyfile src="compile.bat" dest="compile.bat" />
</project>
</manifest>
四、注意事项:
在创建gerrit项目时,需要注意两点:
- .gitattributes
主要用于配置换行符自动切换功能,windows与ubuntu的换行不同,配置为auto后,ubuntu与windows共通编辑同一文件时,就不会有文件未编辑,但是git status会有显示该文件有change的问题。 - .gitignore
git add .会忽略.gitignore中标注的文件夹,这样就不会再把build文件夹提到gerrit上了。git add .会忽略.gitignore中标注的文件夹,这样就不会再把build文件夹提到gerrit上了。
五、.gitignore及.gitattributes补救提交
如果项目已经建立完毕,发现.gitignore及.gitattributes忘记提交了,现在补救提交,只需要将上面的脚本做一下修改即可:
#从.repo/manifests/manifest.xml中获取各个仓的名字和路径
function getNameAndPath()
{
echo "------------getNameAndPath---------------"
ignoreLine=false
i=0
while read LINE
do
# ignore line with comments end flag
if [ `echo $LINE | grep "\-\->"` ]
then
ignoreLine=false
continue
fi
# ignore line with comments start flag
if [ `echo $LINE | grep "<!--"` ]
then
ignoreLine=true
continue
fi
# ignore line between comments start flag and comments end flag
if [ "$ignoreLine" == true ]; then continue; fi
command_line=`echo $LINE | grep "<project"`
if [ "$command_line" ]
then
#echo $LINE
reposity_name_sec=${LINE#*name=\"}
reposity_path_sec=${LINE#*path=\"}
if [ "$reposity_name_sec" ] && [ "$reposity_path_sec" ]
then
reposity_name=${reposity_name_sec%%\"*}
reposity_path=${reposity_path_sec%%\"*}
echo "$reposity_name,$reposity_path"
PROJECT_LISTS[i]="$reposity_name,$reposity_path"
((i++))
fi
fi
done < $MANIFEST_XML_FILE
echo $i
}
#推送本地仓库到服务器,包括本地仓库的所有branch分支信息和tag标签信息
function pushLocalReposityToRemote()
{
echo "------------pushLocalReposityToRemote---------------"
for item in ${PROJECT_LISTS[@]}
do
PROJECT_NAME=`echo "$item" | awk -F ',' '{print $1}'`
PROJECT_PATH=`echo "$item" | awk -F ',' '{print $2}'`
cd "$LOCAL_PATH/$PROJECT_PATH"
#echo `pwd`
#REMOTE_REPOSITY_NAME=`git remote`
#ALL_LOCAL_BRANCHS=`git branch -a | grep "remotes/$REMOTE_REPOSITY_NAME"`
#for branchLoop in `echo $ALL_LOCAL_BRANCHS`
#do
#BRANCH_NAME=${branchLoop#*$REMOTE_REPOSITY_NAME\/}
#git init
#提交本地所以分支信息到远程分支
git add .
git commit -m "[$PROJECT_NAME][XXXX][add $PROJECT_NAME/.gitatrributes and .gitignore][1/1]"
echo "git push ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME HEAD:refs/heads/$BRANCH_NAME"
git push ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME HEAD:refs/heads/$BRANCH_NAME
sleep 5
#提交本地所以tag信息到远程分支
echo "git push --tag ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME"
git push --tag ssh://$USER_NAME@$SERVER_IP:$SERVER_PORT/$PROJECT_NAME
#done
done
}
getNameAndPath
#creatEmptyGerritProject
#pushManifestsProject
pushLocalReposityToRemote