svn安装与使用

1.SVN介绍

1.1 SVN简介

  Subversion(SVN) 是一个开源的版本控制系統, 也就是说 Subversion 管理着随时间改变的数据。 这些数据放置在一个中央资料档案库(repository) 中。 这个档案库很像一个普通的文件服务器, 不过它会记住每一次文件的变动。 这样你就可以把档案恢复到旧的版本, 或是浏览文件的变动历史。

 

1.2 SVN和Git的区别

  在开发中最常使用的版本控制工具大致分为两种:git与svn(Subversion)

  对比使用来讲 svn 更利于理解与使用,且与模块式开发思维相符合

  但git对于多人协作开发来讲,其模式与设计能更好的利于开发过程中的种种问题

  所以,对此,总结分析svn与git的区别:

 

1.2.1 Git是分布式的,SVN是集中式的

  这是 Git 和 SVN 最大的区别。若能掌握这个概念,两者区别基本搞懂大半。因为 Git 是分布式的,所以 Git 支持离线工作,在本地可以进行很多操作,包括接下来将要重磅推出的分支功能。而 SVN 必须联网才能正常工作。

 

  集中式版本管理控制系统

  集中式的版本控制系统都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。

  

  Subversion的特点概括起来主要由以下几条:

  • 每个版本库有唯一的URL(官方地址),每个用户都从这个地址获取代码和数据;
  • 获取代码的更新,也只能连接到这个唯一的版本库,同步以取得最新数据;
  • 提交必须有网络连接(非本地版本库);
  • 提交需要授权,如果没有写权限,提交会失败;
  • 提交并非每次都能够成功。如果有其他人先于你提交,会提示“改动基于过时的版本,先更新再提交”… 诸如此类;
  • 冲突解决是一个提交速度的竞赛:手快者,先提交,平安无事;手慢者,后提交,可能遇到麻烦的冲突解决。

  好处:每个人都可以一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限。

  缺点:中央服务器的单点故障。

  若是宕机一小时,那么在这一小时内,谁都无法提交更新、还原、对比等,也就无法协同工作。如果中央服务器的磁盘发生故障,并且没做过备份或者备份得不够及时的话,还会有丢失数据的风险。最坏的情况是彻底丢失整个项目的所有历史更改记录,被客户端提取出来的某些快照数据除外,但这样的话依然是个问题,你不能保证所有的数据都已经有人提取出来。

  Subversion原理上只关心文件内容的具体差异。每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容

 

  分布式的版本控制系统

  分布式的版本控制系统都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们在自己本地也会创建一个库,用于保存自己的修改与提交,之后再将自己库提交至服务器库进行更新.

  

  Git记录版本历史只关心文件数据的整体是否发生变化。Git 不保存文件内容前后变化的差异数据。

  实际上,Git 更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,Git 不会再次保存,而只对上次保存的快照作一连接。

  在分布式版本控制系统中,客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。你可以根据需要设定不同的协作流程。
  另外,因为Git在本地磁盘上就保存着所有有关当前项目的历史更新,并且Git中的绝大多数操作都只需要访问本地文件和资源,不用连网,所以处理起来速度飞快。用SVN的话,没有网络或者断开VPN你就无法做任何事情。但用Git的话,就算你在飞机或者火车上,都可以非常愉快地频繁提交更新,等到了有网络的时候再上传到远程的镜像仓库。换作其他版本控制系统,这么做几乎不可能,抑或是非常麻烦。

  Git具有以下特点:

  • Git中每个克隆(clone)的版本库都是平等的。你可以从任何一个版本库的克隆来创建属于你自己的版本库,同时你的版本库也可以作为源提供给他人,只要你愿意。
  • Git的每一次提取操作,实际上都是一次对代码仓库的完整备份。
  • 提交完全在本地完成,无须别人给你授权,你的版本库你作主,并且提交总是会成功。
  • 甚至基于旧版本的改动也可以成功提交,提交会基于旧的版本创建一个新的分支。
  • Git的提交不会被打断,直到你的工作完全满意了,PUSH给他人或者他人PULL你的版本库,合并会发生在PULL和PUSH过程中,不能自动解决的冲突会提示您手工完成。
  • 冲突解决不再像是SVN一样的提交竞赛,而是在需要的时候才进行合并和冲突解决。
  • Git 也可以模拟集中式的工作模式
  • Git版本库统一放在服务器中
  • 可以为 Git 版本库进行授权:谁能创建版本库,谁能向版本库PUSH,谁能够读取(克隆)版本库
  • 团队的成员先将服务器的版本库克隆到本地;并经常的从服务器的版本库拉(PULL)最新的更新;
  • 团队的成员将自己的改动推(PUSH)到服务器的版本库中,当其他人和版本库同步(PULL)时,会自动获取改变
  • Git 的集中式工作模式非常灵活
  • 你完全可以在脱离Git服务器所在网络的情况下,如移动办公/出差时,照常使用代码库
  • 你只需要在能够接入Git服务器所在网络时,PULL和PUSH即可完成和服务器同步以及提交
  • Git提供 rebase 命令,可以让你的改动看起来是基于最新的代码实现的改动
  • Git 有更多的工作模式可以选择,远非 Subversion可比

 

1.2.2 Git复杂概念多,SVN简单易上手

  所有同时掌握 Git 和 SVN 的开发者都必须承认,Git 的命令实在太多了,日常工作需要掌握add,commit,status,fetch,push,rebase等,若要熟练掌握,还必须掌握rebase和merge的区别,fetch和pull的区别等,除此之外,还有cherry-pick,submodule,stash等功能,仅是这些名词听着都很绕。

  在易用性这方面,SVN 会好得多,简单易上手,对新手很友好。但是从另外一方面看,Git 命令多意味着功能多,若我们能掌握大部分 Git 的功能,体会到其中的奥妙,会发现再也回不去 SVN 的时代了。

 

1.2.3 Git分支廉价,SVN分支昂贵

  在版本管理里,分支是很常使用的功能。在发布版本前,需要发布分支,进行大需求开发,需要 feature 分支,大团队还会有开发分支,稳定分支等。在大团队开发过程中,常常存在创建分支,切换分支的需求。

  Git 分支是指针指向某次提交,而 SVN 分支是拷贝的目录。这个特性使 Git 的分支切换非常迅速,且创建成本非常低。

  而且 Git 有本地分支,SVN 无本地分支。在实际开发过程中,经常会遇到有些代码没写完,但是需紧急处理其他问题,若我们使用 Git,便可以创建本地分支存储没写完的代码,待问题处理完后,再回到本地分支继续完成代码。

 

1.2.4 Git 核心概念

  Git 最核心的一个概念就是工作流。

  • 工作区(Workspace)是电脑中实际的目录。
  • 暂存区(Index)类似于缓存区域,临时保存你的改动。
  • 仓库区(Repository),分为本地仓库和远程仓库。

  从 SVN 切换到 Git,最难理解并且最不能理解的是暂存区和本地仓库。熟练使用 Git 后,会发现这简直是神设计,由于这两者的存在,使许多工作变得易管理。

  通常提交代码分为几步:

  1.git add从工作区提交到暂存区

  2.git commit从暂存区提交到本地仓库

  3.git push或git svn dcommit从本地仓库提交到远程仓库

  一般来说,记住以下命令,便可进行日常工作了(图片来源于网络):

  

 

1.3 SVN服务端运行方式及客户端访问方式

  

  

 

1.4 SVN档案数据格式

  svn存储版本数据有2种方式:BDB(一种事务安全型表类型)和FSFS(一种不需要数据库的存储系统)。因为BDB方式在服务器中断时,有可能锁住数据,所以还是FSFS方式更安全一点。

  BDB

  伯克利DB(Berkeley DB),版本库可以使用一种经过充分测试的后台数据库实现,不能在通过网络共享的文件系统上使用,伯克利DB是Subversion1.2版本以前的缺省版本库格式。

  FSFS

  一个专用于Subversion版本库的文件系统后端,可以使用网络文件系统(例如NFS或SMBFS)。是1.2版本及其后的缺省版本库格式。

  CSV是个基于RCS文件的版本控制系统。每个CSV文件都不过是普通的文件,加上一些额外的信息。这些文件会简单的重复本地文件的树结构。因此,不必担心有什么数据损失,如果必要的话可以手工修改RCS文件。

  SVN是基于关系数据库的(BerkleyDB)或一系列二进制文件的(FS_FS)。一方面这解决了许多问题(例如,并行读写共享文件)以及添加了许多新功能(例如运行时的事务特性)然而另一方面,数据存储由此变得不透明,不能像ftp,samba,nfs等看到实体文件了。

  小总结: 因为BDB方式在服务器中断时,有可能锁住数据(搞ldap时就深受其害,没法根治),所以还是FSFS方式更安全一点,我也选择这种方式。

 

