Gerrit代码服务器搭建

转载请注明链接

环境: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管理员操作。

  1. Projects->Create New Project,输入parent_projectname,勾选下面空commit及仅作parent,作为所有子项目的父项目

  2. 执行上述shell脚本,创建各个子项目,并上传代码

  3. People->Create New Group,创建人员权限组

  4. Projects->List,点击parent_projectname父项目,点击Access,配置人员权限组的权限,具体配置此处不做解析。

  5. 需要下载代码的各个客户端登录Gerrit,注册mail,添加ssh pub key。

  6. Gerrit管理员将人员添加至人员权限组

  7. 客户端执行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项目时,需要注意两点:

  1. .gitattributes
    主要用于配置换行符自动切换功能,windows与ubuntu的换行不同,配置为auto后,ubuntu与windows共通编辑同一文件时,就不会有文件未编辑,但是git status会有显示该文件有change的问题。
  2. .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

猜你喜欢

转载自blog.csdn.net/weixin_39694445/article/details/83270650