总的原则:trunk保证相对稳定。分支合并到主干时将冲突降至最低。

(1)       trunk用于集成、测试、发布,可以提交fixbug代码,但不允许直接提交新特性。

(2)       特性在分支上开发,在编译、测试通过后才能合并到主干。

(3)       特性分支确定一个负责人,负责每天执行从trunk到分支的合并。合并回trunk前,先执行一次trunk到dev的合并,然后在trunk上使用复兴分支。

(4)       特性分支的存在时间不能太长,不超过一周为宜。合入主干后不能继续使用。

相册特性开发-采用特性分支

特性分支: 为了使新特性的开发不影响测试或发布,把新特性开发放在分支上进行管理,分支的生命周期取决于特性的开发周期,该策略的特点是:

1)  trunk用于集成、测试、发布

2)  新特性放在分支上开发

3)  分支负责人定期(如每天)把trunk的变更同步至分支

4)  分支合并回trunk前先执行trunk到分支的合并,然后使用复兴分支

5)  分支合并回trunk后,分支生命周期结束,清理分支。

第三方代码管理-采用供应商分支

这里的供应商分支通常是指对第三方源代码的管理,供应商分支的管理通常步骤如下:

1)  创建供应商分支目录,导入供应商代码,供应商代码的维护在此分支上进行

2)  将供应商分支拷贝(branch/tag方式)到trunk或开发分支的某个目录下

3)  trunk或开发分支不对供应商分支代码做修改

4)  trunk或开发分支确认使用供应商分支的新版本时,把供应商分支合并到trunk或开发分支

可能会有人存在疑问,为什么要对供应商内容做管理?

供应商代码和自己的产品代码可以看着是两个产品线,供应商的代码可能随时会发生变化,为了不让供应商代码的变更影响自己产品的正常研发,就有必要使用分支独立管理供应商代码。

供应商分支还可以被另外一种方案所替代,那就是:外部引用(svn:externals)

分支合并到主干策略

如果说到svn使用最痛苦的一点,那莫过于主干合分支,或者分支合主干时爆发的各种莫名其妙的冲突狂潮,如“树冲突”,“文件冲突”,“文件丢失”等等。解决起来费时费力,还容易出错,效率很低。有没有较好的解决方法,可以让日子好过一点呢?答案是有的,需要遵循下面的方法。

冲突产生的根源

svn版本管理原理

svn生成的每个版本只记录增量修改,每个文件都有一个根源版本。

根源版本

根源版本,即祖先版本,在合并的时候是比较重要的一个概念,类似于C++中基类和派生类的关系,这里所说的根源就是一个基础版本。

如上图所示,hello.h的v1版本是v2版本的根源,而v2则是v3、v4的根源。

当进行分支合并时,SVN会沿着分支和trunk追溯共同的根源版本,然后计算其差异,如果没有共同的根源,则会报树冲突,就只能使用忽略根源的方式进行合并了。

冲突1:丢失文件及可避免的树冲突(可以避免)

当多人协作开发时,如果分支间合并缺乏时序性,就有可能导致合并时丢失文件。

举个简单例子来说:

如上图所示:

A和B两人同时在2.0-dev分支上开发,A新增一个a.cpp,并提交到SVN版本库上,产生123版本;然后B基于A提交的a.cpp做修改,提交后生成一个新版本124;

如果B此时想把自己修改的版本124merge到trunk,那么问题就来了,因为124版本的根源版本是123,只合并124过来,实际上就相当于只合并124的变更内容,而此时trunk上还没有a.cpp,这时SVN就会认为trunk上的a.cpp被删除了(因为找不到),会提示用户一个树冲突;

【由于是从2.0-dev合并到trunk, trunk是主合并方,分支是从的关系(在SVN中,trunk的东西称着mine,而分支是theirs),所以处理树冲突的时候优先用mine来解决】

当124合并到trunk时,由于找不到a.cpp,SVN会报一个树冲突,用trunk解决冲突,实际上也就是不会把a.cpp合并过来,这就会导致合并时出现丢失文件的现象。

冲突2:文本冲突(无法避免)

当A、B两人同时修改一个文件的同一行时,工具不能判断到底是选择A的修改or选择B的修改,或者是A和B的修改都要,这个事情就会报一个冲突,这种冲突也就是文本冲突。

冲突3:树冲突 (无法避免)

当A、B同时改了一个文件,A删除了该文件,而B修改了该文件,这时由于二者的修改无法进行合并,所以只能让用户二选一,要么删除该文件、要么保留该文件,这种冲突是树冲突。

树冲突产生的场景比较多,以下A和B的任何一种操作组合都会导致树冲突。

 

