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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章