svn命令再封装--主干修改分支同步修改

svn使用过程中,svn仅提供了基础命令,当遇到特定的场景时,需要组合一个很长的命令,每次使用很不方便,因此再封装svn命令。

使用环境搭建

1、添加脚本

在服务器上的工作目录HOME下创建一个隐藏目录.bin

chenshibing@ubuntu:~$ ls -ld .bin
drwxrwxrwx 4 chenshibing chenshibing 4096 Dec  7 11:34 .bin
chenshibing@ubuntu:~$ 

把脚本tool_svn.sh放在.bin中。封装后的命令支持有空格的文件名。

2、配置环境变量

为了使命令随处可用,需要添加到环境变量中,在HOME下的.bashrc中增加如下代码

bin_files=`ls ${HOME}/.bin/*.sh`
# echo bin_file: $bin_files
for bin_file in ${bin_files}
do
        source ${bin_file}
done
# end

3、命令

$ bsvnst 
!    ?    ?!   A    AD   ADM  C    D    M    ?M   ?M!  M! 

$ bsvnfile 
!    ?    ?!   A    AD   ADM  C    D    M    ?M   ?M!  M!  

$ bsvnci
Usage: bsvnci -c svn_version

$ bsvnci_branch_config -h
Usage: bsvnci_branch_config [-[d|a] path]

解决场景

1、很多文件状态改变,上传一种状态的文件

add未上传文件

原命令
svn st --no-ignore | grep "^[I\?]" | grep -vE "(\<out\>|\.ccache\>)"' | awk '{print $2}' | svn add
封装后
bsvnfile ? | svn add

上传修改的文件

原命令
svn st  | grep "^M" | awk '{print $2}' | svn ci -m "message"
封装后
bsvnfile M | svn ci -m "message"

其他操作,可以使用bsvnst、bsvnfile+tab查看支持的选项

2、分支同步修改上传

一个分支修改,该修改要同步到其他分支
svn分支merge,需要先把分支checkout到本地,且需要切换目录。使用封装的命令就可以修改一处,配置分支后,其他分支也可以同步修改,不需要切换目录。

2.1 配置分支

查看已配置的分支
$ bsvnci_branch_config
branches:
/home2/chenshibing/svn/P_HS_AN51/sourcecode/trunk_YIUI6.51/Android_V551
/home2/chenshibing/svn/P_HS_AN51/sourcecode/trunk/Android_V551
增加分支
$ bsvnci_branch_config -a /home2/chenshibing/svn/P_HS_AN51/sourcecode/trunk/Android_V551     
branches:
/home2/chenshibing/svn/P_HS_AN51/sourcecode/trunk_YIUI6.51/Android_V551
/home2/chenshibing/svn/P_HS_AN51/sourcecode/trunk/Android_V551
删除分支
$ bsvnci_branch_config -d /home2/chenshibing/svn/P_HS_AN51/sourcecode/trunk/Android_V551     
branches:
/home2/chenshibing/svn/P_HS_AN51/sourcecode/trunk_YIUI6.51/Android_V551

2.2 修改分支并上传

主干修改同时修改分支切上传
bsvnci -m "[test]分支同步修改上传test" chenshibing
主干已上传,单独上传分支
在主干目录执行
bsvnci -c 5246

上传过程中会分别确认某个分支是否上传

tools_svn.sh源码

ALL_CHOICE=(M C \? A D AD ADM \! \?M M\! \?\! \?M\!)
function __checkparam() {
    for t in ${ALL_CHOICE[*]}
    do
	if [ x"$1" == x"$t" ];then
	    return 0
	fi 	
    done
    return 1
}

function __per_dir_do() {
    local func=$1
    local target=$2
    shift 2
    local dirs=$@
    if [ $# -eq 0 ];then
	dirs=./
    fi

    for dir in $dirs
    do
	i=0
	len=`echo $target | wc -L`
	while [ $i -lt $len ]
	do
	    t=${target:$i:1}
	    $func $t $dir 
	    let i++
	done
	echo
    done
}

function __bsvnst() {
    local files=
    if [ "$2" = "\." ];then
	files=`ls -l | grep -v "^[dl]" | awk '{print $9}' | sed -e "s/^[^ \t][ \t]*/\'/g;s/$/\'/g"`
	if [ -z "$files" ];then
	    return 
	fi
    fi

    case $1 in
    M)
	svn st $files | grep "^M";;
    A)  
	svn st $files | grep "^A";;
    D)
	svn st $files | grep "^D";;
    ?)
	svn st --no-ignore $files | grep "^[I?]" | grep -vE "(\.ccache\>)";;
	# svn st --no-ignore $files | grep "^[I?]" | grep -vE "(\<out\>|\.ccache\>)";;
    !)
	svn st $files | grep "^!";;
    C)
	echo "need implement function";;
    *)
	echo \"$1\": param error!!!
    esac
}

function bsvnfile() {
    bsvnst $@ | sed -e "s/^[^ \t][ \t]*/\'/g;s/$/\'/g"
}