推荐的合并实践

1)  创建分支时,在日志中写明主干当前版本号。

2)  创建分支后,每天同步一次主干到分支, 并在日志中写明合入的主干当前版本号,便于定位问题。合并命令的用法见小节《常用svn命令》

每天合并问题最容易定位与解决,这也应了敏捷开发中小步快跑的思想,以及持续集成的初衷都是一样的;如果这个频率不能保证,每周也至少2-3次,否则解决冲突与定位问题的代价就大了。

3)合并回主干前,先执行一次主干到分支的合并,然后在主干上使用复兴分支。复兴分支使用了合并跟踪技术(svn1.5以上),能够不指定合并版本范围就将分支中的改动自动合入主干。

4)特性分支的存在时间不能太长,不超过一周为宜。合入主干后不能继续使用,否则当下次从trunk合到此分支时,会引入大量的树冲突。

svn常见使用流程讲解

命令行下字符编码的问题:目前相册源程序文件使用的都是gbk编码,而svn提交时默认使用utf8编码。我们希望在终端使用GBK编码,包括编译调试,但是使用svn时切换到utf8编码。所以需要如下两个封装的命令

命令

在.bashrc中加入下列两行,并且执行source ~/.bashrc

alias svncoding="export LC_ALL=\"en_US.UTF-8\""

alias gcccoding="export LC_ALL=\"en_US.ISO-8859-1\""

作用

编码方式切换

示例

svncoding切换到svn需要的编码(utf-8)

gcccoding切换到开发、编译需要的编码(ISO-8859-1编码无法表示编码,但是开发机对应的默认中文显示用gbk。原因何在?开发机/etc/sysconfig/language里写的是RC_LANG="en_US.UTF-8",secureCRT中使用默认设置(windows默认GBK),看来是以终端编码为准)

结果

命令

在.bashrc中加入下列两行,并且执行source ~/.bashrc

export PHOTO_REPO=

” https://tc-svn.tencent.com/isd/isd_qzoneplatformdev_rep/QzonePhoto_proj”

作用

代表相册代码svn库地址,便于快捷输入,减少输入量

示例

echo $PHOTO_REPO/trunk

结果

https://tc-svn.tencent.com/isd/isd_qzoneplatformdev_rep/QzonePhoto_pro/trunk

命令

svn info TRUNK_URL

作用

获取svn库的最新信息,如trunk的当前版本号

示例

svn info $PHOTO_REPO/trunk

结果

Path: trunk

URL: https://tc-svn.tencent.com/isd/isd_qzoneplatformdev_rep/QzonePhoto_proj/trunk

Repository Root: https://tc-svn.tencent.com/isd/isd_qzoneplatformdev_rep

Repository UUID: df2599cb-4e79-6a4a-84f3-a1dd8b66c2e7

Revision: 166688 <- 最新版本号

Node Kind: directory

Last Changed Author: reanshen

Last Changed Rev: 166688

Last Changed Date: 2013-04-12 19:07:17 +0800 (Fri, 12 Apr 2013)

命令

svn copy TRUNK_URL BRANCH_URL –m ”Create branch from trunk %REVISION%”

作用

创建分支

示例

svn copy $PHOTO_REPO/trunk $PHOTO_REPO/branches/photo_xxxx -m “Create branch from trunk 166688”

结果

Committed revision 166690.

命令

svn co SVN_URL[@REVISION]  [PATH]

作用

把svn库中的代码检出到本地,进行开发,编译

SVN_URL: 想要检出的代码URL路径

REVISION: 想要检出的版本号

PATH: 想要将检出代码存放在何处。不填,则将URL最后一段作为文件夹名

示例

svn co $PHOTO_REPO/branches/photo_xxxx

结果

检出代码到当前目录下的photo_xxxx下

命令

svn commit [PATH] –m “comments”

作用

提交开发的代码

示例

svn commit . –m “add test cases”

结果

提交了当前目录内的修改

命令

svn merge TRUNK_URL [–dry-run]

作用

将主干改动同步到分支。svn1.5引入“合并跟踪”技术,让我们不再需要每次自己查找哪些版本需要同步到分支。svnbook中称这种合并技术为sync-merge。对于之前需要手动跟踪版本合并范围,效率的提升不是一点点。

前置条件:本地代码库保证无任何未提交改动(用svn status查看);使用svn update更新到分支最新版本。

--dry-run选项:可以尝试合并,但不修改本地代码。可以借此先看看冲突多不多。

不加—dry-run选项: 进行真实的合并,修改本地代码,需要进行提交。

示例