1.5 SVN 的一些概念

  • repository(源代码库):源代码统一存放的地方
  • Checkout(提取):当你手上没有源代码的时候,你需要从 repository checkout 一份
  • Commit(提交):当你已经修改了代码,你就需要Commit到repository
  • Update (更新):当你已经 checkout 了一份源代码, update 一下你就可以和Repository上的源代码同步,你手上的代码就会有最新的变更

  日常开发过程其实就是这样的(假设你已经Checkout并且已经工作了几天):Update(获得最新的代码) -->作出自己的修改并调试成功 --> Commit(大家就可以看到你的修改了) 。

  如果两个程序员同时修改了同一个文件呢, SVN 可以合并这两个程序员的改动,实际上 SVN 管理源代码是以行为单位的,就是说两个程序员只要不是修改了同一行程序,SVN 都会自动合并两种修改。如果是同一行,SVN 会提示文件 Conflict, 冲突,需要手动确认。

 

1.6 SVN的主要功能

  (1)目录版本控制

  CVS 只能跟踪单个文件的历史, 不过 Subversion 实作了一个 "虚拟" 的版本控管文件系统, 能够依时间跟踪整个目录的变动。 目录和文件都能进行版本控制。

  (2)真实的版本历史

  自从 CVS 限制了文件的版本记录,CVS 并不支持那些可能发生在文件上,但会影响所在目录内容的操作,如同复制和重命名。除此之外,在 CVS 里你不能用拥有同样名字但是没有继承老版本历史或者根本没有关系的文件替换一个已经纳入系统的文件。在 Subversion 中,你可以增加(add)、删除(delete)、复制(copy)和重命名(rename),无论是文件还是目录。所有的新加的文件都从一个新的、干净的版本开始。

  (3)自动提交

  一个提交动作,不是全部更新到了档案库中,就是不完全更新。这允许开发人员以逻辑区间建立并提交变动,以防止当部分提交成功时出现的问题。

  (4)纳入版本控管的元数据

  每一个文件与目录都附有一組属性关键字并和属性值相关联。你可以创建, 并儲存任何你想要的Key/Value对。 属性是随着时间来作版本控管的,就像文件內容一样。

  (5)选择不同的网络层

  Subversion 有抽象的档案库存取概念, 可以让人很容易地实作新的网络机制。 Subversion 可以作为一个扩展模块嵌入到 Apache HTTP 服务器中。这个为 Subversion 提供了非常先进的稳定性和协同工作能力,除此之外还提供了许多重要功能: 举例来说, 有身份认证, 授权, 在线压缩, 以及文件库浏览等等。还有一个轻量级的独立 Subversion 服务器, 使用的是自定义的通信协议, 可以很容易地通过 ssh 以 tunnel 方式使用。

  (6)一致的数据处理方式

  Subversion 使用二进制差异算法来异表示文件的差异, 它对文字(人类可理解的)与二进制文件(人类无法理解的) 两类的文件都一视同仁。 这两类的文件都同样地以压缩形式储存在档案库中, 而且文件差异是以两个方向在网络上传输的。

  (7)有效的分支(branch)与标签(tag)

  在分支与标签上的消耗并不必一定要与项目大小成正比。 Subversion 建立分支与标签的方法, 就只是复制该项目, 使用的方法就类似于硬连接(hard-link)。 所以这些操作只会花费很小, 而且是固定的时间。

  (8)Hackability

  Subversion没有任何的历史包袱; 它主要是一群共用的 C 程序库, 具有定义完善的API。这使得 Subversion 便于维护, 并且可被其它应用程序与程序语言使用。

 

1.7 优于 CVS 之处

  1、原子提交:一次提交不管是单个还是多个文件,都是作为一个整体提交的,所以要么全部提交成功,要么就是全部不成功,这样就不会引起数据库的不完整和数据损坏。

  2、重命名、复制、删除文件等动作都保存在版本历史记录当中。

  3、对于二进制文件,使用了节省空间的保存方法。(简单的理解,就是只保存和上一版本不同之处)

  4、目录也有版本历史。整个目录树可以被移动或者复制,操作很简单,而且能够保留全部版本记录。

  5、分支的开销非常小。

  6、优化过的数据库访问,使得一些操作不必访问数据库就可以做到。这样减少了很多不必要的和数据库主机之间的网络流量。

 

2.SVN 生命周期

  本章讨论了版本控制系统的生命周期。

  创建版本库

  版本库相当于一个集中的空间,用于存放开发者所有的工作成果。版本库不仅能存放文件,还包括了每次修改的历史,即每个文件的变动历史。

  Create 操作是用来创建一个新的版本库。大多数情况下这个操作只会执行一次。当你创建一个新的版本库的时候,你的版本控制系统会让你提供一些信息来标识版本库,例如创建的位置和版本库的名字。

  检出

  Checkout 操作是用来从版本库创建一个工作副本。工作副本是开发者私人的工作空间,可以进行内容的修改,然后提交到版本库中。

  更新

  顾名思义,update 操作是用来更新版本库的。这个操作将工作副本与版本库进行同步。由于版本库是由整个团队共用的,当其他人提交了他们的改动之后,你的工作副本就会过期。

  让我们假设 Tom 和 Jerry 是一个项目的两个开发者。他们同时从版本库中检出了最新的版本并开始工作。此时,工作副本是与版本库完全同步的。然后,Jerry 很高效的完成了他的工作并提交了更改到版本库中。

  此时 Tom 的工作副本就过期了。更新操作将会从版本库中拉取 Jerry 的最新改动并将 Tom 的工作副本进行更新。

  执行变更

  当检出之后,你就可以做很多操作来执行变更。编辑是最常用的操作。你可以编辑已存在的文件,例如进行文件的添加/删除操作。

  你可以添加文件/目录。但是这些添加的文件目录不会立刻成为版本库的一部分,而是被添加进待变更列表中,直到执行了 commit 操作后才会成为版本库的一部分。

  同样地你可以删除文件/目录。删除操作立刻将文件从工作副本中删除掉,但该文件的实际删除只是被添加到了待变更列表中,直到执行了 commit 操作后才会真正删除。

  Rename 操作可以更改文件/目录的名字。"移动"操作用来将文件/目录从一处移动到版本库中的另一处。

  复查变化

  当你检出工作副本或者更新工作副本后,你的工作副本就跟版本库完全同步了。但是当你对工作副本进行一些修改之后,你的工作副本会比版本库要新。在 commit 操作之前复查下你的修改是一个很好的习惯。

  Status 操作列出了工作副本中所进行的变动。正如我们之前提到的,你对工作副本的任何改动都会成为待变更列表的一部分。Status 操作就是用来查看这个待变更列表。

  Status 操作只是提供了一个变动列表,但并不提供变动的详细信息。你可以用 diff 操作来查看这些变动的详细信息。

  修复错误

  我们来假设你对工作副本做了许多修改,但是现在你不想要这些修改了,这时候 revert 操作将会帮助你。

  Revert 操作重置了对工作副本的修改。它可以重置一个或多个文件/目录。当然它也可以重置整个工作副本。在这种情况下,revert 操作将会销毁待变更列表并将工作副本恢复到原始状态。

  解决冲突

  合并的时候可能会发生冲突。Merge 操作会自动处理可以安全合并的东西。其它的会被当做冲突。例如,"hello.c" 文件在一个分支上被修改,在另一个分支上被删除了。这种情况就需要人为处理。Resolve 操作就是用来帮助用户找出冲突并告诉版本库如何处理这些冲突。

  提交更改

  Commit 操作是用来将更改从工作副本到版本库。这个操作会修改版本库的内容,其它开发者可以通过更新他们的工作副本来查看这些修改。

  在提交之前,你必须将文件/目录添加到待变更列表中。列表中记录了将会被提交的改动。当提交的时候,我们通常会提供一个注释来说明为什么会进行这些改动。这个注释也会成为版本库历史记录的一部分。Commit 是一个原子操作,也就是说要么完全提交成功,要么失败回滚。用户不会看到成功提交一半的情况。

 

