Subversion迁移仓库自动化脚本

脚本实现将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"
# 迁移列表
commitList="${mainOpsDir}/commitList.txt"
# 迁移日志
commitLogs="${mainOpsDir}/commitLogs.log"
# 日志等级
commitLogM=("【信息】" "【警告】" "【失败】" "【成功】" "设置代码仓库基线版本")

# 获取时间函数
GET_TIME () {
  time=`date +"%Y%m%d%H%M%S"`
}

# 获取上一次命令执行结果函数(仅在循环中使用)
GET_PSTATUS () {
  if [ $? -ne 0 ]
  then
    echo -e "${time}${commitLogM[2]}上一次命令执行失败" >> ${commitLogs}
    continue
  fi
}

# 检查是否安装SVN
checkCommand=`svn --version | grep -E "version|版本"`
if [ -z "${checkCommand}" ]
then
  echo "${commitLogM[2]}本机没有安装subversion,终止代码迁移"
  exit 1
fi
# 检查源仓库工作目录
if [ ! -d "${srcRepoDir}" ]
then
  mkdir -p ${srcRepoDir}
fi
# 检查目标仓库工作目录
if [ ! -d "${desRepoDir}" ]
then
  mkdir -p ${desRepoDir}
fi
# 检查迁移列表文件
if [ ! -e "${commitList}" ]
then
  exit 0
fi