svn merge  $PHOTO_REPO/trunk

结果

将主干上次合并后的改动自动同步到分支

命令

svn merge –reintegrate BRANCH_URL

作用

将分支代码合并进主干。

前置条件:主干中所有的更改都已合并入分支。主干的本地代码库无未提交的代码,并且使用svn update更新到最新版本。

示例

svn merge –reintegrate $PHOTO_REPO/branches/photo_xxxx

结果

分支中所有的改动均合入主干。

无冲突时,OK,顺利合并;

有冲突时,如果是文本冲突,有两种选择。

  1. 输入”l”启动配置的merge工具(详见”svn配置”一节)

会用vimdiff打开左中右三个垂直并列窗口

左:base版本(分支svn库中的版本)

中:mine版本(有本地修改的版本)

右:theirs版本(主干上的版本)

  1. 输入”p”推迟解决。之后用status可以看到哪些文件有冲突。

如果是树冲突,用svn status可以看出来。

$ svn status

	A  +  C code/bar.c
	      >   local edit, incoming delete upon update
	Summary of conflicts:
	  Tree conflicts: 1

如何解决树冲突,视乎具体情况而定。

例如:主干上该文件被删除,则在分支上先使用svn delete删掉文件,再用svn resolve –accept working 解决冲突。

命令

svn delete BRANCH_URL –m “remove branch, reintegrated with trunk in r%REVISION%”

作用

分支合入主干后就不能继续使用,否则再次从主干合入分支会造成大量树冲突。

清理掉svn数据库中的分支,让代码库更整洁一些,避免隐患。

示例

svn delete $PHOTO_REPO/branches/photo_xxxx  \

-m "remove branch, reintegrated with trunk in r16666"

结果

Committed revision 166702.

分支从版本库中删除

命令

svn copy BRANCH_URL@LAST_REVISION BRANCH_URL –m “resurrect branch photo_xxxx@%LAST_REVISION”

作用

这时候有人问了,“万一我需要看某个分支改了哪些东西,删掉分支后我怎么看呢”?

不用担心,分支一旦出现就永远不会消失,我们只是让它隐藏而已。真的需要时,可以轻易让它复活。如此命令所示,其中分支最后存在的版本号可以通过svn log branches父目录获得

示例

svn copy

$PHOTO_REPO/branches/photo_xxxx@166701 $PHOTO_REPO/branches/photo_xxxx -m "resurrect branch photo_xxxx@166701"

结果

复活分支

大体的svn工作流程如上所示,下面是其他一些通用操作。

命令

svn update

作用

将svn库中的代码更新到本地代码库

示例

svn up

结果

命令

svn resolve –accept [working | theirs-full | mine-full |base] filename

作用

冲突解决

--accept是个选择器

base: 选择上次最新checkout的版本(未作本地修改的)

mine-full: 选择仅包含自己本地修改的版本,忽略来自服务器的代码改动

theirs-full: 选择仅包含来自服务器的代码改动,忽略自己本地的改动

working: 选择手动merge完成后的版本

示例

结果

命令

svn status [-v]

作用

查看本地文件状态,可以看到当前目录下所有的改动

-v: 可以显示所有的文件信息,包括未修改的。

-u: 可以用”*”标识有更新的文件

示例

svn status

结果

?       scratch.c (不在版本控制中)

A       stuff/loot (新加文件,未提交)

A       stuff/loot/new.c

D       stuff/old.c (删除文件,未提交)

M       bar.c (修改文件,未提交)

C        cc.c (有冲突未解决的)

命令

svn log . –stop-on-copy –l N [-v]

作用

查看svn记录

--stop-on-copy: 在分支从主干分出时停止

-l N: 显示最多N个版本的Log

-v: 显示详细的改动(文件改动)

示例

svn log . –stop-on-copy –l 1 -v

结果

------------------------------------------------------------------------

r164717 | philchen| 2013-03-29 09:22:23 +0800 (Fri, 29 Mar 2013) | 2 lines

Changed paths:

M /QzonePhoto_proj/branches/photobuild_xxxx/application/qqphoto/comm/photo_log/include/monitor_id_define.h

命令

svn diff [filename]

作用

未指定filename: 查看当前目录的所有更改

指定filename: 查看指定文件的修改

示例

svn diff

结果

如果未配置diff-cmd, 默认使用svn自带的diff工具,输出格式如下

Index: bar.c

===================================================================

--- bar.c    (revision 3) [‘-‘标识前一版本的]

+++ bar.c (working copy) [‘+’标识当前本地文件的]

