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"
# 迁移列表
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迁移仓库自动化脚本

赞 (0) 打赏

精彩评论

5+8=

感谢您的支持与鼓励

支付宝扫一扫打赏

微信扫一扫打赏