# 开始迁移仓库
cat ${commitList} | grep -v "^#" | while read srcRepoName srcRepoBra desRepoName desRepoBra
do
  echo -e "----- ${srcRepoURL}${srcRepoName} -> ${desRepoURL}${desRepoName} -----" >> ${commitLogs}
  linenumber=`grep -n "${srcRepoName}" ${commitList} | grep -v "^#"  | head -n 1 | awk -F: '{print $1}'`
  GET_TIME
  # 检查列表中待迁移的仓库信息
  if [ -z "${desRepoBra}" ] || [ -z "${desRepoName}" ] || [ -z "${srcRepoBra}" ] || [ -z "${srcRepoName}" ]
  then
    echo -e "${time}${commitLogM[2]}第${linenumber}行项目信息不全,请查检${commitList}\n" >> ${commitLogs}
    continue
  fi
  # 检查历史记录
  commitHistory=`grep "^#" ${commitList} | grep -E "${srcRepoName}|${desRepoName}"`
  if [ -n "${commitHistory}" ]
  then
    echo -e "${time}${commitLogM[1]}该项目之前已成功同步代码,重新同步请取消第${linenumber}行首的#号\n" >> ${commitLogs}
    continue
  fi
  # 开始检出源仓库代码
  echo -e "${time}${commitLogM[0]}开始检出代码${srcRepoURL}${srcRepoName}" >> ${commitLogs}
  cd ${srcRepoDir}
  if [ -d "${srcRepoName}" ]
  then
    # 删除本地已存在的仓库目录
    rm -rf ${srcRepoName}
  fi
  svn co ${srcRepoURL}${srcRepoName} --username ${srcRepoUsr} --password ${srcRepoPwd}
  GET_PSTATUS
  GET_TIME
  # 检查源仓库分支目录
  if [ ! -d "${srcRepoName}/${srcRepoBra}" ]
  then
    echo -e "${time}${commitLogM[2]}源仓库分支目录不存在,请检查${srcRepoURL}${srcRepoName}\n" >> ${commitLogs}
    continue
  else
    cd ${srcRepoName}/${srcRepoBra}
  fi
  echo -e "${time}${commitLogM[0]}完成代码检出${srcRepoURL}${srcRepoName}" >> ${commitLogs}
  # 检查分支是否有效
  GET_TIME
  srcRepoFile=`ls ${srcRepoDir}/${srcRepoName}/${srcRepoBra} | wc -l`
  if [ ${srcRepoFile} -eq 0 ]
  then
    echo -e "${time}${commitLogM[1]}源代码库分支中没有文件,无需迁移\n" >> ${commitLogs}
    continue
  fi
  sleep 1
  # 开始检出目标仓库代码
  GET_TIME
  echo -e "${time}${commitLogM[0]}开始检出代码${desRepoURL}${desRepoName}" >> ${commitLogs}
  cd ${desRepoDir}
  if [ -d "${desRepoName}" ]
  then
    # 删除本地已存在的仓库目录
    rm -rf ${desRepoName}
  fi
  svn co ${desRepoURL}${desRepoName} --username ${desRepoUsr} --password ${desRepoPwd}
  GET_PSTATUS
  GET_TIME
  echo -e "${time}${commitLogM[0]}完成代码检出${desRepoURL}${desRepoName}" >> ${commitLogs}
  sleep 1
  # 检查目标分支
  cd ${desRepoName}
  if [ ! -d "${desRepoBra}" ]
  then
    # 如果不存在则创建
    mkdir ${desRepoBra}
  else
    # 如果存在则进入该目录
    cd ${desRepoBra}
  fi
  # 复制代码至目标分支
  GET_TIME  
  echo -e "${time}${commitLogM[0]}开始从${srcRepoBra}向${desRepoBra}复制代码" >> ${commitLogs}
  cp -rf ${srcRepoDir}/${srcRepoName}/${srcRepoBra}/* ${desRepoDir}/${desRepoName}/${desRepoBra}/
  # 向代码库中添加代码
  GET_TIME
  echo -e "${time}${commitLogM[0]}开始向代码库添加代码" >> ${commitLogs}
  svn add . --force --no-ignore --username ${desRepoUsr} --password ${desRepoPwd}
  GET_PSTATUS
  # 向代码库中提交代码
  GET_TIME
  echo -e "${time}${commitLogM[0]}开始向代码库提交代码" >> ${commitLogs}
  svn ci -m "${commitLogM[4]}" --username ${desRepoUsr} --password ${desRepoPwd}
  GET_PSTATUS
  # 未完全创建目标分支的标志(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}${commitLogM[0]}尝试删除目标分支${desRepoBraNew}" >> ${commitLogs}
        svn rm ${desRepoURL}${desRepoName}/${desRepoBraNew} -F ${commitLogs} --username ${desRepoUsr} --password ${desRepoPwd}
        GET_PSTATUS
      else
        if [ "${delBraFlag}" -eq 0 ]
        then
          delBraFlag=1
        fi
        echo -e "${time}${commitLogM[1]}目标分支${desRepoBraNew}中存在文件且不强制删除" >> ${commitLogs}
        continue
      fi
    fi
    GET_TIME
    # 创建分支
    svn cp ${desRepoURL}${desRepoName}/${desRepoBra} ${desRepoURL}${desRepoName}/${desRepoBraNew} -m "${commitLogM[4]}" --username ${desRepoUsr} --password ${desRepoPwd}
    GET_PSTATUS
    echo -e "${time}${commitLogM[0]}从${desRepoBra}创建分支${desRepoBraNew}" >> ${commitLogs}
    sleep 1
  done
  # 记录代码迁移结果
  GET_TIME
  if [ "${delBraFlag}" -eq 0 ]
  then
    echo -e "${time}${commitLogM[3]}代码已迁移至${desRepoURL}${desRepoName}\n" >> ${commitLogs}
  else
    echo -e "${time}${commitLogM[1]}代码已迁移至${desRepoURL}${desRepoName},但某些分支创建失败,详情看日志\n" >> ${commitLogs}
  fi
  # 标记迁移成功的项目记录
  eval sed -i '"${linenumber}s/^/#&/"' ${commitList}
  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迁移仓库自动化脚本

赞 (0) 打赏

精彩评论

5+6=

感谢您的支持与鼓励

支付宝扫一扫打赏

微信扫一扫打赏