SVN

作者: CoderHong | 来源:发表于2017-12-28 14:55 被阅读17次
Snip20170521_1.png

概述:

SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS、CVS,它采用了分支管理系统,它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS迁移到Subversion。说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的。

搭建svn服务

VisualSVN

这里我再windows使用VisualSVN,可以直接网上下载,一路安装就可以了,比较简单。

安装完成打开如下图:

这里有一个注意事项:
这里有一个注意事项:
这里有一个注意事项:
创建一个temp仓库,点击该仓库右键 Copy URL to ClipBoard。让入浏览器访问,第一次访问会让你输入账户密码完成访问。

image.png

那么坑就来了。有时候我们进入公司,你的领导给你的URL是在浏览器复制过来的,你放在浏览器是可以访问的。但是使用终端执行命令

svn checkout http://ip/!/#temp --username=账号 --password=密码

命令执行完毕显示:

-bash: !/#my/response: event not found

当我们使用终端checkout代码应该使用时真实的地址,而不是浏览器处理过的地址

浏览器地址跟真实地址对应:


image.png

环境准备好了 开始SVN版本控制的路途吧

SVN基础

这里说下原理:
svn本质是通过给被管理文件分配一个版本号。

image.png

首先客户端通过命令把svn服务器代码拉到本地

svn checkout 仓库地址 --username=用户名 --password=密码
Snip20171228_17.png

新建一个main.cpp

touch main.cpp

执行命令查看状态

svn status
status

?代表当前文件还未加入到svn工作空间。换句话说main.cpp还没有被SVN管理

执行命令add 将文件添加svn管理区

svn add main.cpp
add

将本地的仓库的文件提交到svn远程服务器

svn commit -m "描述"

commit

查看svn服务器:

image.png

当前的main.cpp的版本为r1。

修改main.cpp

image.png

查看状态

image.png

M 代表当前文件被修改还未提交

提交修改到svn服务器

image.png image.png

当前的main.cpp的版本为r2。依次类推,随着每一次提交main.cpp的本本就+1

注意:此时我新建一个文件main.h的提交那么它的版本号是多少呢?是1吗还是多少?

那么这里新建一个main.h 然后提交。

image.png

刷新svn服务端仓库:

image.png

这里会发现新建的main.h提交到服务后版本并不是从1开始。是在SVN当前最高的版本+1
本质如下:
1. 每一次提交svn服务器总的版本号+1
2. 每一次提交中包含的文件都会等于svn服务器总的版本号

常见的命令

接着上面的流程。在main.cpp输出一句输出,并提交。


image.png

由于又一次commit 这次只是修改了main.cpp。之前svn仓库总版本号为r3,那么此时main.cpp的版本+1为r4。main.h不变还是为r3。

image.png
svn log 查看提交记录
svn log 查看所有的文件提交历史记录
svn log 文件 查看该文件的历史记录

例如:执行 svn log main.cpp


也可以通过浏览器访问仓库,查看某个文件或这个仓库的提交历史

image.png
版本的回退

对于版本的回退有两种场景:

  • 当前的修改还未提交到svn服务器仓库

    • 执行命令 svn revert file/dir
  • 已经提交到svn服务器仓库

svn merge -r 4:2 main.cpp
image.png

vim mac.cpp内容,r4新增的输出消失了。这就回退完成了吗。NO!!!。刚刚说过回退版本可以理解为一次修改。
执行命令svn status

image.png

对于回退的版本我们还没有提交到服务器仓库。接下来提交。

image.png

又一次的提交 这次提价这包含了main.cpp 所以此时main.cpp版本+1为r5。svn服务器仓库总版本也+1此时为5。

svn diff

检查本地修改:
查看我们本地的修改还未提交到远程仓库内容。
原理:它将会比较你的工作文件与缓存在 .svn 的"原始"拷贝。

举例:
我现在在main.cpp创建一个Test类。

image.png

此时我的修改还未提价到远程仓库。通过命令svn diff查看本地修改了的内容:

svn diff main.cpp
image.png

SVN团队协作

真正公司中的开发是团队开发,各自负责自己的模块。这里就需要学会团队开发。并且能解决冲突。