3.SVN安装

  本次安装在centos7.9上

  1.安装

yum install subversion

 

  2.测试安装是否成功

svnserve --version

 

  3.创建目录并配置

  建立版本库目录

mkdir -pv /data/svn/tw-hxh/prod

  配置

svnadmin create  /data/svn/tw-hxh/prod
#这里为什么有4级目录?
#/data是根目录,这里不做解释
#二级目录svn是一个识别目录,让人知道这是svn的存储目录 
#tw-hxh这是一个项目的所有目录,为什么这里要指定tw-hxh标识?是因为这个项目下面到时候会有很多版本库,比如prod,test,cqc,所有版本库的认证和密码文件也可以放在这里目录下面,那么这样可能就是针对单个项目搭建的svn 
#prod这是单个版本库的目录,可能有cqc,test等版本库

  执行上面的命令后,自动建立repo测试库,查看/data/svn/tw-hxh/prod文件夹发现包含了conf, db,format,hooks, locks, README.txt等文件,说明一个SVN库已经建立。

  创建svn项目时,用svnadmin来创建项目,如果不是使用svn来创建,那么svn就不是svn可管理的项目了

  用svnadmin create –help 也可以看到,svn1.6版本创建的默认文件类型为fsfs

 

  4.配置用户密码

  用户名口令文件由svnserve.conf的配置项password-db指定,缺省为conf目录中的passwd。该文件仅由一个[users]配置段组成。

  [users]配置段的配置行格式如下:

  <用户名> = <口令>

  注意:配置行中的口令为未经过任何处理的明文。

vim /data/svn/tw-hxh/prod/conf/passwd

  

  建立用户lizexiong,密码huawei

       

  5.权限配置

  权限配置文件由svnserve.conf的配置项authz-db指定,缺省为conf目录中的authz。该配置文件由一个[groups]配置段和若干个版本库路径权限段组成。

  [groups]配置段中配置行格式如下:

  <用户组> = <用户列表>

  用户列表由若干个用户组或用户名构成,用户组或用户名之间用逗号","分隔,引用用户组时要使用前缀"@"(如:引用用户组"all"要使用字符串"@all")。

  版本库路径权限段的段名格式如下:

  [<版本库名>:<路径>]

  如版本库abc路径/tmp的版本库路径权限段的段名为"[abc:/tmp]"。

  可省略段名中的版本库名。若省略版本库名,则该版本库路径权限段对所有版本库中相同路径的访问控制都有效。如:段名为"[/tmp]"的版本库路径权限段设置了所有引用该权限配置文件的版本库中目录"/tmp"的访问权限。

  版本库路径权限段中配置行格式有如下三种:

  <用户名> = <权限>

  <用户组> = <权限>

  * = <权限>

  其中,"*"表示任何用户;权限的取值范围为''、'r'和'rw',''表示对该版本库路径无任何权限,'r'表示具有只读权限,'rw'表示有读写权限。

  注意:每行配置只能配置单个用户或用户组。

 

  设置哪些用户可以访问哪些目录

vim /data/svn/tw-hxh/prod/conf/authz

  

 

  6.服务svnserve.conf配置

  注意:所有的行都必须顶格,否则报错。

  [general]配置段中配置行格式如下:

  <配置项> = <值>

  配置项分为以下5项:

  anon-access 控制非鉴权用户访问版本库的权限。取值范围为"write"、"read"和"none"。

  即"write"为可读可写,"read"为只读,"none"表示无访问权限。

  缺省值:read

  auth-access 控制鉴权用户访问版本库的权限。取值范围为"write"、"read"和"none"。

  即"write"为可读可写,"read"为只读,"none"表示无访问权限。

  缺省值:write

  password-db 指定用户名口令文件名。除非指定绝对路径,否则文件位置为相对conf

  目录的相对路径。

  缺省值:passwd

  authz-db 指定权限配置文件名,通过该文件可以实现以路径为基础的访问控制。

  除非指定绝对路径,否则文件位置为相对conf目录的相对路径。

  缺省值:authz

  realm 指定版本库的认证域,即在登录时提示的认证域名称。若两个版本库的

  认证域相同,建议使用相同的用户名口令数据文件。

  缺省值:一个UUID(Universal Unique IDentifier,全局唯一标示)。

  [sasl]

  简单来说就联系windows做验证的,这里用不到

  这里在前文创建了统一的密码文件及权限文件文件夹,这里把密码文件和权限文件全部指定到该文件夹下面,这样的好处是当有了多个项目版本库的时候都使用同一个文件

vim /data/svn/tw-hxh/prod/conf/svnserve.conf

  在[general]下追加以下内容

#匿名访问的权限,可以是read,write,none,默认为read
anon-access=none
##使授权用户有写权限 
auth-access=write
##密码数据库的路径 
password-db=passwd
##访问控制文件 
authz-db=authz
##认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字 
#这里填自己的版本库目录就行,最好不要填公共的
realm=/data/svn/tw-hxh/prod

 

  7.svn目录结构

  在svn创建仓库启动后,会有一系列以下目录,这里还是贴出一下解释

路径 类型 作用
conf 目录 存放版本库所用配置文件的目录
dav 目录 供mod_dav_svn使用
db 目录 版本数据存储目录
db/fs-type 文件 版本库数据真实存储格式,SVN有fsfs和bdb两种存储格式
db/revprops 目录 记录版本属性
db/revs 目录 版本库数据存储真实目录
db/uuid 文件 存储版本库唯一标识号,参考《svn版本库标识uuid简述》
db/txn-current 文件 记录当前事务
format 文件 储一个整数的文件,此整数代表库层次结构版本
hooks 目录 存放版本库勾子目录
locks 目录 存储库锁目录,用来跟踪库的访问者

 

  8.启动服务

  查看svn的服务是否启动

ps -ef|grep svn

  如果没有启动执行 下面命令即可:

svnserve -d -r /data/svn/tw-hxh/prod --listen-port=3690 --log-file /data/svn/tw-hxh/prod/svn.log
#这里-r /data/svn/tw-hxh/prod很重要,如果是/data/svn/tw-hxh/prod启动,那么这个目录就是svn的根目录,后面在创建其它版本库就会比较麻烦,因为你指定了一个版本库作为启动根目录
svnserve -d -r /data/svn/ --listen-port=3690 --log-file /data/svn/svn.log
#如果是这样/data/svn,那么可以用svnadmin创建很多目录,并且通过统一的auth和passwd来管理用户和权限,甚至可以管理多个项目,如tw-hxh,cn-hxh,等等,但是权限方面就是独立的,这种方式废弃,linux上不存在
svnserve -d -r /data/svn/tw-hxh --listen-port=3690 --log-file /data/svn/tw-hxh/svn.log
#如果是这样/data/svn/tw-hxh,那么可以用svnadmin创建很多目录,并且通过统一的auth和passwd来管理用户和权限,和第二种方式比起来,可以方便的管理一个项目的多个版本库,由于这里只是给单个项目更新用,所以选择这种方式,针对一个项目做管理,折中选择一下

 

  9.访问

  svn://ip地址

  输入配置好的用户名和密码即可。

  上面步骤配置的是svn协议,下面配置http协议。

 

  10.使用http协议连接svn

  1).安装Apache

yum install -y httpd mod_dav_svn 安装httpd和svn模块
#查看版本
httpd -version

  查看是否有mod_dav_svn.so和mod_authz_svn.so模块,如果有,说明mod_dav_svn安装成功!

ls /etc/httpd/modules/

  

 

  2).修改配置文件(没有则新建)

vim /etc/httpd/conf.d/subversion.conf
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

<Location /svn>
    DAV svn
SVNListParentPath on
#这里也要注意,注意路径规律
    SVNParentPath /data/svn/tw-hxh
    AuthType Basic
    Satisfy Any
AuthName "Subversion repos"
#这里的可不要误会,这里的不是svn的访问密码文件,是http的,2个文件都需要,所以文件是http_passwd
    AuthUserFile /data/svn/tw-hxh/prod/conf/http_passwd
    AuthzSVNAccessFile /data/svn/tw-hxh/prod/conf/authz
    Require valid-user
</Location>

 

  3).设置权限

