版本控制 - SVN

一、在linux下安装SVN:

1、Ubuntu:

apt-get install subversion

2、CentOS:

yum install subversion

————subversion已经内置了客户端还是服务端。

 

 二、服务端和客户端命令介绍:

服务端命令:

svnserve - 控制svn系统服务的启动等
svnadmin - 版本库的创建/导出/导入/删除等
svnlook - 查看版本库的信息等

客户端命令:

svn - 版本库的检出/更新/提交/重定向等

  

三、启动服务:

启动svn服务:一个完整的SVN服务会有一个服务端和多个客户端。客户端可以在任意客户端访问。

svnserve -d -r /svn/        //这种方式比较合理,可以设置多个版本库而不需要不断分配端口号。检出的时候,根目录相当于是svn

 

四、版本库的创建和删除:

创建版本库blog:

mkdir /svn
svnadmin create /svn/blog    //创建版本库blog,请注意实际的svn服务根目录是不是/svn

删除版本库——如果需要(这就是linux的rm命令):

rm rvf /svn/blog     //请注意实际的svn服务根目录是不是/svn

 

五、版本库的权限配置:

在项目仓库的conf文件夹之下,修改配置。即每个仓库都有自己的配置文件。

authz - 配置用户组以及用户组权限
passwd - 配置用户名和密钥
svnserver.conf - 配置默认权限、权限配置文件及密码配置文件

 打开svnserver.conf,如下:

 

——以上为:默认设置。如图,我们把前面的#拿掉即可。

anon-access:无账号密码用户为read,即更新。假设,想要让无账号密码的用户什么都做不了,则把read改成none即可。

auth-access:有账号密码的用户为write,既可以更新也可以写入。

password-db:指定密码文件的路径。

authz-db:指定设置用户的文件路径。

 

我们再来看下passwd的文件,设置两个用户名和密码即可,格式为[username] = [password]:

 

配置好了用户名和密码之后,我们就可以去authz里面分组和配置权限了。

打开authz,配置:

 

[aliases] - 别名配置,很少用到。

[groups] - 分组配置,上图中pm组有chenweifeng,dev组有linfeng、xingjingtao、xuhezhuo

[blog:/] - 对blog版本库设置:pm组有r的权限,dev组有rw的权限。也可以对每个用户进行权限设置。

————最后,如果要对所有成员设置,只要左边是*即可。

 

// 关于svn的重启:

当我们修改了配置文件后,我们需要重启:

//查看svn服务详情
ps aux | grep svn
//将svn服务强制停止  其中790为svn服务的ID号,-9是kill的参数
kill -9 790

或者用:

killall svnserve

再运行:

svnserve -d -r /svn/       //进行启动服务

 

六、首次导入、检出到客户端和创建trunk/branchs/tags目录

1、从服务器检出资源到本地:——请注意,我们是把整个仓库blog检出,blog里面有trunk、branchs、tags。而如果是测试环境,正式环境checkout,则需要检出的是仓库blog下的trunk。即:开发的时候,需要检出主干和分支代码,而正式环境、测试环境,只要检出主干即可。需要的时候svn up一下代码即可。

svn checkout svn://xx.xx.xx.xx/blog /Users/linfeng/svn/blog --username=linfeng --password=123456    //本地代码检出
svn checkout svn://xx.xx.xx.xx/blog/trunk /Users/linfeng/svn/blog --username=linfeng --password=123456    //正式环境、测试环境检出

—— 此时svn的地址,就是svn服务根目录地址之后开始的。一般情况下,仓库命名方式是域名,不会只是个blog。

 

2、客户端创建trunk/branchs/tags目录并提交 -  - 首次检出需要创建trunk/branchs/tags目录,如果是已经有了,你就正常使用就好了。

//切换到本地客户端,本例子即第一步中的/Users/linfeng/svn/blog
cd /Users/linfeng/svn/blog    //切换到本地仓库目录下
mkdir trunk branchs tags    //创建3个目录
svn add * --force    //加入版本库
svn commit -m '创建trunk/branchs/tags' *    //提交

 

3、第一次初始化导入(首次上传):-centOS7有防火墙问题,请添加安全组和防护墙的端口。

svn import /var/www/blog svn://127.0.0.1/blog/trunk --username=linfeng --password=123456 -m "初始化导入到主干版本"     //本例子在服务器上导入,所以源没有写IP

——导入的时候,是导入到blog/trunk之下的。web目录检出的时候,也是检出trunk目录的。

—— 注意,此时svn的根目录地址,不是服务器的根目录,而是你启动服务的地址(如/svn)之后开始算的。

 