对于刚才的学习一直是coder2在开发,现在我们新增了一个开发者coder1。此时想在coder1跟coder2公司开发一个项目。

首先coder1需要checkout最新的远程仓库代码到本地。
coder1在自己电脑执行命令:

svn checkout http://ip/svn/temp --username=账号 --password=密码
image.png

这里可以看出当前远程仓库的总版本为5。
在看下拉取本地的代码


image.png

到此coder1跟coder2两个电脑上的版本都是最新的。下面开始合作开发了。

当前coder1接到一个需求是:需要在main.cpp中的实现一个求和的函数。此时coder1开始编辑main.cpp。

image.png

coder1编写完后提交到远程仓库。

image.png

此时远程跟coder1本地的仓库版本都为6,coder2还是为5。coder2现在需要使用coder1中新增的求和函数。只需要执行命令

svn update

此时coder2本地就将远程仓库最新的代码同步下来,其中包含coder1刚刚提交的sum函数代码。

如果按着这种开发可能没有问题。但是事实并非如此。在多人开发中,如果没有按着规范来就会出现冲突。

冲突

冲突的原因:本地修改的文件版本比远程仓库的版本低。进行修改提交或者update

当前coder1、coder2本地、远程仓库的文件版本都是相同的。main.h版本为r3。main.cpp的版本为r6。

场景一
本地的修改的该文件版本比远程仓库的版本低。修改后提交冲突。

场景二
本地的修改的该文件版本比远程仓库的版本低。修改后update冲突。

两个场景问题的产生跟解决都是一样的。下面通过场景一来举例。

举例:
现在coder2在main.cpp文件调用了sum函数。然后提交修改。

此时coder1没有做update。coder2跟远程仓库的main.cpp文件的版本都为r7。而coder1本地main.cpp文件的版本为r6。换句话说就是coder1本地main.cpp文件的版本比远程仓库的版本低。

此时code1也对main.cpp文件做了修改。增加了一句输出。这个时候coder1将修改提交至远程仓库。

image.png

显示结果为:main.cpp is out of date。其实就是main.cpp本地版本比远程仓库main.cpp版本低做提交。对于这个错误我们只能执行命令
svn update。来更新本地版本。

让coder1选择解决冲突的方式。

p 手动解决 此时code1本地跟远程的代码相同相当于一次update。coder1跟coder2代码同时存在。自己手动修改,然后commit。

mc 使用我的覆盖别人的 此时code1本地跟远程的代码相同相当于一次update。但是coder1本地未提交的代码不会被覆盖。此时main.cpp状态为M。
执行commit。远程仓库的coder2的代码被coder1本地代码覆盖。

tc 使用别人的覆盖我的 此时code1本地跟远程的代码相同相当于一次update。自己未提交的代码被覆盖。

三种策略的共同特点都是先通过update将本地的版本远程仓库版本同步。p与mc后本地的状态是M还需commit,而tc直接将远程的代码覆盖本地没有commit步骤了

对于避免冲突的解决方案:

1. 在开始修改文本前一定执行一次update。确保当前本地文件的版本不比远程仓库的版本低。

2. 对于本地修改后要及时提交到远程仓库。

上面通过命令展示了svn一些原理,在实际的开发中我们通常使用图形化工具来提交效率。

图形化界面工具 Cornerstone

Cornerstone
整体的界面介绍

为了演示,我这里创建的了一个远程仓库下面是一些信息 :

http://10.211.55.3/svn/TestRepository/
经理的角色 manager
两个开发人员账户coder1、coder2 

第一步: 项目经理初始化项目
项目经理先在自己电脑的SVN工具上关联自己的账户。

关联仓库

提示:这里在添加之前直接复制仓库完成地址复制然后点击添加仓库关联,其中客户端会将粘贴板的内容,一些信息会帮我们自动填好

我们点击Import将我们创建好的初始化项目导入仓库中。也可以直接拖入

Import

提交

这里将来就可以用来查看远程仓库最新的内容。

此时我们也可以访问当前的远程仓库地址:

SVN Repository

如果项目经理相对刚刚的项目做一些项目架构调整。
首先添加本地关联。checkout out代码到本地

checkout out image.png

执行完之后,仓库的代码就被拉取到本地了。

image.png