chown apache:apache /data/svn/ -R

 

  4.)设置Apache http访问用户名,按提示输入两次相同密码

  注意:这里的用户名密码要和svn里配置的一样。passwd和http_passwd文件中,账号密码必须设置相同。

htpasswd -cm /data/svn/tw-hxh/prod/conf/http_passwd lizexiong

  PS:htpasswd命令是Apache的Web服务器内置工具,用于创建和更新储存用户名、域和用户基本认证的密码文件。

  -c:创建一个加密文件;

  -m:默认采用MD5算法对密码进行加密;

  -D:删除指定的用户。

  -b:在命令行中一并输入用户名和密码而不是根据提示输入密码;

 

  5.)启动Apache,查看httpd状态是否成功运行,并加入开机启动

service httpd start
service httpd status
#设置开机启动
chkconfig httpd on  #设置开机启动

 

  11.使用http协议连接svn

  1).安装https模块

yum -y install httpd-devel mod_ssl openssl

 

  2).配置https模块

  使用openssl配置,整个openssl过程复杂,这里只列出本svn https访问所需要配置及解释,深入请百度 apache https 访问

cd  /etc/pki/tls/private  
openssl  genrsa  -out  my.key  1024    
openssl  req  -new  -key  my.key  -out  my.csr  
cd  /etc/pki/tls/certs  
openssl  x509  -req  -days  365  -in  /etc/pki/tls/private/my.csr  -signkey  /etc/pki/tls/private/my.key  -out  my.crt
#以上命令,下面图示演示出使用方式

  生成服务器用的私钥文件my.key

  

  生成服务器证书请求,并按要求填些相关证书信息

  

  这里按照提示输入信息,因为这里本人是用ip访问,所以填写的是IP

  在网站名称的时候一定要填自己访问时输入的域名或者IP,否者证书会报错

  这里写出提示输入的解释

State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:HZ所在城市
Organization Name (eg, company):SW_TECH公司名称
Organizational Unit Name (eg, section) []:SW_TECH组织名称
Common Name (eg, YOUR name) []:kedou.com申请证书的域名
Email Address []:admin@admin.com 管理员邮箱
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: 交换密钥
An optional company name []:  注:Common Name必须和httpd.conf中server name必须一致,否则apache不能启动 (启动apache报错)

  签证

  

 

  3.)修改ssl配置文件/etc/https/conf.d/ssl.conf,指定ssl认证文件位置

  SSLCertificateFile /etc/pki/tls/certs/my.crt 

  SSLCertificateKeyFile /etc/pki/tls/private/my.key

  

 

  4).开启ssl模块,开启ssl访问

  这里不开启所有ssl访问,否者不管什么访问都是ssl,如果只需要访问本地,只要在subversion.conf开启就可以了

  开启全局https

  

  仅开启subversion https访问

  

 

  5).现在可以使用https web方式访问测试了

  注意,这里的访问链接地址一定要指定到版本库正确地址,否则会出现报错

  如,本人版本库是 svnrepos,那么链接地址就是

  https://172.21.161.161/prod

  

  点击那个小锁就会发现出现以下内容

  

  上面访问发现有证书风险,那是因为这个证书包括ca都是自建的,需要让浏览器信任我这个ca机构。(即使现在信任之后,也会有此网站尚未通过身份验证的错误,所以还是建议申请一个免费的ssl证书,腾讯云,阿里云都有)

  导入刚才生成的/etc/pki/tls/certs/my.crt文件即可。

  

  导入完成后就变成下面这种没有报错的情况,但是360浏览器还是会报错

  

  ie浏览器显示正常,360可能经过了更新,几年前的360也会显示正常,但是该办法治标不治本,还是建议申请公共免费的ssl证书。

 

4.SVN 检出操作

  首先还是强调启动的时候/data/svn/tw-hxh为根目录,这样方便添加多版本库以及方便对多版本库管理。

  上一章中,我们创建了版本库svnrepos,URL为svn://172.21.161.161/prod, https的访问方式如下:https://172.21.161.161/svn/prod, svn用户lizexiong有读写权限。

  那么就用svn checkout url --username=lizexiong ,以上两种方式都可以拉取代码。

  以上命令将产生如下结果:

  

  因为目前里面没有文件,所以啥都没有

 

5.SVN 提交操作

  在上一章中,我们检出了版本库tw-hxh/prod,对应的目录放在/tmp/svnurl/prod中,下面我们针对这个库进行版本控制。(这里使用svnurl做测试)

  我们在库本版中需要增加一个readme的说明文件。

  

  查看工作副本库的状态

  

  此时 readme的状态为?,说明它还未加到版本控制中。

  将文件readme加到版本控制,等待提交到版本库。

  

  查看工作副本中的状态

  

  此时 readme的状态为A,它意味着这个文件已经被成功地添加到了版本控制中。

  为了把 readme 存储到版本库中,使用 commit -m 加上注释信息来提交。

  如果你忽略了 -m 选项, SVN会打开一个可以输入多行的文本编辑器来让你输入提交信息。

  

  现在 readme 被成功地添加到了版本库中,并且修订版本号自动增加了1。

   

6.SVN版本回退

  当我们想放弃对文件的修改,可以使用 SVN revert 命令。

  svn revert 操作将撤销任何文件或目录里的局部更改。

  我们对文件 readme 进行修改,查看文件状态。

  比如在刚才的readmin文件中新增This is  a v2

  

  现在查看状态

  

  这时我们发现修改错误,要撤销修改,通过 svn revert 文件 readme 回归到未修改状态。

  

  进行 revert 操作之后,readme 文件恢复了原始的状态。 revert 操作不单单可以使单个文件恢复原状, 而且可以使整个目录恢复原状。恢复目录用 -R 命令,如下。

svn revert -R trunk

  但是,假如我们想恢复一个已经提交的版本怎么办。

  为了消除一个旧版本,我们必须撤销旧版本里的所有更改然后提交一个新版本。这种操作叫做 reverse merge。

  首先,找到仓库的当前版本,现在是版本 2,我们要撤销回之前的版本,比如版本 1。

  (现在为了模拟环境,我们还是提交一个v2版本)

  

 

7.SVN 查看历史信息

  通过svn命令可以根据时间或修订号去除过去的版本,或者某一版本所做的具体的修改。以下四个命令可以用来查看svn 的历史:

  • svn log: 用来展示svn 的版本作者、日期、路径等等。
  • svn diff: 用来显示特定修改的行级详细信息。
  • svn cat: 取得在特定版本的某文件显示在当前屏幕。
  • svn list: 显示一个目录或某一版本存在的文件。

  先准备一下测试环境,来演示下面的案例,因为刚才有个撤销操作,所以这里v3版本实际上是svn的4版本,我测试填写的版本号落后svn一位,这里需要注意。

  

 

7.1 svn log

  可以显示所有的信息,如果只希望查看特定的某两个版本之间的信息,可以使用:

[root@public prod]# svn log -r 4:6
------------------------------------------------------------------------
r4 | lizexiong | 2022-09-19 18:20:55 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v3
------------------------------------------------------------------------
r5 | lizexiong | 2022-09-19 18:21:10 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v4
------------------------------------------------------------------------
r6 | lizexiong | 2022-09-19 18:21:19 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v5
------------------------------------------------------------------------

  如果只想查看某一个文件的版本修改信息,可以使用 svn log 文件路径。

[root@public prod]# svn log readme 
------------------------------------------------------------------------
r8 | lizexiong | 2022-09-19 18:21:37 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v7
------------------------------------------------------------------------
r7 | lizexiong | 2022-09-19 18:21:29 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v6
------------------------------------------------------------------------
r6 | lizexiong | 2022-09-19 18:21:19 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v5
------------------------------------------------------------------------
r5 | lizexiong | 2022-09-19 18:21:10 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v4
------------------------------------------------------------------------
r4 | lizexiong | 2022-09-19 18:20:55 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v3
------------------------------------------------------------------------
r3 | lizexiong | 2022-09-19 18:20:44 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v2
------------------------------------------------------------------------
r2 | lizexiong | 2022-09-19 16:55:27 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod v2
------------------------------------------------------------------------
r1 | lizexiong | 2022-09-19 16:50:38 +0800 (一, 2022-09-19) | 1 行

tw-hxh/prod readme
------------------------------------------------------------------------

  如果希望得到目录的信息要加 -v

  如果希望显示限定N条记录的目录信息,使用 svn log -l N -v