4、本地更新:

svn up    //更新本地代码

 

 

七、常用的命令————请注意当前所在目录

 

 

 1、svn up:更新工作副本(即从服务器下载最新的)——在提交前需要先uodate,不然别人的会被你给覆盖的。第一次使用checkout,后面都使用update

svn up *      //需要先切换到该目录下

 

2、svn add:添加版本控制文件 ——有新增文件/文件夹的时候,需要先add,表示把该文件添加到版本控制里边。不然commit的时候无法传上去。

svn add js '增加js目录到版本控制'
svn add * --force     //--force表示需要扫描已加入版本库的文件夹,因为里面可能还是有文件未加入版本库

 

3、svn commit:提交修改到服务器 ——无添加文件,只是修改了文件,直接commit即可。备注为必须参数

svn commit -m "修改了main.m文件" index.html            //同步index.html到svn服务器
svn commit -m "修改了main.m文件" *        //提交版本控制里面改动过全部文件,有新增文件的时候需要先add

 

 4、svn delete:从版本库中删除文件或目录————一般会配合commit(ci)使用

svn delete 文件名        //一般delete后会commit

 

5、svn st:查看版本库当前状态 ——查看当前本地版本库库做了哪些修改

svn st  //会列出增加了哪些东西,删除了哪些东西。

 

6、批量标记已删除文件加入版本——本地手动删除文件时候(非使用svn delete删除的),会在本地版本库标记为!,需要改为D,以下命令就是批量将!改为D,则提交的时候,服务端也会删除该文件

svn status | grep ! | awk '{print $2}' | xargs svn delete

—— 如果使用svn delete删除的,则svn st,会显示状态为D,手动删除的,则会显示状态!,需操作后才会进入版本库

 

 ———— 使用频率不那么高的命令学习:

svn diff *      //比较所有文件的差异
svn diff -r 1:3 index.html      //比较index.html这个文件,版本1和版本3的区别

svn mkdir js     //创建目录并增加到版本控制
svn cat svn://IP/index.html      //不检出工作副本,直接查看svn服务器上指定文件

svn revert --recursive *      //批量还原所有文件,还原到与当前版本一直
svn revert index.html       //还原index.html与服务器一致

 

 

冲突的种类和原因:

二进制冲突:A、B都更改了同一处代码,A提交的之后,B在未更新工作副本的情况下也提交了。svn服务器认为B是不知情了。所以提示冲突。解决方法:提交前先更新。

树冲突:图片之类的(非html/css/js之类的),无法精确到某行的冲突。

 

冲突的解决:

建议推迟处理,那么冲突部分的代码,会保存到B的机器上。保存的是两个版本的都代码都有。保存后处理如下:

以下两种方式选择一种:

vim index.html    //这种方式进行编辑并保存。
svn resolve index.html    //会出现冲突出现时候的选项,这次你就可以选择商量后的结果。而不需要再推迟(P选项)。

使用vim方式处理后,需要告诉svn,index.html的冲突解决了:

svn resolved index.html

然后提交给服务器:

svn commit -m '处理了冲突' index.html

 

————当然,修改的时候,你也可以锁定该文件,让别人改不了,改完了后再解锁:

svn lock index.html    //锁定index.html,别人无法做修改
svn unlock index.html    //解锁index.html,别人又可以修改了

 

 

以下为一些文件日志查看方式:

svn ls --recursive     //递归列出当前目录下处于版本控制的所有文件。
svn st    //列出工作副本中的文件/目录的状态
svn log    //查看提交日志(也就是commit -m后面的参数)
svn info    //工作副本及文件夹的详细信息

 

 

八、创建分支版本库:使用svn copy命令 ——注意:其实一开始就需要创建trunk、branch和tag,tag是用来已发布版本的代码备份的。

1、创建分支版本

//本地的仓库
svn cp svn://xx.xx.xx.xx/blog/trunk svn://xx.xx.xx.xx/blog/branchs/blog2.0 -m '创建2.0分支' //这时候操作的是服务器的分支,本地需同步
svn up //更新本地,需要先切换到本地仓库目录

2、把工作目录转移到分支或转回主干:

svn switch svn://118.xx.xx.xx/blog/branchs/blog2.0    //转移到分支
svn switch svn://118.xx.xx.xx/blog/trunk    //转移到主干

 

 

 九、合并分支

情况一:合并一个分支到主干

// 1、切换到本地分支库,查找创建时候的版本号。
cd /Users/linfeng/svn/blog/branchs/blog2.0    //切换到分支目录
svn info    // 获取分支url  
svn log --verbose --stop-on-copy | tail -10      //获取分支创建时的版本号(r3),位于最下方