这些步骤完成后,当前的图像界面展示的就如下图:

image.png

现在项目经理就可以在本地工程做调整了。调整完成后,查看工具。

image.png

执行提交

image.png

以上就是项目经理完成了项目的初始化工作。

第二步: 开发人员开发

这里示例coder1开发人员开始开发了,如上步骤相同,将自己账号添加到图形化工具服务端跟本地关联并拉取代码到本地。

image.png

下面开始演示利用Cornerstone演示svn的基础操作。

添加文件
添加文件

点击添加后,? 变成 A

image.png

提交到远程仓库。

删除文件
image.png

文件状态

image.png

提交。

回退

未提交回退的修改

image.png

选择丢弃修改

image.png

版本回退

我这里分为项目版本回退跟单个文件版本回退。操作一样只是选择不一样。

首先你得会查看当前项目或者要回退文件的版本。

image.png image.png

这里我展示的工程的版本信息,比如我现在想从r4 回退到 r1版本。

image.png image.png

冲突解决

现在有加入了coder2,此时code1当前的版本比远程仓库的版本低, 同时也做修改执行commit

发生冲突

这种错误在上面命令行里操作已经说过,这里点击OK。先执行update更新本地的版本。

这里解决冲突直接给的策略是手动解决。我们将冲突的文件手解决后,执行resolved

image.png

执行提交。

开发中遇到的问题及解决

调整项目的目录结构。
当前项目结构如图:

项目结构

此时我想讲一些除了.h跟.m的文件放到一个Resources文件夹里。这个是有我直接在项目中创建一个文件夹,将这些文件放进Resources文件夹。

调整后的目录结构

这个时候我们改变了文件的路径,此时报错文件丢失。

image.png

原因是这里我们项目创建的Resource是真实的文件夹。改变了原有文件的路径,如果在工程创建的是虚拟的文件夹不会出现这种问题。

解决

在项目中创建了真实的文件夹Resource

image.png

点击Add

image.png

Cornerstoner 选中文件拖移到Resources文件夹中。

image.png

可以看出,内部其实做的是现将原有的删除在移动到新的目录中。

点击提交。

图形化工具已经显示文件在 Resources目录下

image.png

此时我们看下xcode中的工程。

image.png

我们将红色的文件delete,然后到目录从新引用就可以了。
这样就是我们想要的目录结构了。

image.png

图形化界面工具 Xcode

Xcode

xcode9关联 SVN 仓库有有些变化;

image.png image.png

SVN目录规范

在我们新建一个仓库是可以选择一个默认带有trunk、 branches 、tags文件夹的仓库。

image.png

创建好的仓库

image.png

trunk为我们的开发主干,通常开发者拥有的权限都是这个。branches跟tags没有权限。

比如,现在给coder1、coder2开通trunk目录的权限。

image.png

当coder完成v1.0版本开发将代码commit以后。此时manager需要打一个tag。

image.png

填写tag信息

image.png

接着开始开发2.0版本的开发。在2.0版本的开发过程中,发现v1.0有一个严重的bug急需解决,但是又不能在当前的主干上去解决。

此时需要在tags中的v1.0开一个分支fixbugv1.0。专门用于bug的修复。

image.png

此时远程仓库有branches有一个fixbugv1.0的分支。

如果这个bug给coder2修复,manager需要将fixbugv1.0权限给coder2。

那么coder2拿到这个地址 checkout 代码,开始修复。
http://10.211.55.3/svn/ProjRepo/branches/fixbugv1.0

现在coder2完成了bug修复,执行commit。

manager需要将这次的修复分支branches/fixbugv1.0在tags打一个tag。

image.png

到这里还需要重要的一步,就是将/branches/fixbugv1.0分支合并到trunk上。

image.png

此时/branches/fixbugv1.0分支合并到manager本地的trunk上,然后执行commit提交到服务器,其它开发人员直接执行update,修复的代码同步到自己的本地。

接着就可以继续开发v2.0版本的开发了。

下面一张图是整个流程。其中SVN图形界面化每个步骤的本质就只执行下图的命令:

image.png

相关文章

网友评论

      本文标题:SVN

      本文链接:https://www.haomeiwen.com/subject/gbfvgxtx.html