轉載請註明鏈接
環境: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