@@ -1,6 +1,7 @@[解释:’-‘标识前一版本,”1,6”指显示从第一行开始,共显示6行;’+’标识当前版本,”1,7”指显示从第一行开始,共显示7行]

#include<stdlib.h>   [前面无标注,为公共行]

+#include <stdio.h>   [前面为’+’,为当前本地文件的改动]

int main(void) {

-  printf("Sixty-four slices of American Cheese...\n"); [前面为’-‘, 为前一版本的改动]

+  printf("Sixty-five slices of American Cheese...\n");

return 0;

}

如果配置了diff-cmd, 就使用配置的。详见”svn配置”一节。

命令

svn add FOO

作用

把FOO(文件,目录,符号链接)加入到版本库。添加目录时目录下面的所有东西都被加进来,除非文件的后缀在svn::ignore里面。

示例

svn add newproj/

结果

命令

svn delete FOO

作用

把FOO(文件,目录,符号链接)从版本库中删除。文件或者符号链接会立即从文件系统中删除。

示例

svn del newproj/

结果

svn配置

配置diff工具(vimdiff)

作用:在命令行近似于ui方式较直观显示差异

打开~/.subversion/config, 编译diff-cmd选项。

diff-cmd = /usr/local/py/diffwrap.py

diffwrap.py内容如下

#!/usr/bin/env python

import sys

import os

DIFF = "/usr/local/bin/vimdiff"

# Subversion provides the paths we need as the last two parameters.

LEFT  = sys.argv[-2]

RIGHT = sys.argv[-1]

# Call the diff command (change the following line to make sense for

# your diff program).

cmd = [DIFF, LEFT, RIGHT]

os.execv(cmd[0], cmd)

当使用一个外部的diff命令时,Subversion会生成一个非常复杂的命令行。第一个参数就是具体的--diff-cmd,然后就是具体的 --extensions (尽管使用空白的 --符号时会忽略扩展),或者如果没有指定--extensions或者--extensions为空的话,就加上‘-u’参数。第三和第四个参 数,Subversion会传递一个“-L”还有第一个文件的标签(例如,“"project_issues.html (revision 11209)”)。第五个和第六个就是另一个“-L”和第二个文件的标签。第七和第八个参数分别是第一个和第二个文件的名称(例如,“.svn/text-base/project_issues.html.svn-base”和“.svn/tmp /project_issues.html.tmp”)。

配置merge工具(vimdiff)

作用:在命令行近似于ui方式较直观显示差异

左:base版本

中:merged编辑区

右:来自外部的版本

打开~/.subversion/config, 编译merge-tool-cmd选项。

merge-tool-cmd=”/usr/local/py/mymerge.py”

然后编辑mymerge.py

#!/usr/bin/env python

 

import sys

import shutil

import subprocess

 

try:

# Configure your favorite merge program here.

MERGE = “/usr/local/bin/vimdiff”

# Get the paths provided by Subversion.

BASE   = sys.argv[1]

THEIRS = sys.argv[2]

MINE   = sys.argv[3]

MERGED = sys.argv[4]

 

# Replace ‘merged’ file with a copy of ‘mine’

shutil.copy(MINE, MERGED)

cmd = [MERGE, BASE, MERGED, THEIRS]

subprocess.check_call(cmd)

except:

sys.exit(1)

vimdiff用法

窗口焦点切换,即切换当前窗口

CTRL-w h 跳转到左边的窗口

CTRL-w j 跳转到下面的窗口

CTRL-w k 跳转到上面的窗口

CTRL-w l 跳转到右边的窗口

CTRL-w t 跳转到最顶上的窗口

CTRL-w b 跳转到最底下的窗口

CTRL-w w 跳转到另一个窗口

CTRL-w CTRL-w 跳转到另一个窗口,同CTRL-w w

光标移动

移动光标,切分窗口会同步移动,使用:set noscrollbind命令可取消同步

]c 跳到下一个不同的地方