[root@public prod]#svn log -l 3 -v readme 
------------------------------------------------------------------------
r8 | lizexiong | 2022-09-19 18:21:37 +0800 (一, 2022-09-19) | 1 行
改变的路径: 
   M /readme

tw-hxh/prod v7
------------------------------------------------------------------------
r7 | lizexiong | 2022-09-19 18:21:29 +0800 (一, 2022-09-19) | 1 行
改变的路径: 
   M /readme

tw-hxh/prod v6
------------------------------------------------------------------------
r6 | lizexiong | 2022-09-19 18:21:19 +0800 (一, 2022-09-19) | 1 行
改变的路径: 
   M /readme

tw-hxh/prod v5
------------------------------------------------------------------------

 

7.2 svn diff

  用来检查历史修改的详情。

  • 检查本地修改
  • 比较工作拷贝与版本库
  • 比较版本库与版本库

  (1)、如果用 svn diff,不带任何参数,它将会比较你的工作文件与缓存在 .svn 的"原始"拷贝。

  

 

  (2)、比较工作拷贝和版本库

  比较你的工作拷贝和版本库中版本号为 3 的文件 readme。

  

 

  (3)、比较版本库与版本库

  通过 -r(revision) 传递两个通过冒号分开的版本号,这两个版本会进行比较。

  比较 svn 工作版本中版本号1和2的这个文件的变化。

  

 

7.3 svn cat

  如果只是希望检查一个过去版本,不希望查看他们的区别,可使用svn cat

  

  这个命令会显示在该版本号下的该文件内容

 

7.4 svn list

  svn list 可以在不下载文件到本地目录的情况下来察看目录中的文件:

  

 

8.SVN分支

  Branch 选项会给开发者创建出另外一条线路。当有人希望开发进程分开成两条不同的线路时,这个选项会非常有用。

  比如项目 demo 下有两个小组,svn 下有一个 trunk 版。

  由于客户需求突然变化,导致项目需要做较大改动,此时项目组决定由小组 1 继续完成原来正进行到一半的工作(某个模块),小组 2 进行新需求的开发。

  那么此时,我们就可以为小组2建立一个分支,分支其实就是 trunk 版(主干线)的一个copy版,不过分支也是具有版本控制功能的,而且是和主干线相互独立的,当然,到最后我们可以通过(合并)功能,将分支合并到 trunk 上来,从而最后合并为一个项目。

  我们在本地副本中创建一个my_branch 分支。

[root@public prod]# svn mkdir trunk tags branches
A         trunk
A         tags
A         branches
[root@public prod]# ls
branches  readme  tags  trunk
[root@public prod]# cd trunk/
[root@public trunk]# echo "Hello World" >> HelloWorld.html
[root@public trunk]# svn add HelloWorld.html 
A         HelloWorld.html
[root@public trunk]# svn commit -m "trunk/HelloWorld.thml"
正在增加       .
正在增加       HelloWorld.html
传输文件数据.
提交后的版本为 34。
[root@public trunk]# svn status
#以上是准备环境,先提交一下trunk的环境HelloWorld.html到svn,然后在创建分支
[root@public trunk]# cd ../
[root@public prod]# svn copy trunk/ branches/my_branch
A         branches/my_branch

  查看状态:

[root@public prod]# svn status
A       branches
A  +    branches/my_branch
A       tags

  提交新增的分支到版本库。

  这里因为branches,tag,trunk都是一起创建测试的,所以会显示出所有的一起提交,但是不要紧,知道就行。

[root@public prod]# svn commit -m "add my_branch" 
正在增加       branches
正在增加       branches/my_branch
正在增加       tags

提交后的版本为 35。

  接着我们就到 my_branch 分支进行开发,切换到分支路径并创建 index.html 文件。

[root@public prod]# cd branches/my_branch/
[root@public my_branch]# ls
HelloWorld.html
[root@public my_branch]# echo "index"  >> index.html
[root@public my_branch]# ls
HelloWorld.html  index.html

  将 index.html 加入版本控制,并提交到版本库中。

[root@public my_branch]# svn status
?       index.html
[root@public my_branch]# svn add index.html
A         index.html
[root@public my_branch]# svn commit -m "add index.html"
正在增加       index.html
传输文件数据.
提交后的版本为 36。

  切换根下,这里是prod,执行 svn update,然后切换到trunk,然后将 my_branch 分支合并到 trunk 中。

[root@public my_branch]# cd ../../
#这里一定要切换到跟下svn update,然后切换到trunk下面合并,否则合并信息为空
[root@public prod]# svn update
正在升级 '.':
版本 36。
[root@public prod]# cd trunk/
[root@public trunk]# svn merge ../branches/my_branch/
--- 正在合并 r35,经由 r36,到 “.”:
A    index.html
--- 记录合并 r35,经由 r36,到“.”的信息:
 G   .

  此时查看目录,可以看到 trunk 中已经多了 my_branch 分支创建的 index.html 文件。

[root@public trunk]# ls
HelloWorld.html  index.html
[root@public trunk]# pwd
/tmp/svnurl/prod/trunk

  将合并好的 trunk 提交到版本库中。

[root@public trunk]# pwd
/tmp/svnurl/prod/trunk
[root@public trunk]# svn commit -m "add trunk index.htm"
正在发送       .
正在增加       index.html

提交后的版本为 37。
[root@public trunk]# svn status

 

9.SVN 标签(tag)

  版本管理系统支持 tag 选项,通过使用 tag 的概念,我们可以给某一个具体版本的代码一个更加有意义的名字。

  Tags 即标签主要用于项目开发中的里程碑,比如开发到一定阶段可以单独一个版本作为发布等,它往往代表一个可以固定的完整的版本,这跟 VSS 中的 Tag 大致相同。

  我们在本地工作副本创建一个 tag。

[root@public prod]# svn copy trunk/ tags/v1.0
A         tags/v1.0

  上面的代码成功完成,新的目录将会被创建在 tags 目录下。

[root@public prod]# ls tags/
v1.0
[root@public prod]# ls tags/v1.0/
HelloWorld.html  index.html

  查看状态。

[root@public prod]# svn status
A  +    tags/v1.0
A  +    tags/v1.0/HelloWorld.html

  提交tag内容。

[root@public prod]# svn commit -m "tags v1.0"
正在增加       tags/v1.0
正在增加       tags/v1.0/HelloWorld.html

提交后的版本为 38。
[root@public prod]# svn status

 

10.SVN 解决冲突

  版本冲突原因:

  假设 A、B 两个用户都在版本号为 100 的时候,更新了 kingtuns.txt 这个文件,A 用户在修改完成之后提交 kingtuns.txt 到服务器, 这个时候提交成功,这个时候 kingtuns.txt 文件的版本号已经变成 101 了。同时B用户在版本号为 100 的 kingtuns.txt 文件上作修改, 修改完成之后提交到服务器时,由于不是在当前最新的 101 版本上作的修改,所以导致提交失败。

  我们已在本地检出 prod库,下面我们将实现版本冲突的解决方法。

  我们发现 HelloWorld.html 文件存在错误,需要修改文件并提交到版本库中。

  我们将首先在第一个用户 HelloWorld.html 的内容修改为 "HelloWorld! https://www.lizexiong.com/"。此时用户版本提交后在41,这时候,第二个用户的版本在40,HelloWorld.html内容为Helloworld, 此时

#第一个用户
[root@public trunk]# cat HelloWorld.html 
Hello World! www.lizexiong.com

  用下面的命令查看更改:

#第一个用户
[root@public trunk]# svn diff
Index: HelloWorld.html
===================================================================
--- HelloWorld.html    (版本 36)
+++ HelloWorld.html    (工作副本)
@@ -1 +1 @@
-Hello World
+Hello World! www.lizexiong.com

  尝试使用下面的命令来提交他的更改:

#第一个用户
[root@public trunk]# svn commit -m "change HelloWorld.html first user"
正在发送       HelloWorld.html
传输文件数据.
提交后的版本为 41。

  现在第二个用户尝试修改HelloWorld.html,为Hello World! www.baidu.com,然后提交

