SVN并行开发管理策略

总的原则: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 [email protected]_REVISION BRANCH_URL –m “resurrect branch [email protected]%LAST_REVISION”


作用


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

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


示例


svn copy

$PHOTO_REPO/branches/[email protected] $PHOTO_REPO/branches/photo_xxxx -m "resurrect branch [email protected]"


结果


复活分支

大体的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! 全部强制退出,不保存文件修改

时间: 2024-12-28 02:31:03

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

SVN分支管理策略个人见解

本篇目录 前言 SVN分支管理策略 VisualSVN Server TortoiseSVN客户端 Repository的创建 Check out trunk创建新项目MyProject trunk更新提交更新,迭代版本创建Tag V1.0 基于Tag的Hotfix Branch Hotfix Branch改动Marge(合并)到trunk中同时创Tag_V1.1进行发布 定制化分支Customize branch 总结 前言 使用svn做为源码管理工具已有几年,但一直都只是使用到了trunk.

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

Git工程开发实践(四)--Git分支管理策略 一.Git版本管理的挑战 Git是非常优秀的版本管理工具,但面对版本管理依然有非常大得挑战.工程开发中,开发者彼此的代码协作必然带来很多问题和挑战:A.如何开始一个Feature开发,而不影响其它Feature?B.由于很容易创建新分支,分支多了如何管理,时间久了,如何知道每个分支是干什么的?C.哪些分支已经合并回了主干?D.如何进行Release的管理?开始一个Release的时候如何冻结Feature, 如何在Prepare Release的时

源代码管理工具 SVN在开发中的使用

1.公司常用命令:svn checkout 服务器地址 —username=账号 —password=密码svn update 更新到最新的版本svn commit -m “注释” 将本地的代码提交到服务器svn add 文件名 在添加静态库的时候需要使用,其他时候不经常使用:2.命令行中版本的回退3.图形化界面的使用使用Xcode进行文件添加和进行忽略操作:4.xcode使用SVN进行开发的注意点:(1)如果使用到静态库时候需要特别注意,必须使用命令行将静态库添加到svn的管理之下:(动态库只

GIt分支管理策略

大纲: 1.前言 2.创建分支 3.切换分支 4.合并分支(快速合并) 5.删除分支 6.分支合并冲突 7.合并分支(普通合并) 8.分支管理策略 9.团队多人开发协作 10.总结 注,测试机 CentOS 5.5 x86_64,Git 服务器版本:git version 1.8.2.1,客户端版本:git version 1.9.2.msysgit.0.所有软件请到这里下载:http://msysgit.github.io/. 1.前言 在上一篇博客中我们主要讲解了Git 远程仓库,相信大家对

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

以下主要是通过一个报表处理程序来说明并行开发的方式.对于数据冲突和共享,可以通过对象数组解决.设计到并行的核心代码已用红色标出.在并行程序的处理上,需要把原来串行的子公司变成一个一个类的对象,让所有的类对象一起并行运行就达到提高响应速率的目的了.并行设计中,主要的还是编程的思想,并行的语法,规则都是规划好的.好的工具就看你如何使用了. using System;using System.Data;using System.Configuration;using System.Collection

分支管理策略

通常,合并分支时,如果可能,Git会用“Fast forward”模式,但这种模式下,删除分支后,会丢掉分支信息. 如果要强制禁用“Fast forward”模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息. 下面我们实战一下--no-ff方式的merge: 首先,仍然创建并切换dev分支: $ git checkout -b dev Switched to a new branch 'dev' 修改readme.txt文件,并提交一个新的commit

【原创】基于禅道的敏捷开发管理实践

以下是我在一个长期项目研发过程中采用敏捷思想进行项目开发管理的成功实践,供大家参考 一.项目背景     1.这是一个长期维护,需要不断扩展功能的O2O平台,系统本身包含多达13个子系统,且还在不断增加中 2.系统采用了"组件化架构",各个组件之间实现了脱藕,可以各自单独扩展 3.开发资源严重匮乏,程序员严重不足,且其中能独立工作的程序员比例很低 二.敏捷开发实践 1.每一次版本迭代都包括:需求->设计->编码->测试->交付这四个阶段 2.用禅道对开发全过程进

VII (8) Python(并行开发)

VII8Python(并行开发) In [1]: import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better tha

[转]Git分支管理策略

如果你严肃对待编程,就必定会使用"版本管理系统"(Version Control System). 眼下最流行的"版本管理系统",非Git莫属. 相比同类软件,Git有很多优点.其中很显著的一点,就是版本的分支(branch)和合并(merge)十分方便.有些传统的版本管理软件,分支操作实际上会生成一份现有代码的物理拷贝,而Git只生成一个指向当前版本(又称"快照")的指针,因此非常快捷易用. 但是,太方便了也会产生副作用.如果你不加注意,很可能