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