#第二个用户,当前版本为40
[root@public trunk]# cat HelloWorld.html 
Hello World! www.baidu.com
[root@public trunk]# svn commit -m "change HelloWorld.html second user"
正在发送       HelloWorld.html
传输文件数据.svn: E155011: 提交失败(细节如下): 
svn: E155011: 文件 “/tmp/httpurl/prod/trunk/HelloWorld.html” 已经过时
svn: E170004: Item '/trunk/HelloWorld.html' is out of date

  这时我发现提交失败了。

  因为此时,HelloWorld.html 已经被 user01 修改并提交到了仓库。Subversion 不会允许 user02(本例使用的 svn 账号)提交更改,因为 user01 已经修改了仓库,所以我们的工作副本已经失效。

  为了避免两人的代码被互相覆盖,Subversion 不允许我们进行这样的操作。所以我们在提交更改之前必须先更新工作副本。所以使用 update 命令,如下:

[root@public trunk]# svn update
正在升级 '.':
在 “/tmp/httpurl/prod/trunk/HelloWorld.html” 中发现冲突。
选择: (p) 推迟,(df) 显示全部差异,(e) 编辑,
        (mc) 我的版本, (tc) 他人的版本,
        (s) 显示全部选项: mc
G    HelloWorld.html
更新到版本 41。

  这边输入"mc",以本地的文件为主。你也可以使用其选项对冲突的文件进行不同的操作。可以看到更新到41了

  默认是更新到最新的版本,我们也可以指定更新到哪个版本

svn update -r6

  此时工作副本是和仓库已经同步,可以安全地提交更改了

[root@public trunk]# cat HelloWorld.html 
Hello World! www.baidu.com
[root@public trunk]# svn commit -m "change HelloWorld.html second user"
正在发送       HelloWorld.html
传输文件数据.
提交后的版本为 42。

警告: post commit FS processing had error:
sqlite: attempt to write a readonly database

 

11.钩子的讲解

  1).钩子简介

  钩子脚本的具体写法就是操作系统中shell脚本程序的写法,请根据自己SVN所在的操作系统和shell程序进行相应的写作

  所谓钩子就是与一些版本库事件触发的程序,例如新修订版本的创建,或是未版本化属性的修改。每个钩子都会被告知足够多的信息,包括那是什么事件,所操作的对象,和触发事件的用户名。通过钩子的输出或返回状态,钩子程序能让工作继续、停止或是以某种方式挂起。

  其实简单来说,就是在我的版本更新前或者更新后触发某些事情,如:上传版本前,我限制这个文件大小,提交 备注信息的长度,上传版本后,同步svn的文件等

  默认情况下,钩子的子目录中包含各种版本库钩子模板。

$ ls repos/hooks/
post-commit.tmpl          pre-revprop-change.tmpl
post-revprop-change.tmpl start-commit.tmpl
pre-commit.tmpl  

  提示

  由于安全原因,Subversion版本库在一个空环境中执行钩子脚本—就是没有任何环境变量,甚至没有$PATH或%PATH%。由于这个原因,许多管理员会感到很困惑,它们的钩子脚本手工运行时正常,可在Subversion中却不能运行。要注意,必须在你的钩子中设置好环境变量或为你的程序指定好绝对路径。

 

  2.)钩子的默认模版

  目前Subversion有已实现了五种钩子:

  start-commit.bat

  它在提交事务产生前已运行,通常用来判定一个用户是否有权提交。版本库传给该程序两个参数:到版本库的路径,和要进行提交的用户名。如果程序返回一个非零值,会在事务产生前停止该提交操作。如果钩子程序要在stderr中写入数据,它将排队送至客户端。

  pre-commit.bat

  在事务完成提交之前运行,通常这个钩子是用来保护因为内容或位置(例如,你要求所有到一个特定分支的提交必须包括一个bug追踪的ticket号,或者是要求日志信息不为空)而不允许的提交。版本库传递两个参数到程序:版本库的路径和正在提交的事务名称,如果程序返回非零值,提交会失败,事务也会删除。如果钩子程序在stderr中写入了数据,也会传递到客户端。

  Subversion的分发版本包括了一些访问控制脚本(在Subversion源文件目录树的tools/hook-scripts目录),可以用来被pre-commit调用来实现精密的写访问控制。另一个选择是使用Apache的httpd模块mod_authz_svn,可以对单个目录进行读写访问控制(见“每目录访问控制”一节)。在未来的Subversion版本中,我们计划直接在文件系统中实现访问控制列表(ACL)。

  post-commit.bat

  它在事务完成后运行,创建一个新的修订版本。大多数人用这个钩子来发送关于提交的描述性电子邮件,或者作为版本库的备份。版本库传给程序两个参数:到版本库的路径和被创建的新的修订版本号。退出程序会被忽略。

  Subversion分发版本中包括mailer.py和commit-email.pl脚本(存于Subversion源代码树中的 tools/hook-scripts/目录中)可以用来发送描述给定提交的email(并且或只是追加到一个日志文件),这个mail包含变化的路径清单,提交的日志信息、日期和作者以及修改文件的GNU区别样式输出。

  Subversion提供的另一个有用的工具是hot-backup.py脚本(在Subversion源代码树中的tools/backup/目录中)。这个脚本可以为Subversion版本库进行热备份(Berkeley DB数据库后端支持的一种特性),可以制作版本库每次提交的快照作为归档和紧急情况的备份。

  pre-revprop-change.bat

  因为Subversion的修订版本属性不是版本化的,对这类属性的修改(例如提交日志属性 svn:log)将会永久覆盖以前的属性值。因为数据在此可能丢失,所以Subversion提供了这种钩子(及与之对应的post-revprop- change),因此版本库管理员可用一些外部方法记录变化。作为对丢失未版本化属性数据的防范,Subversion客户端不能远程修改修订版本属性,除非为你的版本库实现这个钩子。

  这个钩子在对版本库进行这种修改时才会运行,版本库给钩子传递四个参数:到版本库的路径,要修改属性的修订版本,经过认证的用户名和属性自身的名字。

 

  3.)钩子的基本使用简介

  1.把文件改名把后缀.tmpl去掉

  2.赋予钩子文件 755权限

  3.钩子执行的命令就是shell脚本,只要在文件尾部写入可执行的shell命令即可

 

12.实战:一个版本库(项目),多个代码库

  就拿上面的tw-hxh来说,假设tw-hxh下面有prod代码,test代码,cqc的代码,我们怎么控制权限和用户,总不能一个代码库一套用户和密码吧?虽然是可以,但是一般情况下,一个版本库里面都是一组相同的研发人员,每个代码库都使用相同的authz和passwd文件,那不是太繁琐了吗?

  假设我们的代码树目录是这样的。

[root@public test]# tree  tw-hxh/
tw-hxh/
├── cqc
├── prod
└── test

  碰到以上情况,使用svdadmin create cqc?prod?test?每个配置文件都独立吗?

  当然不用,完全可以在每个代码库的conf的svnserve.conf下指定公用的authz和passwd文件即可。

  当然,配置文件肯定有小小的改动。

 

  1.创建目录并配置

  建立对应的所有的版本库目录

mkdir -pv /data/svn/tw-hxh/prod
mkdir -pv /data/svn/tw-hxh/test
mkdir -pv /data/svn/tw-hxh/cqc

  配置

svnadmin create  /data/svn/tw-hxh/prod
svnadmin create  /data/svn/tw-hxh/test
svnadmin create  /data/svn/tw-hxh/cqc
#这里为什么有4级目录?这里就不做解释,查看第3节SVN安装即可

 

  2.配置用户密码

  这里的区别就体现出来了,因为之前的passwd文件是不是在/data/svn/tw-hxh/prod/conf/passwd下面?

  那么尽然/data/svn/tw-hxh/是项目版本库,prod,cqc,test都是他们的一套管理代码流程,那么passwd就能放在/data/svn/tw-hxh下面呀,其它的cqc和test也好调用。所以见如下:

[root@k8s-lizexiong tw-hxh]# ls
cqc  passwd  prod  svn.log  test
[root@k8s-lizexiong tw-hxh]# pwd
/data/svn/tw-hxh

  所以单个代码库的conf下面就不用passwd文件了。passwd放到项目的跟目录就行

  当然以下还是多添加2个用户来做等会的测试

[root@k8s-lizexiong tw-hxh]# cat /data/svn/tw-hxh/passwd 
[users]
lizexiong = huawei
wuxinzhe = huawei
liuwen = huawei

 

  3.权限配置

  尽然passwd可以这么做,那么authz当然可以一样。

[root@k8s-lizexiong tw-hxh]# cat /data/svn/tw-hxh/authz 

[aliases]
# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average

[groups]
# * = r