[c 跳到上一个不同的地方

上下文折叠

默认情况下,vimdiff会将文件中不同之处上下6行之外的相同文本折叠隐藏,可通过 :set diffopt=context:3 修改显示的上下文行数。

zo 打开折叠

zc 关闭折叠

文件合并

dp 将当前窗口光标位置处的内容复制到另一窗口

do 将另一窗口光标位置处的内容复制到当前窗口

diffupdate 重新比较两个文件,如果手动修改文件的话有时不会自动同步

文件操作

yy 复制当前行

nyy 复制当前行开始的n行

dd 删除当前行

ndd 删除当前行开始的n行

p 粘贴

u 撤销

CTRL-r 重复(即取消撤销)

wa 全部保存

wqa 全部保存后退出

qa 全部退出

qa! 全部强制退出,不保存文件修改

SVN并行开发管理策略的更多相关文章

  1. Git工程开发实践(四)——Git分支管理策略

    A successful Git branching model https://nvie.com/posts/a-successful-git-branching-model/ Git工程开发实践( ...

  2. [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下)

    [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下) 本篇导读: 接上篇继续介绍SVN的高级功能,即使用分支并行开发.随着需求的不断变更,新功能的增加.特别是 ...

  3. SVN分支管理策略个人见解

    本篇目录 前言 SVN分支管理策略 VisualSVN Server TortoiseSVN客户端 Repository的创建 Check out trunk创建新项目MyProject trunk更 ...

  4. SVN创建分支主干策略

    本篇目录 前言 SVN分支管理策略 VisualSVN Server TortoiseSVN客户端 Repository的创建 Check out trunk创建新项目MyProject trunk更 ...

  5. Git 分支管理策略汇总

    原文链接: Git 分支管理策略 最近,团队新入职了一些小伙伴,在开发过程中,他们问我 Git 分支是如何管理的,以及应该怎么提交代码? 我大概说了一些规则,但仔细想来,好像也并没有形成一个清晰规范的 ...

  6. Git 分支管理策略

    分支管理策略 下面我们来说一下一般企业中开发一个项目的分支策略: 主分支 master 开发分支 develop 功能分支 feature 预发布分支  release bug 分支 fixbug 其 ...

  7. .NET下的并行开发(案例代码)

    以下主要是通过一个报表处理程序来说明并行开发的方式.对于数据冲突和共享,可以通过对象数组解决.设计到并行的核心代码已用红色标出.在并行程序的处理上,需要把原来串行的子公司变成一个一个类的对象,让所有的 ...

  8. [svn] 分支开发

    参考博客: http://www.cnblogs.com/cxd4321/archive/2012/07/12/2588110.html (1)为什么要使用SVN分支开发和主干合并? 目的:在SVN下 ...

  9. 小团队开发管理工具:gitlab+redmine+testlink+jenkins

    由于工作需要,需要为团队搭建一个高效可用的开发管理平台.现在可用的开发管理工具很多开源的.商业的,网上也有很多博客和文章.经过2周的学习比较,再结合自己的项目特点,最后选定工具集:gitlab+red ...

随机推荐

  1. C++ struct 定义及初始化

    1 定义: struct Book{ unsigned int bookNo; string name; }; 2 初始化 struct的初始化分为三种:逐一赋值,顺序赋值,乱序赋值 //    逐一 ...

  2. Java-->实现群聊功能(C/S模式--TCP协议)

    --> Java 对TCP协议的支持: --> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端. -- ...

  3. hdu4632 Palindrome subsequence ——区间动态规划

    link:http://acm.hdu.edu.cn/showproblem.php?pid=4632 refer to: o(╯□╰)o……明明百度找的题解,然后后来就找不到我看的那份了,这位哥们对 ...

  4. POJ 3233 Matrix Power Series 矩阵快速幂

    设S[k] = A + A^2 +````+A^k. 设矩阵T = A[1] 0 E E 这里的E为n*n单位方阵,0为n*n方阵 令A[k] = A ^ k 矩阵B[k] = A[k+1] S[k] ...

  5. WindowsServer问题总结

    1.System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志.不可访问的日志: Security.在安装的“回滚”阶段发生异常.将忽略该异常并继续回 ...

  6. UVa 1225 Digit Counting --- 水题

    UVa 1225 题目大意:把前n(n<=10000)个整数顺次写在一起,12345678910111213...,数一数0-9各出现多少字 解题思路:用一个cnt数组记录0-9这10个数字出现 ...

  7. poj2367 拓扑序

    题意:有一些人他们关系非常复杂,一个人可能有很多后代,现在要制定一种顺序,按照前辈在后代前排列就行 拓扑序裸题,直接建边拓扑排序一下就行了. #include<stdio.h> #incl ...

  8. 越狱Season 1-Episode 15: By the Skin and the Teeth

    Season 1, Episode 15: By the Skin and the Teeth -Pope: doctor...you can leave. 医生你得离开 -Burrows: It's ...

  9. 【HAOI2009】【P1307】毛毛虫

    感觉相比其他树归题简单多了,不过有点绕(也许是我的思路很奇怪一.一)(这是省选题啊,就算作为T1这题也太水了,HA好弱……) 原题: 对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一 ...

  10. Performance Analysis Methodology

    http://www.brendangregg.com/methodology.html The USE Method: for finding resource bottlenecks The TS ...