Windows 系统下,通常我们使用 TortoiseSVN 来处理 svn 客户端工作流,而 Mac 下第三方 svn GUI 工具一般都需要收费,这里我给大家友情链接一个破解版的 Cornerstone(声称 Mac 上最好用的 svn 客户端),当然更欢迎大家支持正版。
Mac OS 自带了 svn 的服务端和客户端环境,我们完全可以使用 svn 命令行快狠准地解决客户端工作流。
简单粗暴版
假设需要把项目的生产目录文件 distDir/*
转移到 svn 目录 svnDir
并提交到目标服务器,我们可以执行命令:
cd svnDir
svn update
svn delete *
cp -rf distDir/* svnDir
svn add *
svn commit -m "commit info"
这样粗暴覆盖上一个 version,基本能避免冲突,另外不建议用 svn 来处理开发过程中的代码冲突问题。
批量处理
实际上,我们经常会遇到 svn 目录下存在各种不同状态的文件或文件夹,譬如:
$ svn status
M index.html
! static/js/0.c1af89c249789814f99b.js
? static/js/0.cbb2833152f342a96f84.js
! static/js/1.62e25d5cba0e0b90bbe7.js
? static/js/1.ae9f8f72ced58a1b92eb.js
? static/js/2.5b9ab989656feaabcc44.js
! static/js/2.f852e8b7f0bebe09723e.js
! static/js/3.1f1f9a6192673180de94.js
PS: 常见的 svnstatus
及其含义
status | 含义 |
---|---|
M | 目标被修改 |
! | 目标遗失或不完整 |
? | 目标未纳入版本控制 |
A | 目标添加 |
D | 目标删除 |
C | 目标冲突 |
这个时候如果我们执行 svn add *
会失败
$ svn add *
svn: warning: W150002: 'index.html' is already under version control
svn: warning: W150002: 'static' is already under version control
svn: E200009: Could not add all targets because some targets are already versioned
svn: E200009: Illegal target for the requested operation
由于 index.html
已经在版本控制内,是无法被 add
的,所以我们需要把未纳入版本控制的项目筛选出来再添加:
# 筛选出未纳入版本控制的记录
# grep "^?" -- 匹配以`?`开始的行并输出
$ svn st | grep "^?"
? static/js/0.cbb2833152f342a96f84.js
? static/js/1.ae9f8f72ced58a1b92eb.js
? static/js/2.5b9ab989656feaabcc44.js
# 过滤出文件名
# awk '{print $2}' -- 行匹配语句,输出每行第二个字段
$ svn st | grep "^?"| awk '{print $2}'
static/js/0.cbb2833152f342a96f84.js
static/js/1.ae9f8f72ced58a1b92eb.js
static/js/2.5b9ab989656feaabcc44.js
# 把上条命令的输出插入到`svn add`命令的后面即可
$ svn add `svn st | grep "^?"| awk '{print $2}'`
A static/js/0.cbb2833152f342a96f84.js
A static/js/1.ae9f8f72ced58a1b92eb.js
A static/js/2.5b9ab989656feaabcc44.js
PS:awk
是 linux 系统下用于文本和数据处理的一种编程语言,有兴趣的可以看看教程文档。
批量添加
svn add `svn st | grep "^?"| awk '{print $2}'`
批量删除
批量删除和批量添加的流程类似,只需要把遗失状态(status == !
)的文件名筛选出来并插入到 svn delete
后面即可。
svn delete `svn st | grep ^! | awk '{print $2}'`
自动化
不妨把 svn 客户端工作流编成自动化脚本,实现一键部署。这里我设计了一个简单的脚本程序 demo,接受以下参数配置:
option | required | param desc |
---|---|---|
-s PATH | true | 源目录,通常为项目生产代码所在目录 |
-d PATH | true | svn目录 |
-m INFO | false | svn的提交信息 |
# svn-deploy.sh
#!/bin/bash
# 使用`getopts`解析命令行参数
while getopts :s:d:m: opt
do
case "$opt" in
s) SRC_DIR=$OPTARG ;;
d) SVN_DIR=$OPTARG ;;
m) COMMIT_INFO=$OPTARG ;;
*)
echo "ERROR: unknown option"
exit 0 ;;
esac
done
# 设置-s,-d参数必填
if [ -z $SRC_DIR ] || [ -z $SVN_DIR ]
then
echo "ERROR: options -s, -d is null";
exit 0;
fi
cd $SVN_DIR
svn update
svn delete *
cp -rf $SRC_DIR/* $SVN_DIR
svn add *
svn commit -m "$COMMIT_INFO"
# # 批量增删版本
# cd $SVN_DIR
# svn update
# rm -rf *
# cp -rf $SRC_DIR/* $SVN_DIR
# svn add `svn st | grep "^?"| awk '{print $2}'`
# svn delete `svn st | grep "^!" | awk '{print $2}'`
# svn commit -m $COMMIT_INFO
# 运行脚本
$ sh ./svn-deploy.sh -s ~/Documents/demo/dist -d ~/Documents/demo/svn -m "提交信息"
我们可以把脚本制作成可执行文件,并放到环境变量中支持全局调用:
$ cat svn-deploy.sh > svn-deploy
# 授予可执行权限
$ chmod +x svn-deploy
# 获取svn-deploy脚本所在目录
$ pwd
/path/to/svn-deploy
# 添加环境变量,往`.bash_profile`文件中添加:
# export PATH=/path/to/svn-deploy:$PATH
$ vim ~/.bash_profile
$ source ~/.bash_profile
接下来就可以全局使用 svn-deploy
命令了
svn-deploy -s ~/Documents/demo/dist -d ~/Documents/demo/svn
其他
如果在 svn commit
时遇到冲突或者其他异常,建议直接回滚取消当前修改:
svn revert . -R
本文中的 demo 已放在 github 上,欢迎大家一起交流。
网友评论