[/]
lizexiong = rw
[cqc:/]
wuxinzhe = rw
[test:/]
liuwen =r

 

  4.服务svnserve.conf配置

  重要的来了,passwd和authz都移动到了版本库的根目录下,怎么才知道代码库的权限和予许哪些用户访问呢?

  这里的svnserve.conf就必须独立了,都各自放到单独的代码库下面

[root@k8s-lizexiong conf]# cat /data/svn/tw-hxh/prod/conf/svnserve.conf 
[general]
# force-username-case = none
#匿名访问的权限,可以是read,write,none,默认为read
anon-access=none
##使授权用户有写权限 
auth-access=write
##密码数据库的路径 
password-db=/data/svn/tw-hxh/passwd
##访问控制文件 
authz-db=/data/svn/tw-hxh/authz
##认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字 
realm=/data/svn/tw-hxh/prod

[sasl]


[root@k8s-lizexiong conf]# cat /data/svn/tw-hxh/cqc/conf/svnserve.conf 
[general]
# force-username-case = none
#匿名访问的权限,可以是read,write,none,默认为read
anon-access=none
##使授权用户有写权限 
auth-access=write
##密码数据库的路径 
password-db=/data/svn/tw-hxh/passwd
##访问控制文件 
authz-db=/data/svn/tw-hxh/authz
##认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字 
realm=/data/svn/tw-hxh/cqc

[sasl]


[root@k8s-lizexiong conf]# cat /data/svn/tw-hxh/test/conf/svnserve.conf 
[general]
# force-username-case = none
#匿名访问的权限,可以是read,write,none,默认为read
anon-access=none
##使授权用户有写权限 
auth-access=write
##密码数据库的路径 
password-db=/data/svn/tw-hxh/passwd
##访问控制文件 
authz-db=/data/svn/tw-hxh/authz
##认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字 
realm=/data/svn/tw-hxh/test

[sasl]

  以上可以看出,除了realm配置不一样,基本都是相同的

 

  5.服务启动

  之前第三节svn安装里面非常明确的讲解过,到底哪一层为工作目录,这个非常重要,这次的案例就是以下:(一定记得要重启)

svnserve -d -r /data/svn/tw-hxh --listen-port=3690 --log-file /data/svn/tw-hxh/svn.log

 

  6.HTTP以及HTTPS

  对应的HTTP以及HTTPS这里就不用多说,和svn更改方式一样,所以这里就略过了

 

  7.测试

  首先验证wuxinzhe和liuwen对prod代码库没有访问权限

  

  wuxinzhe对test没有读写权限

  

  liuwen对cqc没有读写权限

  

  然后验证wuxinzhe对cqc代码有读写权限

  

  

  接下来liuwen对test只有读权限

  

  

  最后lizexiong对所有仓库拥有所有权限

  

 

13.实战:多个项目,多个版本库

  以下该章节就保留了,以下演示是个错误的,因为无法使用svnserve -r /data/svn直接控制深入的2级目录,如果想实现 一个项目,下面很多文件夹,然后根据项目/文件夹访问,那么只有windows上的版本可以实现,目前,windows版本已经收费了,所以linux上可以使用12小结通过不同的版本和名称来控制,但是不太规范,也可以实现。

  以下的方式是有问题的,因为这里做了,所以这里还是保留我的错误示范,如果需要多版本库管理和控制,参考12小结即可

 

  和上一小节来对比,这里说出了多个项目,多个项目什么意思?

  就拿上面的tw-hxh来说,假设tw-hxh下面有prod代码,test代码,cqc的代码,直接在/data/svn/tw-hxh下公共管理项目用户和权限就行了

  那如果有多个项目呢?比如tw-hxh,tw-yuu,那么怎么办?

  其实也很好解决,每个项目就像上一小节一样创建就行,并且权限代码也是相同管理,但是启动目录需要改成,还要向上一层,比如一个版本库,多个代码库,启动目录是/data/svn/tw-hxh,现在多个项目,那么就是/data/svn/了

  那么目录树就变成这个样子了

[root@k8s-lizexiong svn]# tree /data/svn/ -L 2
/data/svn/
├── svn.log
├── tw-hxh
│   ├── authz
│   ├── cqc
│   ├── passwd
│   ├── prod
│   ├── svn.log
│   └── test
└── tw-yuu
    ├── authz
    ├── cbt
    ├── passwd
    └── prod

  以上的tw-hxh的权限和任何都不需要改,直接新建tw-yuu的项目所需信息就行了。

  所以说,这是上一节的加强版本,2个章节需要组合来运用学习,所以关于tw-hxh的配置过程就不在展示了,只需要关注最后启动的时候即可。

 

  1.创建目录并配置

  建立对应的所有的版本库目录

mkdir -pv /data/svn/tw-yuu/prod
mkdir -pv /data/svn/tw-yuu/cbt

  配置

svnadmin create  /data/svn/tw-yuu/prod
svnadmin create  /data/svn/tw-yuu/cbt

 

  2.配置用户密码

  那么tw-yuu的帐号认证信息当然也是放在他自己的目录/data/svn/tw-yuu下了

[root@k8s-lizexiong tw-yuu]# ls
prod cbt
[root@k8s-lizexiong tw-yuu]# pwd
/data/svn/tw-yuu

  所以单个代码库的conf下面就不用passwd文件了。

  当然以下还是多添加2个用户来做等会的测试

[root@k8s-lizexiong tw-yuu]# cat /data/svn/tw-yuu/passwd 
[users]
zhuwenjing = huawei
qinhaiwei = huawei

 

  3.权限配置

  尽然passwd可以这么做,那么authz当然可以一样。

[root@k8s-lizexiong tw-yuu]# cat /data/svn/tw-yuu/authz 
[aliases]

[groups]

[/]
zhuwenjing = rw

[cbt:/]
qinhaiwei = rw

 

  4.服务svnserve.conf配置

  以下的代码不用多解释,按照一个版本库的案例配置即可,一摸一样即可

[root@k8s-lizexiong tw-yuu]# cat /data/svn/tw-yuu/
authz   cbt/    passwd  prod/   
[root@k8s-lizexiong tw-yuu]# cat /data/svn/tw-yuu/prod/conf/svnserve.conf 
[general]
# force-username-case = none
#匿名访问的权限,可以是read,write,none,默认为read
anon-access=none
##使授权用户有写权限 
auth-access=write
##密码数据库的路径 
password-db=/data/svn/tw-yuu/passwd
##访问控制文件 
authz-db=/data/svn/tw-yuu/authz
##认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字 
realm=/data/svn/tw-yuu/prod

[sasl]

[root@k8s-lizexiong tw-yuu]# cat /data/svn/tw-yuu/cbt/conf/svnserve.conf 
[general]
# force-username-case = none
#匿名访问的权限,可以是read,write,none,默认为read
anon-access=none
##使授权用户有写权限 
auth-access=write
##密码数据库的路径 
password-db=/data/svn/tw-yuu/passwd
##访问控制文件 
authz-db=/data/svn/tw-yuu/authz
##认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字 
realm=/data/svn/tw-yuu/cbt

[sasl]

 

  5.服务启动

  这里就是最重要的,启动工作目录一定要是/data/svn了,否则就是一个版本仓库了,所以基本多个项目就启动这里有这么点区别。(日志最好也可以改改,但是不改问题也不大)

svnserve -d -r /data/svn/ --listen-port=3690 --log-file /data/svn/svn.log

 

  6.HTTP以及HTTPS

  对应的HTTP以及HTTPS这里就不用多说,和svn更改方式一样,所以这里就略过了

   

  7.测试

  权限什么都不对,直接废弃,不做测试

 

14.TortoiseSVN 使用教程

  TortoiseSVN 是 Subversion 版本控制系统的一个免费开源客户端,可以超越时间的管理文件和目录。

 

14.1 TortoiseSVN 安装

  下载地址:https://tortoisesvn.net/downloads.html, 页面里有语言包补丁的下载链接。至于怎么去下载这里就不做演示了。

  最新下载1.14.3: https://osdn.net/projects/tortoisesvn/storage/1.14.3/

  

  运行下载的 TortoiseSVN 安装程序

  

  正确安装后,应该进行一次的重开机,以确保 TortoiseSVN 的正确无误。

  修改 TortoiseSVN 默认语言

  TortoiseSVN 安装完后默认的界面是英文的,我们可以通过设置修改成已安装语言

  

  

 

 

