SVN MERGE 和冲突

来源:互联网 发布:开淘宝店要多少钱押金 编辑:程序博客网 时间:2024/05/17 05:59

摘要:最佳做法是避免冲突。冲突时,不要把branch merge到trunk. 先由最新版本的trunk得到branch,然后再修改文件,直接merge过去就行。这样不会有冲突。先用svn merge --dry-run来模拟假装merge一下看是否有冲突


1 svn merge

# svn merge --help
merge: Apply the differences between two sources to a working copy path.
usage: 1. merge sourceURL1[@N] sourceURL2[@M] [WCPATH]
       2. merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]
       3. merge [-c M | -r N:M] SOURCE[@REV] [WCPATH]

我们以第一个为例
merge sourceURL1[@N] sourceURL2[@M] [WCPATH]
这个help里面提示,merge需要三个参数
sourceURL1,sourceURL2的含义并不是两个分支,或者一个分支一个主干,而是同一个分支的两个状态,或者说是两个版本。对这两个版本做一个diff,然后把diff的结果,应用到最后的参数WCPATH上,WCPATH代表是一个本地已经checkout的工作区

svn merge的思想是diff and apply

比如,我开发一个项目叫做proj
目录结构是
proj/trunk
proj/branches
proj/tags

(省略了http:// 之后的,只是相对路径,但是真正使用时候不能省略)

当版本达到100的时候,我决定做一个branch进行一些其他开发

 [Reversion:100]
 $svn cp proj/trunk proj/branches/proj_branch_1
 OK Reversion:101

然后,trunk和proj_branch_1都在开发,到了某一个版本,比如150,branch开发完成,需要merge回到trunk
此时的目录结构是
[Reversion:150]
proj/trunk
proj/branches/proj_branch_1
proj/tags

按照svn的实现,我需要知道proj_branch_1所做的所有的变化,也就是当前的状态对刚刚生成时候状态的变化。根据这个变化生成一个diff文件,在apply一个本地的工作区上。(建议是一个干净的本地trunk工作区)

那么执行
$cd proj/trunk
$svn merge proj/branches/proj_branch_1@101 proj/branches/proj_branch_1 .

其实,第一个URL(我们称之为左边),为起始状态,通过最后的@101,表示取版本101,这个101就是cp成功之后的那个版本。第二个URL(我们称之为右边),为最终状态,取最新的,
 左边和右边做了一个diff,应用到当前工作区目录,也就是trunk。
 此时
 $svn st就可以看到变化了

这里的一个问题是如何获取这个cp之后的版本,也就是例子中的101
可以使用svn log里面的--stop-on-copy命令
$svn log --stop-on-copy proj/branches/proj_branch_1
会到cp的时候停下来,那里边标注的版本就是需要的版本

 比如,这是一个真正项目的一个例子,
 ------------------------------------------------------------------------
 r995 | yinweiming | 2007-10-24 09:07:08 +0800 (三, 24 10月 2007) | 1 line

 Create a branch for proj client using
 ------------------------------------------------------------------------
 其中的r995,995就是我需要的版本
 (说明一下,commit时候写commet的好处,比如这里我就很明确的肯定这是branch的起始点)

对于svn merge的另外的用法也是类似,只要是明白了
他是根据左边,右边生成diff,然后应用到本地的一个工作区就容易理解了。

还有可以使用svn merge --dry-run来模拟假装merge一下,看一下merge会发生什么,而不是真正的做这个动作。


而对于merge的help里面的 3. merge [-c M | -r N:M] SOURCE[@REV] [WCPATH]
这个也很容易理解,就是取 SOURCE 这个东西,版本N,M之间的区别,作用在WCPATH这个本地工作区上

注意!
做branch千万别根据本地修改过的工作区做,一定基于某一个URL的版本做
我就吃过这个亏
diff的时候,diff不出来,因为基于本地工作区的,所以现在merge起来很是费劲


转自:http://www.blogjava.net/lingy/archive/2009/06/02/279544.html


2 svn resolve 解决冲突

svn resolve --accept  ARG  file 

 --accept ARG             : specify automatic conflict resolution source
                            ('base', 'working', 'mine-conflict',
                             'theirs-conflict', 'mine-full', 'theirs-full')


Resolve “conflicted” state on working copy files or directories. This routine does not semantically resolve conflict markers, however, it replaces PATH with the version specified by the --accept argument and then removes conflict-related artifact files. This allows PATH to be committed again—that is, it tells Subversion that the conflicts have been “resolved.”. You can pass the following arguments to the --accept command depending on your desired resolution:

base

Choose the file that was the BASE revision before you updated your working copy. That is, the file that you checked out before you made your latest edits.

working

Assuming that you've manually handled the conflict resolution, choose the version of the file as it currently stands in your working copy.

mine-full

Resolve all conflicted files with copies of the files as they stood immediately before you ran svn update.

theirs-full

Resolve all conflicted files with copies of the files that were fetched from the server when you ran svn update.



例子:

工程师A修改了a.txt的第一行,提交了。

工程师B也修改了a.txt的第一行,然后执行svn up,这时SVN提示了:(以下,你开始扮演工程师B的角色了)
$ svn up
在 “a.txt” 中发现冲突。
选择: (p) 推迟,(df) 显示全部差异,(e) 编辑,
(mc) 我的版本, (tc) 他人的版本,
(s) 显示全部选项:

我一般选择p(推迟),即引入冲突到本地,不过不会影响到SVN服务器端,可以放心。

OK,开始解决冲突了。

这时,会生成几个文件:

a.txt 

 a.txt.mine  a.txt.r6328  a.txt.r6336

其中a.txt中包含了工程师A、B的所有修改,以<<<<<<<、=======、>>>>>>>分隔。

a.txt.mine是工程师B的修改,也就是未update前的a.txt。

a.txt.r6328 是工程师A提交前的版本,即未导致冲突的版本。

a.txt.r6336是工程师A提交后的版本,即导致冲突的版本。

一般,查看a.txt就可以看到冲突的详情了:

[yicheng@chengyi svntest]$ cat a.txt

<<<<<<< .mine

i also modify ,agndagnagasdg;

=======

i modify this line;

>>>>>>> .r6336

以上,<<<<<<< .mine和=======之间是工程师B(当前的“你”)修改的内容,=======与>>>>>>> .r6336之间是工程师A修改的内容。这时,最好的办法是,叫上工程师A,你们一起确定这些修改是否都需要,是否相互兼容,然后留下需要的部分,删 除<<<<<<< .mine、=======和>>>>>>> .r6336。

然后,测试,测试!确定没问题之后,就可以告诉SVN,你解决冲突了:

svn resolve –accept working a.txt (该命令会删除a.txt.mine  a.txt.r6328  a.txt.r6336)

svn ci -m ’some comment’ a.txt
0 0
原创粉丝点击