脚本实现将Subversion(SVN)仓库中指定的项目自动迁移至另一个仓库,同时以此为基线创建新分支,具备完善的判断机制和日志记录功能,可放心使用。
#!/bin/bash # 工作目录 mainOpsDir="/home/demo" srcRepoDir="${mainOpsDir}/srcRepo" desRepoDir="${mainOpsDir}/desRepo" # 源仓库 srcRepoURL="http://10.10.100.1/svn/" srcRepoUsr="demo1" srcRepoPwd="Password1" # 目标仓库 desRepoURL="svn://10.10.200.2/" desRepoUsr="demo2" desRepoPwd="Password2" # 目标仓库分支(不含写在迁移列表中的基本分支) desBraList=("SIT" "UAT" "PRE" "TRUNK") # 传递是否强制删除已存在的目标分支参数(Del) frcDelFlag="$1" # 迁移列表 copyRepoList="${mainOpsDir}/copyRepoList.txt" # 迁移日志 copyRepoLogs="${mainOpsDir}/copyRepoLogs.log" # 日志等级 copyRepoLogM=("【信息】" "【警告】" "【失败】" "【成功】" "设置代码仓库基线版本") # 获取时间函数 GET_TIME () { time=`date +"%Y%m%d%H%M%S"` } # 获取上一次命令执行结果函数(仅在循环中使用) GET_PSTATUS () { if [ $? -ne 0 ] then echo -e "${time}${copyRepoLogM[2]}上一次命令执行失败" >> ${copyRepoLogs} continue fi } # 检查是否安装SVN checkCommand=`svn --version | grep -E "version|版本"` if [ -z "${checkCommand}" ] then echo "${copyRepoLogM[2]}本机没有安装subversion,终止代码迁移" exit 1 fi # 检查源仓库工作目录 if [ ! -d "${srcRepoDir}" ] then mkdir -p ${srcRepoDir} fi # 检查目标仓库工作目录 if [ ! -d "${desRepoDir}" ] then mkdir -p ${desRepoDir} fi # 检查迁移列表文件 if [ ! -e "${copyRepoList}" ] then exit 0 fi # 开始迁移仓库 cat ${copyRepoList} | grep -v "^#" | while read srcRepoName srcRepoBra desRepoName desRepoBra do echo -e "----- ${srcRepoURL}${srcRepoName} -> ${desRepoURL}${desRepoName} -----" >> ${copyRepoLogs} linenumber=`grep -nw "${srcRepoName}" ${copyRepoList} | grep -w "srcRepoBra" | grep -w "desRepoName" | grep -w "desRepoBra" | awk -F: '{print $1}'` GET_TIME # 检查列表中待迁移的仓库信息 if [ -z "${desRepoBra}" ] || [ -z "${desRepoName}" ] || [ -z "${srcRepoBra}" ] || [ -z "${srcRepoName}" ] then echo -e "${time}${copyRepoLogM[2]}第${linenumber}行项目信息不全,请查检${copyRepoList}\n" >> ${copyRepoLogs} continue fi # 检查历史记录 copyHistory=`grep "^#" ${copyRepoList} | grep -Ew "${srcRepoName}" | grep -Ew "${desRepoName}" | grep -Ew "${srcRepoBra}" | grep -Ew "${desRepoBra}"` if [ -n "${copyHistory}" ] then echo -e "${time}${copyRepoLogM[1]}该项目之前已成功同步代码,重新同步请取消第${linenumber}行首的#号\n" >> ${copyRepoLogs} continue fi # 开始检出源仓库代码 echo -e "${time}${copyRepoLogM[0]}开始检出代码${srcRepoURL}${srcRepoName}/${srcRepoBra}" >> ${copyRepoLogs} cd ${srcRepoDir} if [ -d "${srcRepoName}" ] then # 删除本地已存在的仓库目录 rm -rf ${srcRepoName} GET_TIME echo -e "${time}${copyRepoLogM[0]}已删除此前下载到本地的代码目录${srcRepoName}\n" >> ${copyRepoLogs} fi # 拉取源仓库中指定的分支 mkdir ${srcRepoName} cd ${srcRepoName} # 如果源分支中包含“/”符号 branchFlag=`echo "${srcRepoBra}" | grep "/"` if [ -n "${branchFlag}" ] then srcRepoPath=`echo ${srcRepoBra%/*}` srcRepoPathLast=`echo ${srcRepoBra##*/}` mkdir -p ${srcRepoPath} cd ${srcRepoPath} fi # 开始检出代码 svn co ${srcRepoURL}${srcRepoName}/${srcRepoBra} --username ${srcRepoUsr} --password ${srcRepoPwd} GET_PSTATUS GET_TIME # 检查源仓库分支目录 if [ ! -d "${srcRepoPathLast}" ] then echo -e "${time}${copyRepoLogM[2]}源仓库分支目录不存在,请检查${srcRepoDir}/${srcRepoName}/${srcRepoBra}\n" >> ${copyRepoLogs} continue else cd ${srcRepoPathLast} fi echo -e "${time}${copyRepoLogM[0]}完成代码检出${srcRepoURL}${srcRepoName}/${srcRepoBra}" >> ${copyRepoLogs} # 检查分支是否有效 GET_TIME srcRepoFile=`ls ${srcRepoDir}/${srcRepoName}/${srcRepoBra} | wc -l` if [ ${srcRepoFile} -eq 0 ] then echo -e "${time}${copyRepoLogM[1]}源代码库分支中没有文件,无需迁移\n" >> ${copyRepoLogs} continue fi sleep 1 # 开始检出目标仓库代码 GET_TIME echo -e "${time}${copyRepoLogM[0]}开始检出代码${desRepoURL}${desRepoName}/${desRepoBra}" >> ${copyRepoLogs} cd ${desRepoDir} if [ -d "${desRepoName}" ] then # 删除本地已存在的仓库目录 rm -rf ${desRepoName} GET_TIME echo -e "${time}${copyRepoLogM[0]}已删除此前下载到本地的代码目录${desRepoName}\n" >> ${copyRepoLogs} fi # 如果目标分支中包含“/”符号 branchFlag=`echo "${desRepoBra}" | grep "/"` if [ -n "${branchFlag}" ] then desRepoPath=`echo ${desRepoBra%/*}` mkdir -p ${desRepoPath} cd ${desRepoPath} fi # 开始检出代码 svn co ${desRepoURL}${desRepoName}/${desRepoBra} --username ${desRepoUsr} --password ${desRepoPwd} GET_PSTATUS GET_TIME echo -e "${time}${copyRepoLogM[0]}完成代码检出${desRepoURL}${desRepoName}/${desRepoBra}" >> ${copyRepoLogs} sleep 1 # 复制代码至目标分支 GET_TIME echo -e "${time}${copyRepoLogM[0]}开始从${srcRepoBra}向${desRepoBra}复制代码" >> ${copyRepoLogs} cp -rf ${srcRepoDir}/${srcRepoName}/${srcRepoBra}/* ${desRepoDir}/${desRepoName}/${desRepoBra}/ # 向代码库中添加代码 GET_TIME echo -e "${time}${copyRepoLogM[0]}开始向代码库添加代码" >> ${copyRepoLogs} svn add . --force --no-ignore --username ${desRepoUsr} --password ${desRepoPwd} GET_PSTATUS # 向代码库中提交代码 GET_TIME echo -e "${time}${copyRepoLogM[0]}开始向代码库提交代码" >> ${copyRepoLogs} svn ci -m "${copyRepoLogM[4]}" --username ${desRepoUsr} --password ${desRepoPwd} GET_PSTATUS # 若目标仓库中需要以该分支为基线创建新分支 if [ ${#desBraList[*]} -lt 0] # 未完全创建目标分支的标志(0表示已完全创建) delBraFlag=0 for desRepoBraNew in ${desBraList[@]} do GET_TIME cd ${desRepoName} # 删除已存在的目标分支 if [ -d "${desRepoBraNew}" ] then chkBraFile=`ls ${desRepoBraNew} | wc -l` if [ "${frcDelFlag}" == "Del" ] || [ "${chkBraFile}" -eq 0 ] then echo -e "${time}${copyRepoLogM[0]}尝试删除目标分支${desRepoBraNew}" >> ${copyRepoLogs} svn rm ${desRepoURL}${desRepoName}/${desRepoBraNew} -F ${copyRepoLogs} --username ${desRepoUsr} --password ${desRepoPwd} GET_PSTATUS else if [ "${delBraFlag}" -eq 0 ] then delBraFlag=1 fi echo -e "${time}${copyRepoLogM[1]}目标分支${desRepoBraNew}中存在文件且不强制删除" >> ${copyRepoLogs} continue fi fi GET_TIME # 创建分支 svn cp ${desRepoURL}${desRepoName}/${desRepoBra} ${desRepoURL}${desRepoName}/${desRepoBraNew} -m "${copyRepoLogM[4]}" --username ${desRepoUsr} --password ${desRepoPwd} GET_PSTATUS echo -e "${time}${copyRepoLogM[0]}从${desRepoBra}创建分支${desRepoBraNew}" >> ${copyRepoLogs} sleep 1 done fi # 记录代码迁移结果 GET_TIME if [ "${delBraFlag}" -eq 0 ] then echo -e "${time}${copyRepoLogM[3]}代码已迁移至${desRepoURL}${desRepoName}\n" >> ${copyRepoLogs} else echo -e "${time}${copyRepoLogM[1]}代码已迁移至${desRepoURL}${desRepoName},但某些分支创建失败,详情看日志\n" >> ${copyRepoLogs} fi # 标记迁移成功的项目记录 eval sed -i '"${linenumber}s/^/#&/"' ${copyRepoList} sleep 3 done
其中,待提交项目列表的文本格式如下:
# srcRepoName srcRepoBra desRepoName desRepoBra # 字段间用制表符或半角的空格符隔开,迁移成功后会自动注释项目所在的行 project1 trunk/code 10001_ABCD CODE/BASELINE project2 trunk/code 10002_EFGH CODE/DEV_DEMO project3 xpre/trunk 10003_IJKL TRUNK/DEMO_PROJ
原创文章禁止转载:技术学堂 » Subversion迁移仓库自动化脚本