// 2、切换到主干目录,获得最新版本号,进行合并并提交:
cd /Users/linfeng/svn/blog/trunk     //切换到主干目录
svn up                    //获得最新版本号,(r5)
svn merge -r 3:5 svn://118.xx.xx.xx/blog/branchs/blog2.0     //合并3-5的版本到主干版本上
svn commit -m "提交合并分支" *    //提交合并分支

 

————至此,合并分支到主干道成功,你可以在本地进行up,则可以更新最新的代码库。

 

情况二:合并分支到主干 =>其实就是情况一反过来即可

// 1、切换到分支版本库
cd /Users/linfeng/svn/blog/branchs/blog2.0

// 2、进行合并主干版本到分支
svn merge [-r M:N] svn://118.xx.xx.xx/blog/trunk

 

 

 

十、svn自动同步到web目录。

第1步:—— 此时检出的代码是主干trunk的,所以主干有commit的时候,才会自动同步。

svn checkout svn://127.0.0.1/blog/trunk /var/www/blog -m "检出代码"

以下更贴切:

svn checkout svn://127.0.0.1/domain.com/trunk /www/wwwroot/domain.com --username=zhangsan --password=mima

 

 第2步:进入svn的项目目录,然后进入hooks目录,执行:

cd /svn/blog/hooks    //进入服务器配置目录
vim post-commit //编辑文件

然后在post-commit文件里面添加以下内容:

#!/bin/sh
#设定环境变量,如果没有设定可能会出现update报错
#设定语言,根据系统语言设置,如果是GBK就设置为 LANG=zh_CN.GBK
export LANG=en_US.utf8
SVN_PATH=/usr/bin/svn
WEB_PATH=/var/www/blog  
$SVN_PATH update $WEB_PATH --username 'linfeng' --password '123456' --no-auth-cache

第3步:赋予post-commit权限:

chmod -R 755 post-commit

————那么当你出现任何提交,都会自动同步到web目录

 

2)版本库的精简和丢弃:

 

3)版本库迁移与重定向: 

迁移:停掉svn服务,直接把整个版本库压缩成zip包。然后放到新的服务器上,新的服务器启动即可。  <<== 方式非官方

重定向:——往后svn客户端就和新的svn服务器进行通讯

// 版本库更换服务器的时候,需要进行本地仓库的重定向到新的svn服务器
cd /Users/linfeng/svn/blog svn switch --relocate svn://111.0.0.0/blog svn://111.1.1.1/blog

 

 

十一:tags目录的使用:

svn copy svn://118.xx.xx.xx/blog/trunk/ svn://118.xx.xx.xx/blog/trunk/tags/v1.0    //备份当前已发布的trunk的代码,作为阶段性代码保存

 

 十二:测试环境和正式环境

测试环境:checkout出trunk的代码,并在钩子里面设置有提交自动同步到该目录下

正式环境:checkout出trunk的代码,只有有需要的时候进行update即可。

 

 

 

————————— 总结 ————————————

 

// SVN 常用命令行-客户端

1、首次从服务器检出:

svn checkout svn地址 本地路径 --username=linfeng --password=123456

2、更新本地代码(从服务端更新最新代码)

svn up

3、添加所有变动到版本库(修改过的添加到本地版本库)

svn add * --force

4、本地版本库删除某文件

svn delete 文件名

5、提交所有更新到服务端(需要先add和delete)

svn ci -m "更新了个人文件内容" *

6、查看本地版本库当前所做的修改状态

svn st

 

 

// 基础知识

1、branches和tag都是仓库(服务端)的操作,操作完后可update到本地

2、暂存(shelve):突然临时修改BUG,而原先的功能没写完。就把原先修改的进行暂存不提交,等紧急bug提交了后再恢复。

3、选择add working copy:即添加到版本库。对应命令行为svn add *,增加新的文件的时候,会用到这个。

4、版本回退,是本地代码才有版本回退的说法,指的是本地的代码需要回退到什么版本号然后继续修改。服务端仓库的版本,是一直往上叠加的。

 

 

// 关于仓库管理(多人协作)

1、建立仓库,个人的分支代码向仓库同步(个人开发环境也在服务器)

2、总开发环境设置钩子,有提交则向仓库自动拉取代码。

3、测试环境手动拉取代码。

4、正式环境手动拉取代码。

有仓库在那里,拉取到测试、正式环境都好说。

 

 

 

 

 

————占位符

posted @ 2017-08-30 16:23  小寒1206  阅读(409)  评论(0编辑  收藏  举报