14.2 TortoiseSVN 的使用

14.2.1 建立一个 svntest的工作目录

  所谓的 svntest 目录其实就是您平常用来存放工作档案的地方。通常我们会等到自己的工作做的一个段落的时候再进行备份。所以我们平常都是在 svntest目录下面工作,等到适当时机在 commit 到 repository 中。举例来说,我们想在 D 盘下面建立一个名为 svntest的目录。首先先把这个目录建立出来。

  

  进入创建的目录在空白处按下右键后(您可以在 MyWork 目录的 icon 上按,也可进入 MyWork 目录后,在空白的地方按),选择 SVN checkout。

  

  接着您可以看到如下的画面:

  

  首先我们要填入的是 repository(版本库)的位置,对于 SVN 来说,repository 的位置都是 URL。版本库 URL 这里填入我们测试的版本仓库地址 svn://172.21.161.161/prod

  接着,稍微看一下 Checkout directory(检出至目录),这个字段应该要指向您的 svntest目录。

  

  确认后,按下 OK 按钮,然后输入用户名和密码。您应该可以看到如下的信息窗口。

  

  

  这样就表示动作完成。按下 OK 按钮后,再到您刚刚建立的目录下。您将会看到 MyWork 目录下面多了一个名为 .svn 的目录(这个目录是隐藏的,如果您的档案管理员没有设定可以看到隐藏目录,您将无法看到它) 。当然还有一些之前的测试文件以及目录。这些测试文件这里就先删除了。以便后面测试的时候看的清晰点。

  

  如果您要在一个已经存在的 SVN Server 上面 checkout 出上面的档案,您只需要给定正确的 SVN URL 以及要 checkout 目录的名称。就可以取得指定的档案及目录了。

 

14.2.2 新增档案及目录到 Repository 中 add commit

  创建目录 dir01, 在目录里新增文件

  

  将新增的文件加入到 SVN 版本控制中,TortoiseSVN 会把准备要加入的档案及目录,勾选需要加入的文件。(文件夹右键→TortoiseSVN→增加)

  

  按下 OK 后,您将会看到如下的讯息窗口:

  

  这个 Add(增加)的动作并未真正的将档案放到 Repository 中。仅仅是告知 SVN 准备要在 Repository 中放入这些档案。 此时的文件状态为:(文件夹右键→TortoiseSVN→检查修改)

  

  这些档案真正的放入到 Repository 中,空白处右键选择 SVN commit(提交) 紧接着,您将会看到如下的窗口出现:

  

  在这里可以清楚地了解到哪些档案要被 commit 到 repository(版本库)中。同样的,如果您有档案不想在这个时候 commit 到 Repository,您可以取消选取的档案,这样他们就不会被 commit 到 Repository 中。在"信息"文本框中可以写入对本次 commit 的说明。

  点击"确认"后完成 commit 动作,然后您可以到 svntest目录中,确定是否所有的档案 icon 都有如下的绿色勾勾在上面,这样代表您的档案都正确无误的到 repository 中。

  

 

14.2.3 更新档案及目录 update

  由于版本控制系统多半都是由许多人共同使用。所以,同样的档案可能还有人会去进行编辑。为了确保您工作目录中的档案与 Repository 中的档案是同步的。建议您在编辑前都先进行更新的动作。

  在想要更新的档案或目录 icon 上面按下鼠标右键。并且选择 SVN Update

  

  有时我们需要回溯至特定的日期或是版本,这时就可以利用 SVN 的 Update to revision 的功能。在想要更新的档案或目录 icon 上面按下鼠标右键。并且选择 TortoiseSVN->Update to revision(更新至版本)。

  

  

 

14.2.4 复制档案及目录 branch

  很多时候您会希望有另外一个复制的目录来进行新的编修。等到确定这个分支的修改已经完毕了,再合并到原来的主要开发版本上。举例来说,我们目前在svntest/trunk下面有如下的目录及档案:

  准备环境:以下trunk/file.txt已经提交到svn

  

  现在,我们要为 trunk 这个目录建立一个 branch。假设我们希望这个目录是在 D:\svntest\branch。首先我们可以在 trunk 目录下面的空白处,或是直接在 trunk 的 icon 下面按下鼠标右键选择 Branch/Tag…(分支/标记)这个选项,您将会看到如下的对话框出现。

  

 

  

  请先确认 From WC at URL(从工作副本/URL): 中的目录是您要复制的来源目录。接着,在 To URL(至路径)中输入您要复制过去的路径。通常我们会将所有的 branch 集中在一个目录下面。以上面的例子来说,branch 档案都会集中在 branch 的子目录下面。在 To URL 中您只需要输入您要的目录即可。目录不存在时,会由 SVN 帮您建立。特别需要注意的是 SVN 因为斜线作为目录分隔字符,而非反斜线。 接着在 Log message(日志信息)输入您此次 branch 的目的为何。按下 OK 就可以了。

  如果成功,将可以看到下面的画面:

  

  按下 OK 就可以关闭这个窗口了。如果您此时立刻去 svntest 目录的 branch 子目录下面,您将会失望的发现在该目录下面并没有刚刚指定的目录存在。这是因为您 svntest目录的部份还是旧的,您只需要在 branch 子目录下面进行 SVN update 就可以看到这个新增的目录了。新增的目录就与原来的目录无关了。您可以任意对他进行编辑,一直到您确认好所有在 branch 下面该做的工作都完成后,您可以选择将这个 branch merge 回原来的 trunk 目录,或者是保留它在 branch 中。

  (这里一定要svn update一波)

  

 

14.2.5 合并动作 merge

  假如我们在 branch 分支中对文件进行了修改或增加了文件,要 merge 回 trunk 目录中,方法很简单。以上面的例子来说,我们在 D:\svntest\trunk目录空白处,按下鼠标右键,选择 Merge(合并):

  

  

 

  以下画面主要分为三个部份,前面的 From: 与 To: 是要问您打算从 Branch 中的哪个版本到哪个版本,merge 回原来的 trunk 目录中。因此,From 跟 To 的 URL 字段应当都是指定原来 branch 的目录下。剩下的就是指定要 merge 的 revision 范围。以上面的例子而言,我们从 Branch 的 Revision 50 开始 merge 到 Branch 下面的最新版本。您可以透过,Dry run 按钮,试作一次 Merge。这个 merge 只会显示一些讯息,不会真正的更新到 trunk 的目录去。只有按下 Merge 按钮后,才会真正的将 branch 的档案与 trunk 的档案合并起来。

  

  

  

  

  查看trunk文件夹是否多出了branch的新增文件

  

  如果您确认这次的 merge 没有问题,您可以直接使用 commit 来将这两个被修改的档案 commit 回 SVN repository 上。如果有问题,您可以直接修改这两个档案,直到确认 ok 了,再行 commit。

 

14.2.6 制作 Tag 或是 Release

  所谓的 Tag 或是 Release 就是一个特别的版本,因为这个版本可能有特别的意义。例如:这个版本是特别的 Milestone 或是 release 给客户的版本。其实,Tag 与 Release 的作法与 Branch 完全相同。只是 Branch 可能会需要 merge 回原来的 trunk 中,而 tag 及 release 大部分都不需要 merge 回 trunk 中。

  举例来说,今天我们的 trunk 做了一版,这个版本被认定是软件的 1.0 版。 1.0版对于开发来说是一个非常重要的里程碑。所以我们要特别为他做一个标记,亦即 Tag。假设,这个 1.0 版是要正式 release 给客户或是相关 vendor,我们要可以为他做一个 Release 的标记。基本上,SVN 只有目录的概念,并没有什么 Tag 的用法。所以您会看到在 SVN 的选单上面,Branch 与 Tag 是同一个项目。以这个 1.0 的例子来说,我们在 svntest 目录下创建 tags 目录用于存放打 tag 的版本,并提交到版本库,然后在 Trunk 上面,按下鼠标右键,选择 Branch/Tag 的项目:

  

  

  成功的话,您就在对应的 Tag 目录下面建立了一个 v1.0 的目录。当然,如果您这时到 Tag 的目录下面去(如果这个tag目录是手动创建的),会看不到这个目录,您需要在 Tag 目录下面 update 一下,才能看到它。

 

 

posted @ 2022-09-21 10:00  小家电维修  阅读(346)  评论(0编辑  收藏  举报