function bsvnst() {
    if [ $# -eq 0 ] || [ -d $1 ];then
	if [ "$1" = "\." ];then
	    local files=`ls -l | grep -v "^[dl]" | awk '{print $9}' | sed -e "s/^[^ \t][ \t]*/\'/g;s/$/\'/g"`
            if [ -z "$files" ];then
                return 0
            fi
	    svn st --no-ignore $files
	else
	    svn st --no-ignore $1
	fi
	return 0
    fi
    
    __checkparam $1
    if [ $? -ne 0 ];then
	echo -e "\e[33Usage: bsvnst [M|C|?|A|D|AD|ADM|!|?M|M!|?!|?M!] [.|directory]\e[0m"
	return 0
    fi
    __per_dir_do '__bsvnst' $@ | sed -e '/^[ \t]*$/d'
}

function find_root()
{
   if [ ! -f ~/.config ];then
	echo ""
	return 0
   fi
   while read line
   do
	curDir=$(pwd)
	tmpStr=${curDir#*${line}}
	if [ x"$curDir" = x"$tmpStr" ];then
	    continue
	fi
	echo $line
	return 0
   done < ~/.config
   echo ""
   return 0
}

function bsvnci() {
    local message=
    local files=
    local svn_version=
    local an_root=$(find_root)

    # 1. upload modify and merge
    if [ "$1" = "-m" ];then
        if [ x"$2" = x -o -d $2 -o -f $2 ];then
	    echo "Usage: bsvnci -m \"message\" [files]"
	    return 1
        fi
	message=$2
    	shift 2
	files=$@
        svn_version=$(svn ci -m $message $files | grep "Committed revision" | sed -e 's:.*[ ]\([1-9][0-9]*\)\.$:\1:g')
        if [ -z $svn_version ];then
	    return 1
        fi
	if [ -z $an_root ];then
	    return 0
	fi
    # 2. only merge
    elif [ "$1" = "-c" -a x"$2" != x ];then
	svn_version=$(echo $2 | grep -E "(^[1-9][0-9]*[0-9]$)")
	if [ -z $svn_version ];then
	    echo "Usage: bsvnci -c svn_version"
	    return 1
	fi
    else
	echo "Usage: bsvnci -m message [files]"
	echo "       bsvnci -c svn_version"
	return 1
    fi
 
    if [ -z $an_root ];then
	echo -e "\e[31mMust bsvnci_branch_config first!\e[0m"
	return 1
    fi

    # 2.1 get merge info,eg:version,message,files
    if [ -z $svn_version ];then
        svn_version=$(svn info | grep "Revision:" | sed -e "s:Revision\:[ ]*\([1-9][0-9]*\)$:\1:g")
    fi

    svn log -r $svn_version > /dev/null
    if [ $? -ne 0 ];then
	echo -e "\e[31merror: Current dir is not exist version($svn_version)\e[0m"
	return 1
    fi

    local url=$(svn info | grep "^URL:" | awk -FURL: '{print $2}' | sed -e "s:^[ \t]::g")
    if [ -z $message ];then
        message="merge $url $svn_version"
    fi
    
    local modify_path=$(pwd | awk -F${an_root} '{print $2}')
    local branchs=$(cat ~/.config)
    if [ -z $files ];then
	local spilt_str=${modify_path}
	if [ -z $spilt_str ];then
	    spilt_str=$(basename ${an_root})
	fi
	# echo spilt_str: $spilt_str
        files=$(svn log -v -r $svn_version | grep -E "^[ \t]*[ADM][ ].*" | sed -e "s:^[ \t]*[ADM][ ]\(.*\)$:\1:g" | \
		awk -F${spilt_str} '{print $2}' | sed -e "s:^/\(.*\):\1:g")
    fi

    # 3. merge to other branch
    for branch in $branchs
    do
	branch=$(echo $branch | sed -e "s:\(.*\)/$:\1:g")
	if [ $branch = $an_root ];then
	    continue
	fi
	target_url=$(cd ${branch}${modify_path};svn info | grep "^URL:" | awk -FURL: '{print $2}' | sed -e "s:^[ \t]::g")
	echo -e "\e[36mmerge info:"
	echo -e "---------------------------"
	echo "an_root    : $an_root"
	echo "merge_path : $spilt_str"
	echo "source url : $url"
	echo "target url : $target_url"
	echo "message    : $message"
	echo "merge version: $svn_version"
	echo 
	echo $files | xargs -n 1 echo
	echo -e "\e[0m\e[32m"
	echo "svn log -v -r $svn_version"
	svn log -v -r $svn_version
	echo -e "---------------------------\e[0m"
        (
	    cd ${branch}${modify_path}
	    pwd
	    echo -e "Merge \e[36m$url svn:$svn_version\e[0m to \e[36m$target_url\e[0m" 
	    read -p "确定合并修改(Y:N):" decide
	    case $decide in
	    Y|y)
		echo -e "\e[36msvn up ${branch}${modify_path},then svn merge:$svn_version\e[0m"
		svn up
	        svn merge -c$svn_version $url
	        svn ci -m "[merge:$svn_version]$message" $files
		svn revert .
	        ;;
	    *)
	        echo "Cancle merge!";;
	    esac
	)
    done
}

function bsvnci_branch_config() {
    local act=$1
    if [[ -n $act ]] && [ -z $2 ];then
	echo "Usage: bsvnci_branch_config [-[d|a] path]" 
	return 1
    fi
    shift
    for dir in $@
    do
       case $act in
       -d)
	    sed -i "s:$dir::g" ~/.config > /dev/null
	    sed -i '/^$/d' ~/.config > /dev/null;;
       -a)
	    if [ x$(grep "$dir" ~/.config) = x ];then
	        echo $dir >>~/.config
	    fi;;
	-h|*)
	    echo "Usage: bsvnci_branch_config [-[d|a] path]";;
      esac
    done
    echo -e "\e[36mbranches:"
    cat ~/.config
    echo -e "\e[0m"
}

function _list_all_choice() {
    COMPREPLY=()
    local cur="${COMP_WORDS[COMP_CWORD]}"
    COMPREPLY=( $(compgen -W "${ALL_CHOICE[*]}" -- ${cur}) )
}
complete -F _list_all_choice bsvnst
complete -F _list_all_choice bsvnfile

猜你喜欢

转载自blog.csdn.net/mcsbary/article/details/88636050
今日推荐