<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Behind the Code &#187; svn</title>
	<atom:link href="http://yinwm.com/tag/svn/feed/" rel="self" type="application/rss+xml" />
	<link>http://yinwm.com</link>
	<description>Just Do It</description>
	<lastBuildDate>Wed, 04 Jan 2012 03:54:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>bzr快速入门（2）&#8212;- 采用本地分支的开发方式</title>
		<link>http://yinwm.com/2008/09/bzr%e5%bf%ab%e9%80%9f%e5%85%a5%e9%97%a8%ef%bc%882%ef%bc%89-%e9%87%87%e7%94%a8%e6%9c%ac%e5%9c%b0%e5%88%86%e6%94%af%e7%9a%84%e5%bc%80%e5%8f%91%e6%96%b9%e5%bc%8f/</link>
		<comments>http://yinwm.com/2008/09/bzr%e5%bf%ab%e9%80%9f%e5%85%a5%e9%97%a8%ef%bc%882%ef%bc%89-%e9%87%87%e7%94%a8%e6%9c%ac%e5%9c%b0%e5%88%86%e6%94%af%e7%9a%84%e5%bc%80%e5%8f%91%e6%96%b9%e5%bc%8f/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 08:58:25 +0000</pubDate>
		<dc:creator>yinwm</dc:creator>
				<category><![CDATA[bzr]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[快速入门]]></category>

		<guid isPermaLink="false">http://yinwm.cn/wordpress/?p=54</guid>
		<description><![CDATA[bzr 是一个分布式的版本控制工具，如果我们还那他当svn使用，那就有点暴敛天物了。 所以我们就得按照bzr的方式办事。 svn方式开发最大的问题就是当n个人开发不同的feature，又来回影响时候，基本上就只能使用branch了，否则就玩完了。这时候就得靠DVCS了。而对于所有的DVCS，都是天然的支持轻量级分支，或者天然的就应该按照分支进行开发。 我们可以按照如下的方法开发假设服务器是&#160; /server/repo我们在开发的时候不是想svn一样使用checkout来创建本地工作区，而是在本地做一个服务器代码库的分支，然后进行本地开发。以bzr为例子就是bzr branch /server/repo [local_proj_name]这时候这个local_proj_name是一个服务器工作区的分支，可以进行开发了，并且所有的提交都是本地的，不会影响到服务器的工作区。 如果你和别人一起共享一个服务器的代码库，随时获取最新的代码，在svn里面是使用update，在这里是使用pull，如果出现了和本地的冲突，哪么就需要使用merge来进行合并了。等你在本地工作区都开发好了，也本地提交好了，哪么使用push在传回服务器的代码库就可以了。 这里我想说一下pull和merge的区别。pull的意思是把代码同步成为服务器代码库的代码，并且版本号也发生变化。pull操作成功后，本地就是一个提交后的状态。merge的意思是把服务器代码库的代码，合并到本地，此时仅仅是内容的变化，版本是不会发生变化的。所以merge之后，本地是一个修改后的状态，还需要提交一次，本地才是一个提交后的状态。 比如服务器代码库只有一个文件，叫做readme.txt，在版本是9的时候，readme.txt的内容是No。版本号码是10的时候，内容是Yes。 如果我本地的工作区，是从版本号码为9做的本地分支。我现在pull下来，哪么我本地readme.txt的文件的内容是Yes，本地分支版本号码是10，处于以提交状态。如果是merge下来，哪么本地readme.txt的内容是Yes，本地分支版本号码是9，处于已修改状态，需要自己提交以下，是本地的版本号码达到10。]]></description>
			<content:encoded><![CDATA[<p>bzr 是一个分布式的版本控制工具，如果我们还那他当<a href="http://yinwm.cn/blog/2008/02/bzr-quick-start-1.html" target="_blank">svn使用</a>，那就有点暴敛天物了。 所以我们就得按照bzr的方式办事。</p>
<p>svn方式开发最大的问题就是当n个人开发不同的feature，又来回影响时候，基本上就只能使用branch了，否则就玩完了。这时候就得<a href="http://yinwm.cn/blog/2008/02/why-dvcs.html" target="_blank">靠DVCS</a>了。而对于所有的DVCS，都是天然的支持轻量级分支，或者天然的就应该按照分支进行开发。</p>
<p>我们可以按照如下的方法开发<br />假设服务器是&nbsp; /server/repo<br />我们在开发的时候不是想svn一样使用checkout来创建本地工作区，而是在本地做一个服务器代码库的分支，然后进行本地开发。以bzr为例子就是<br />bzr branch /server/repo [local_proj_name]<br />这时候这个local_proj_name是一个服务器工作区的分支，可以进行开发了，并且所有的提交都是本地的，不会影响到服务器的工作区。</p>
<p>如果你和别人一起共享一个服务器的代码库，随时获取最新的代码，在svn里面是使用update，在这里是使用pull，如果出现了和本地的冲突，哪么就需要使用merge来进行合并了。<br />等你在本地工作区都开发好了，也本地提交好了，哪么使用push在传回服务器的代码库就可以了。</p>
<p>这里我想说一下pull和merge的区别。<br />pull的意思是把代码同步成为服务器代码库的代码，并且版本号也发生变化。pull操作成功后，本地就是一个提交后的状态。<br />merge的意思是把服务器代码库的代码，合并到本地，此时仅仅是内容的变化，版本是不会发生变化的。所以merge之后，本地是一个修改后的状态，还需要提交一次，本地才是一个提交后的状态。</p>
<p>比如<br />服务器代码库只有一个文件，叫做readme.txt，<br />在版本是9的时候，readme.txt的内容是No。<br />版本号码是10的时候，内容是Yes。</p>
<p>如果我本地的工作区，是从版本号码为9做的本地分支。<br />我现在pull下来，哪么我本地readme.txt的文件的内容是Yes，本地分支版本号码是10，处于以提交状态。<br />如果是merge下来，哪么本地readme.txt的内容是Yes，本地分支版本号码是9，处于已修改状态，需要自己提交以下，是本地的版本号码达到10。</p>
]]></content:encoded>
			<wfw:commentRss>http://yinwm.com/2008/09/bzr%e5%bf%ab%e9%80%9f%e5%85%a5%e9%97%a8%ef%bc%882%ef%bc%89-%e9%87%87%e7%94%a8%e6%9c%ac%e5%9c%b0%e5%88%86%e6%94%af%e7%9a%84%e5%bc%80%e5%8f%91%e6%96%b9%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何使用svn进行merge</title>
		<link>http://yinwm.com/2008/04/%e5%a6%82%e4%bd%95%e4%bd%bf%e7%94%a8svn%e8%bf%9b%e8%a1%8cmerge/</link>
		<comments>http://yinwm.com/2008/04/%e5%a6%82%e4%bd%95%e4%bd%bf%e7%94%a8svn%e8%bf%9b%e8%a1%8cmerge/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 08:45:48 +0000</pubDate>
		<dc:creator>yinwm</dc:creator>
				<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://yinwm.cn/wordpress/?p=46</guid>
		<description><![CDATA[svn 的 merge其实很好用，当然前提是你明白了svn merge这个命令，还好，我用了大约一年明白了这个命令 -___-!! 跟大家说一下用法，比如我们要把分支merge到主干上 # svn merge &#8211;help merge: Apply the differences between two sources to a working copy path. usage: 1. merge sourceURL1[@N] sourceURL2[@M] [WCPATH] &#160;&#160;&#160;&#160;&#160;&#160; 2. merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH] &#160;&#160;&#160;&#160;&#160;&#160; 3. merge [-c M &#124; -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 [...]]]></description>
			<content:encoded><![CDATA[<p>svn 的<br />
merge其实很好用，当然前提是你明白了svn merge这个命令，还好，我用了大约一年明白了这个命令 -___-!!</p>
<p>跟大家说一下用法，比如我们要把分支merge到主干上</p>
<p># svn merge &#8211;help<br />
merge: Apply the differences between two sources to a working copy path.<br />
usage: 1. merge sourceURL1[@N] sourceURL2[@M] [WCPATH]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. merge [-c M | -r N:M] SOURCE[@REV] [WCPATH]</p>
<p>我们以第一个为例<br />
merge sourceURL1[@N] sourceURL2[@M] [WCPATH]<br />
这个help里面提示，merge需要三个参数<br />
sourceURL1，sourceURL2的含义并不是两个分支，或者一个分支一个主干，而是同一个分支的两个状态，或者说是两个版本。对这两个版本做一个diff，然后把diff的结果，应用到最后的参数WCPATH上，WCPATH代表是一个本地已经checkout的工作区</p>
<p>svn merge的思想是diff and apply</p>
<p>比如，我开发一个项目叫做proj<br />目录结构是<br />proj/trunk<br />proj/branches<br />proj/tags</p>
<p> (省略了http:// 之后的，只是相对路径，但是真正使用时候不能省略)</p>
<p>当版本达到100的时候，我决定做一个branch进行一些其他开发
<div id="1hpp" class="ArwC7c ckChnd">
&nbsp;[Reversion:100]<br />
&nbsp;$svn cp proj/trunk proj/branches/proj_branch_1<br />
&nbsp;OK Reversion:101</p>
<p>然后，trunk和proj_branch_1都在开发<wbr>，到了某一个版本，比如150，branch开发完成<wbr>，需要merge回到trunk<br />
此时的目录结构是<br />
[Reversion:150]<br />
proj/trunk<br />
proj/branches/proj_branch_1<br />
proj/tags</p>
<p>按照svn的实现，我需要知道proj_branch<wbr>_1所做的所有的变化，也就是当前的状态对刚刚生成时候状态的变<wbr>化。根据这个变化生成一个diff文件，在apply一个本地的工作<wbr>区上。（建议是一个干净的本地trunk工作区）</p>
<p>那么执行<br />
$cd proj/trunk<br />
$svn merge proj/branches/proj_branch_1<wbr>@101 proj/branches/proj_branch_1 .</p>
<p>其实，第一个URL（我们称之为左边），为起始状态，通过最后的<wbr>@101，表示取版本101，这个101就是cp成功之后的那个<wbr>版本。第二个URL（我们称之为右边），为最终状态，取最新的，<br />
&nbsp;左边和右边做了一个diff，应用到当前工作区目录<wbr>，也就是trunk。<br />
&nbsp;此时<br />
&nbsp;$svn st就可以看到变化了</p>
<p>这里的一个问题是如何获取这个cp之后的版本，也就是例子中的1<wbr>01<br />
可以使用svn log里面的&#8211;stop-on-copy命令<br />
$svn log &#8211;stop-on-copy proj/branches/proj_branch_1<br />
会到cp的时候停下来，那里边标注的版本就是需要的版本</p>
<p>&nbsp;比如，这是一个真正项目的一个例子，<br />
&nbsp;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<wbr>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<wbr>&#8212;&#8212;&#8212;&#8212;<br />
&nbsp;r995 | yinweiming | 2007-10-24 09:07:08 +0800 (三, 24 10月 2007) | 1 line</p>
<p>&nbsp;Create a branch for proj client using<br />
&nbsp;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<wbr>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<wbr>&#8212;&#8212;&#8212;&#8212;<br />
&nbsp;其中的r995，995就是我需要的版本<br />
&nbsp;（说明一下，commit时候写commet的好处<wbr>，比如这里我就很明确的肯定这是branch的起始点）</p>
<p>对于svn merge的另外的用法也是类似，只要是明白了<br />
他是根据左边，右边生成diff，然后应用到本地的一个工作区就<wbr>容易理解了。</p>
<p>还有可以使用svn merge &#8211;dry-run来模拟假装merge一下，看一下merge<wbr>会发生什么，而不是真正的做这个动作。</p>
<p>而对于merge的help里面的 3. merge [-c M | -r N:M] SOURCE[@REV] [WCPATH]<br />
这个也很容易理解，就是取 SOURCE 这个东西，版本N，M之间的区别，作用在WCPATH这个本地工作区上</p>
<p>注意！<br />做branch千万别根据本地修改过的工作区做，一定基于某一个URL的版本做
<div id="1hpp" class="ArwC7c ckChnd">
我就吃过这个亏<br />diff的时候，diff不出来，因为基于本地工作区的<wbr>，所以现在merge起来很是费劲</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://yinwm.com/2008/04/%e5%a6%82%e4%bd%95%e4%bd%bf%e7%94%a8svn%e8%bf%9b%e8%a1%8cmerge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>bzr快速入门（1）&#8212;-像svn一样战斗</title>
		<link>http://yinwm.com/2008/02/bzr%e5%bf%ab%e9%80%9f%e5%85%a5%e9%97%a8%ef%bc%881%ef%bc%89-%e5%83%8fsvn%e4%b8%80%e6%a0%b7%e6%88%98%e6%96%97/</link>
		<comments>http://yinwm.com/2008/02/bzr%e5%bf%ab%e9%80%9f%e5%85%a5%e9%97%a8%ef%bc%881%ef%bc%89-%e5%83%8fsvn%e4%b8%80%e6%a0%b7%e6%88%98%e6%96%97/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 19:24:31 +0000</pubDate>
		<dc:creator>yinwm</dc:creator>
				<category><![CDATA[bzr]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[快速入门]]></category>

		<guid isPermaLink="false">http://yinwm.cn/wordpress/?p=37</guid>
		<description><![CDATA[bzr有很多种使用方法，我们首先介绍集中式的使用方法，你可以假装他就是svn。 bzr的基本语法是 bzr 命令 [参数] 首先创建一个代码仓库#bzr init-repo &#8211;no-tree ftp://user@host/repo-name这里使用了ftp作为代码仓库的中心服务器，bzr支持的协议有很多ftp，sftp,http,bzr等等，我这里使用了ftp为了方便。 命令init-repo是创建代码仓库的命令，&#8211;no-tree是说明这个代码仓库本身的物理位置是不参与开发的。 然后创建项目，更精确的说是创建一个分支#bzr init ftp://user@host/repo-name/proj1-trunk 然后checkout代码#bzr checkout ftp://user@host/repo-name/proj1-trunk proj1然后就是熟悉的场景了，可以随意的使用，折腾，捣乱，然后commit到中心代码库。其他的使用者也可以随时update获取最新的代码。怎么样，跟svn一样吧，甚至连基本的命令都一样，比如commit/ci，update/up，revert，info，state/st。 这里面要注意一个问题，就是使用init命令创建的是一个分支，一个branch。branch在bzr当中是非常重要的，如果你了解一些svn详细的东西，你会发现被管理的每一个目录都有一个叫做.svn的目录，也就是我们可以认为从任何的子目录开始都是一个完整的可以被单独checkout的小项目。而bzr则不然，他只是在每一个branch的目录下才有一个.bzr目录，也就是从这一点开始，才是branch的根，下层的任何目录都不能成为一个单独的独立结构。而这个branch是需要用init命令搞定的，不能想svn里面一样随随便便的就创建一个目录就完了。 所以从这里我们看出，bzr是完全可以按照svn的思想来使用bzr。不过，这不就没意义了，我为什么不直接用svn呢，所以我们在使用bzr的时候，还是有一些区别的，下篇再说。]]></description>
			<content:encoded><![CDATA[<p>bzr有很多种使用方法，我们首先介绍集中式的使用方法，你可以假装他就是svn。</p>
<p>bzr的基本语法是 <br />bzr 命令 [参数]</p>
<p>首先创建一个代码仓库<br />#bzr init-repo &#8211;no-tree ftp://user@host/repo-name<br />这里使用了ftp作为代码仓库的中心服务器，bzr支持的协议有很多ftp，sftp,http,bzr等等，我这里使用了ftp为了方便。 <br />命令init-repo是创建代码仓库的命令，&#8211;no-tree是说明这个代码仓库本身的物理位置是不参与开发的。</p>
<p>然后创建项目，更精确的说是创建一个分支<br />#bzr init ftp://user@host/repo-name/proj1-trunk</p>
<p>然后checkout代码<br />#bzr checkout ftp://user@host/repo-name/proj1-trunk proj1<br />然后就是熟悉的场景了，可以随意的使用，折腾，捣乱，然后commit到中心代码库。其他的使用者也可以随时update获取最新的代码。<br />怎么样，跟svn一样吧，甚至连基本的命令都一样，比如commit/ci，update/up，revert，info，state/st。</p>
<p>这里面要注意一个问题，就是使用init命令创建的是一个分支，一个branch。<br />branch在bzr当中是非常重要的，如果你了解一些svn详细的东西，你会发现被管理的每一个目录都有一个叫做.svn的目录，也就是我们可以认为从任何的子目录开始都是一个完整的可以被单独checkout的小项目。而bzr则不然，他只是在每一个branch的目录下才有一个.bzr目录，也就是从这一点开始，才是branch的根，下层的任何目录都不能成为一个单独的独立结构。<br />而这个branch是需要用init命令搞定的，不能想svn里面一样随随便便的就创建一个目录就完了。</p>
<p>所以从这里我们看出，bzr是完全可以按照svn的思想来使用bzr。不过，这不就没意义了，我为什么不直接用svn呢，所以我们在使用bzr的时候，还是有一些区别的，下篇再说。</p>
]]></content:encoded>
			<wfw:commentRss>http://yinwm.com/2008/02/bzr%e5%bf%ab%e9%80%9f%e5%85%a5%e9%97%a8%ef%bc%881%ef%bc%89-%e5%83%8fsvn%e4%b8%80%e6%a0%b7%e6%88%98%e6%96%97/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>为什么使用DVCS</title>
		<link>http://yinwm.com/2008/02/%e4%b8%ba%e4%bb%80%e4%b9%88%e4%bd%bf%e7%94%a8dvcs/</link>
		<comments>http://yinwm.com/2008/02/%e4%b8%ba%e4%bb%80%e4%b9%88%e4%bd%bf%e7%94%a8dvcs/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 23:25:30 +0000</pubDate>
		<dc:creator>yinwm</dc:creator>
				<category><![CDATA[bzr]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://yinwm.cn/wordpress/?p=36</guid>
		<description><![CDATA[我们在开发过程中一般都使用VCS工具，最普遍的工具就是svn，但是在使用过程中还是会存在一些问题的。 假设一个场景一个项目要进行开发， A是底层核心功能开发人员，他要对底层进行开发，并且在第一时间所有的人都要获取他的代码 B是功能开发人员，进行一个feature1的开发 C，D是功能开发人员，进行另外一个feature2的开发 feature1和feature2要公用部分代码，比如同一个接口文件，并对他进行修改 假如我们用svn进行开发，这里面是有一个问题的，因为A的存在，feature1和feature2的开发并不能完全分开，而在开发阶段B，C，D三个人都不能随意的提交代码，否则feature1和feature2都会相互影响。如果他们真的都是分开的功能也没问题，但是因为C，D是一个feature的负责人，他们之间必须要进行代码交换，而因为svn是集中式开发，那么他们应该，必须，也只能通过svn进行代码交换。如果 C提交代码，要求D更新代码 A提交代码，要求所有人更新代码 D获取代码，A和C的，是正确的代码 B获取代码，死菜了，因为C的代码是他不需要的，会影响他的工作，甚至都无法编译通过 这个是一个很普遍的场景，尤其是对人数多一些的小组。那么我们应该如何避免这种情况的发生呢？答案是使用DVCS系统，也就是分布式代码管理系统，例如bzr，hg等。 DVCS的出现可以方便的解决这类问题。与svn等传统VCS系统不同，DVCS并不需要一个中心服务器，每个人的开发工作区都可以认为是中心服务器。DVCS的基础是分支，每需要一个开发工作区，都是基于已有的某个开发工作区创建一个分支，然后开发，然后进行分支的代码merge。因为这种特性，DVCS的分支操作代价非常小。当然对于管理，发布等等我们还是需要一个中心服务器的，那么我们只要一个放在中心服务器的分支就足够了，使用完全相同的技术和下面的各个开发工作区进行代码交换。从技术上，他们的地位是完全等同的。根据这些，我们再使用DVCS假设一下上述的开发场景 在中心服务器创建技术开发版本 A，B，C，D分别根据中心服务器创建自己的开发分支 A进行开发，每个阶段，B，C，D基于A提供的代码进行merge，比如A自己架设一个（临时的）ftp C进行开发，每一阶段，D基于C提供的代码进行merge，相对D的开发来说，情况一样。他们的开发完全不影响B的开发 最终都开发完成，一并merge回中心服务器 这就非常顺利的避免了上面遇到的问题。而且，DVCS因为是把自己的工作区认为是代码仓库（repository），所以可以随时的提交代码，随时记录自己的开发变更。而这个在svn当中有时就比较头疼，如果一个feature要开发时间比较长，那么中间的每一个小阶段的代码就很难记录了。 当然了，你可以说，我在svn当中采用给每个人开分支的方法解决这个问题。bingo，没错，但是，这已经就是DVCS的思想了，不是么？那么为什么不用一个现成的DVCS工具呢？]]></description>
			<content:encoded><![CDATA[<p>我们在开发过程中一般都使用VCS工具，最普遍的工具就是svn，但是在使用过程中还是会存在一些问题的。</p>
<p>假设一个场景<br />一个项目要进行开发，
<ul>
<li>A是底层核心功能开发人员，他要对底层进行开发，并且在第一时间所有的人都要获取他的代码</li>
<li>B是功能开发人员，进行一个feature1的开发</li>
<li>C，D是功能开发人员，进行另外一个feature2的开发</li>
<li>feature1和feature2要公用部分代码，比如同一个接口文件，并对他进行修改</li>
</ul>
<p>假如我们用svn进行开发，这里面是有一个问题的，因为A的存在，feature1和feature2的开发并不能完全分开，而在开发阶段B，C，D三个人都不能随意的提交代码，否则feature1和feature2都会相互影响。如果他们真的都是分开的功能也没问题，但是因为C，D是一个feature的负责人，他们之间必须要进行代码交换，而因为svn是集中式开发，那么他们应该，必须，也只能通过svn进行代码交换。<br />如果
<ol>
<li>C提交代码，要求D更新代码</li>
<li>A提交代码，要求所有人更新代码</li>
<li>D获取代码，A和C的，是正确的代码</li>
<li>B获取代码，死菜了，因为C的代码是他不需要的，会影响他的工作，甚至都无法编译通过</li>
</ol>
<p>这个是一个很普遍的场景，尤其是对人数多一些的小组。那么我们应该如何避免这种情况的发生呢？答案是使用DVCS系统，也就是分布式代码管理系统，例如bzr，hg等。</p>
<p>DVCS的出现可以方便的解决这类问题。与svn等传统VCS系统不同，DVCS并不需要一个中心服务器，每个人的开发工作区都可以认为是中心服务器。DVCS的基础是分支，每需要一个开发工作区，都是基于已有的某个开发工作区创建一个分支，然后开发，然后进行分支的代码merge。因为这种特性，DVCS的分支操作代价非常小。当然对于管理，发布等等我们还是需要一个中心服务器的，那么我们只要一个放在中心服务器的分支就足够了，使用完全相同的技术和下面的各个开发工作区进行代码交换。从技术上，他们的地位是完全等同的。<br />根据这些，我们再使用DVCS假设一下上述的开发场景
<ol>
<li>在中心服务器创建技术开发版本</li>
<li>A，B，C，D分别根据中心服务器创建自己的开发分支</li>
<li>A进行开发，每个阶段，B，C，D基于A提供的代码进行merge，比如A自己架设一个（临时的）ftp</li>
<li>C进行开发，每一阶段，D基于C提供的代码进行merge，相对D的开发来说，情况一样。他们的开发完全不影响B的开发</li>
<li>最终都开发完成，一并merge回中心服务器</li>
</ol>
<p>这就非常顺利的避免了上面遇到的问题。而且，DVCS因为是把自己的工作区认为是代码仓库（repository），所以可以随时的提交代码，随时记录自己的开发变更。而这个在svn当中有时就比较头疼，如果一个feature要开发时间比较长，那么中间的每一个小阶段的代码就很难记录了。</p>
<p>当然了，你可以说，我在svn当中采用给每个人开分支的方法解决这个问题。bingo，没错，但是，这已经就是DVCS的思想了，不是么？那么为什么不用一个现成的DVCS工具呢？</p>
]]></content:encoded>
			<wfw:commentRss>http://yinwm.com/2008/02/%e4%b8%ba%e4%bb%80%e4%b9%88%e4%bd%bf%e7%94%a8dvcs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>使用svn&#8212;-和IDE配合</title>
		<link>http://yinwm.com/2008/01/%e4%bd%bf%e7%94%a8svn-%e5%92%8cide%e9%85%8d%e5%90%88/</link>
		<comments>http://yinwm.com/2008/01/%e4%bd%bf%e7%94%a8svn-%e5%92%8cide%e9%85%8d%e5%90%88/#comments</comments>
		<pubDate>Sat, 19 Jan 2008 08:00:15 +0000</pubDate>
		<dc:creator>yinwm</dc:creator>
				<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://yinwm.cn/wordpress/?p=31</guid>
		<description><![CDATA[不知道你有没有过使用IDE来配合Subversion的经历，比如eclipse啊之流。这些IDE为了对自己的项目进行管理，都回生成一些放在项目下的配置文件，比如eclipse的`.classpath`文件。如果你使用svn，一个不小心就会把这些文件传回代码库，对你自己当然是无所谓了，但是别人就惨了。因为别人在checkout的时候，不得不使用你的配置，而如果别人也和你一样的使用eclipse这种和svn的配合方法，他就更惨了。因为up下来的配置文件和本地的冲突，然后最坏的情况就是你的项目死菜了。况且，这些文件并不是开发的项目的一部分，也不应该和代码放在一起。这是一个很普遍的问题，那么如何来解决呢？使用我们前面说的外部定义。svn标准的目录结构为svn://proj/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +trunk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +branches&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +tags在这里我们添加一个管理个人私有文件的目录，privates，当然了，这些IDE的配置文件也是私有文件咯。svn://proj/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +trunk&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +branches&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +tags&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +privates 这个privates目录如何使用呢？我们首先在下面建立自己的目录，比如/privates/yinwm，此时我的所有的私有文件都应该放在这里。然后再根据自己所要开发的目录结构（trunk还是分支）建立对应的目录，比如/privates/yinwm/trunk，/privates/yinwm/dev_1.0。使用IDE，checkout这个目录，此时这个目录下是任何文件都没有的，并且它只属于你自己。当成功的checkout之后，建立外部定义，让一个内部目录（我喜欢起名字叫proj）指向对应的开发目录（trunk或者某一个branch）。再update，你的代码就下来了。此时你再通过IDE上传东西，代码会放在对应的代码区域，而配置文件会放入你自己的私人文件夹。这样就不会相互影响了。 目录结构如下：svn://proj/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +trunk/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +branches/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +dev_1.0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +dev_2.0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +tags/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +privates/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +yinwm/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +trunk/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +.classpath等 （IDE文件）&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +proj （外部定义，指向trunk）&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +dev_1.0/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +.classpath等 （IDE文件）&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +proj （外部定义，指向branches/dev_1.0）&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +xxx 这样大家就可以方便的工作了。当然，如果你是console+editor达人（我是70%的这类达人，:D，hoho），你就可以直接checkout trunk或者branch开发，反正这里也没有什么私人配置文件的问题。]]></description>
			<content:encoded><![CDATA[<p><font style="FONT-SIZE: 1em">不知道你有没有过使用IDE来配合Subversion的经历，比如eclipse啊之流。这些IDE为了对自己的项目进行管理，都回生成一些放在项目下的配置文件，比如eclipse的</font>`.classpath`文件。如果你使用svn，一个不小心就会把这些文件传回代码库，对你自己当然是无所谓了，但是别人就惨了。因为别人在checkout的时候，不得不使用你的配置，而如果别人也和你一样的使用eclipse这种和svn的配合方法，他就更惨了。因为up下来的配置文件和本地的冲突，然后最坏的情况就是你的项目死菜了。况且，这些文件并不是开发的项目的一部分，也不应该和代码放在一起。<br />这是一个很普遍的问题，那么如何来解决呢？使用我们前面说的<a href="http://yinwm.cn/blog/2008/01/svn-externals.html" target="_blank">外部定义</a>。<br />svn标准的目录结构为<br />svn://proj/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags<br />在这里我们添加一个管理个人私有文件的目录，privates，当然了，这些IDE的配置文件也是私有文件咯。<br />svn://proj/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +privates</p>
<p>这个privates目录如何使用呢？我们首先在下面建立自己的目录，比如/privates/yinwm，此时我的所有的私有文件都应该放在这里。然后再根据自己所要开发的目录结构（trunk还是分支）建立对应的目录，比如/privates/yinwm/trunk，/privates/yinwm/dev_1.0。<br />使用IDE，checkout这个目录，此时这个目录下是任何文件都没有的，并且它只属于你自己。当成功的checkout之后，建立外部定义，让一个内部目录（我喜欢起名字叫proj）指向对应的开发目录（trunk或者某一个branch）。再update，你的代码就下来了。此时你再通过IDE上传东西，代码会放在对应的代码区域，而配置文件会放入你自己的私人文件夹。这样就不会相互影响了。</p>
<p>目录结构如下：<br />svn://proj/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_2.0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +privates/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +yinwm/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +.classpath等 （IDE文件）<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +proj （外部定义，指向trunk）<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +.classpath等 （IDE文件）<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +proj （外部定义，指向branches/dev_1.0）<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +xxx</p>
<p>这样大家就可以方便的工作了。当然，如果你是console+editor达人（我是70%的这类达人，:D，hoho），你就可以直接checkout trunk或者branch开发，反正这里也没有什么私人配置文件的问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://yinwm.com/2008/01/%e4%bd%bf%e7%94%a8svn-%e5%92%8cide%e9%85%8d%e5%90%88/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用svn——项目的目录布局</title>
		<link>http://yinwm.com/2008/01/%e4%bd%bf%e7%94%a8svn%e2%80%94%e2%80%94%e9%a1%b9%e7%9b%ae%e7%9a%84%e7%9b%ae%e5%bd%95%e5%b8%83%e5%b1%80/</link>
		<comments>http://yinwm.com/2008/01/%e4%bd%bf%e7%94%a8svn%e2%80%94%e2%80%94%e9%a1%b9%e7%9b%ae%e7%9a%84%e7%9b%ae%e5%bd%95%e5%b8%83%e5%b1%80/#comments</comments>
		<pubDate>Sat, 19 Jan 2008 06:34:40 +0000</pubDate>
		<dc:creator>yinwm</dc:creator>
				<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://yinwm.cn/wordpress/?p=30</guid>
		<description><![CDATA[Subversion有一个很标准的目录结构，是这样的。比如项目是proj，svn地址为svn://proj/，那么标准的svn布局是 svn://proj/ &#124; +-trunk +-branches +-tags 这是一个标准的布局，trunk为主开发目录，branches为分支开发目录，tags为tag存档目录（不允许修改）。但是具体这几个目录应该如何使用，svn并没有明确的规范，更多的还是用户自己的习惯。 对于这几个开发目录，一般的使用方法有两种。我更多的是从软件产品的角度出发（比如freebsd），因为互联网的开发模式是完全不一样的。第一种方法，使用trunk作为主要的开发目录。一般的，我们的所有的开发都是基于trunk进行开发，当一个版本/release开发告一段落（开发、测试、文档、制作安装程序、打包等）结束后，代码处于冻结状态（人为规定，可以通过hook来进行管理）。此时应该基于当前冻结的代码库，打tag。当下一个版本/阶段的开发任务开始，继续在trunk进行开发。此时，如果发现了上一个已发行版本（Released Version）有一些bug，或者一些很急迫的功能要求，而正在开发的版本（Developing Version）无法满足时间要求，这时候就需要在上一个版本上进行修改了。应该基于发行版对应的tag，做相应的分支（branch）进行开发。例如，刚刚发布1.0，正在开发2.0，此时要在1.0的基础上进行bug修正。按照时间的顺序 1.0开发完毕，代码冻结 基于已经冻结的trunk，为release1.0打tag此时的目录结构为svn://proj/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +trunk/&#160; (freeze)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +branches/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +tags/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +tag_release_1.0　(copy from trunk) 2.0开始开发，trunk此时为2.0的开发版 发现1.0有bug，需要修改，基于1.0的tag做branch此时的目录结构为svn://proj/ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +trunk/&#160; ( dev 2.0 ) &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +branches/&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +dev_1.0_bugfix (copy from tag/release_1.0) &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +tags/ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +release_1.0　(copy from trunk) 在1.0 bugfix branch进行1.0 bugfix开发，在trunk进行2.0开发 在1.0 bugfix 完成之后，基于dev_1.0_bugfix的branch做release等 根据需要选择性的把dev_1.0_bugfix这个分支merge回trunk（什么时候进行这步操作，要根据具体情况） 这是一种很标准的开发模式，很多的公司都是采用这种模式进行开发的。trunk永远是开发的主要目录。 第二种方法，在每一个release的branch中进行各自的开发，trunk只做发布使用。这种开发模式当中，trunk是不承担具体开发任务的，一个版本/阶段的开发任务在开始的时候，根据已经release的版本做新的开发分支，并且基于这个分支进行开发。还是举上面的例子，这里面的时序关系是。 1.0开发，做dev1.0的branch此时的目录结构svn://proj/ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +trunk/&#160; (不担负开发任务 ) &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Subversion有一个很标准的目录结构，是这样的。<br />比如项目是proj，svn地址为svn://proj/，那么标准的svn布局是</p>
<pre>svn://proj/
|
+-trunk
+-branches
+-tags
</pre>
<p>这是一个标准的布局，trunk为主开发目录，branches为分支开发目录，tags为tag存档目录（不允许修改）。但是具体这几个目录应该如何使用，svn并没有明确的规范，更多的还是用户自己的习惯。</p>
<p>对于这几个开发目录，一般的使用方法有两种。我更多的是从软件产品的角度出发（比如freebsd），因为互联网的开发模式是完全不一样的。<br />第一种方法，使用trunk作为主要的开发目录。<br />一般的，我们的所有的开发都是基于trunk进行开发，当一个版本/release开发告一段落（开发、测试、文档、制作安装程序、打包等）结束后，代码处于冻结状态（人为规定，可以通过hook来进行管理）。此时应该基于当前冻结的代码库，打tag。当下一个版本/阶段的开发任务开始，继续在trunk进行开发。<br />此时，如果发现了上一个已发行版本（Released Version）有一些bug，或者一些很急迫的功能要求，而正在开发的版本（Developing Version）无法满足时间要求，这时候就需要在上一个版本上进行修改了。应该基于发行版对应的tag，做相应的分支（branch）进行开发。<br />例如，刚刚发布1.0，正在开发2.0，此时要在1.0的基础上进行bug修正。<br />按照时间的顺序
<ol>
<li>1.0开发完毕，代码冻结</li>
<li>基于已经冻结的trunk，为release1.0打tag<br />此时的目录结构为<br />svn://proj/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/&nbsp; (freeze)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tag_release_1.0　(copy from trunk)</li>
<li>2.0开始开发，trunk此时为2.0的开发版</li>
<li>发现1.0有bug，需要修改，基于1.0的tag做branch<br />此时的目录结构为<br />svn://proj/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/&nbsp; ( dev 2.0 )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0_bugfix (copy from tag/release_1.0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +release_1.0　(copy from trunk)</li>
<li>在1.0 bugfix branch进行1.0 bugfix开发，在trunk进行2.0开发</li>
<li>在1.0 bugfix 完成之后，基于dev_1.0_bugfix的branch做release等</li>
<li>根据需要选择性的把dev_1.0_bugfix这个分支merge回trunk（什么时候进行这步操作，要根据具体情况）</li>
</ol>
<p>这是一种很标准的开发模式，很多的公司都是采用这种模式进行开发的。trunk永远是开发的主要目录。</p>
<p>第二种方法，在每一个release的branch中进行各自的开发，trunk只做发布使用。<br />这种开发模式当中，trunk是不承担具体开发任务的，一个版本/阶段的开发任务在开始的时候，根据已经release的版本做新的开发分支，并且基于这个分支进行开发。还是举上面的例子，这里面的时序关系是。
<ol>
<li>1.0开发，做dev1.0的branch<br />此时的目录结构<br />svn://proj/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/&nbsp; (不担负开发任务 )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0 (copy from trunk)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/</li>
<li>1.0开发完成，merge dev1.0到trunk<br />此时的目录结构<br />
svn://proj/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/&nbsp; (merge from branch dev_1.0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0 (开发任务结束，freeze)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/</li>
<li>根据trunk做1.0的tag<br />此时的目录结构<br />
svn://proj/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/&nbsp; (merge from branch dev_1.0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0 (开发任务结束，freeze)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tag_release_1.0 (copy from trunk)</li>
<li>1.0开发，做dev2.0分支<br />此时的目录结构<br />
svn://proj/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0 (开发任务结束，freeze)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_2.0 （进行2.0开发）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tag_release_1.0 (copy from trunk)</li>
<li>1.0有bug，直接在dev1.0的分支上修复<br />此时的目录结构<br />
svn://proj/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +trunk/&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +branches/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_1.0 (1.0bugfix)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +dev_2.0 （进行2.0开发）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tags/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +tag_release_1.0 (copy from trunk)</li>
<li>选择性的进行代码merge</li>
</ol>
<p>这其实是一种分散式的开发，当各个部分相对独立一些（功能性的），可以开多个dev的分支进行开发，这样各人/组都不会相互影响。比如dev_2.0_search和dev_2.0_cache等。但是这样merge起来就是一个很痛苦的事情。</p>
<p>这里要注意一下的，第六步进行选择性的merge，是可以当2.0开发结束后一起把dev_1.0（bugfix用）和dev_2.0（新版本开发用）merge回trunk。或者先把dev_1.0 merge到dev_2.0，进行测试等之后再merge回trunk。<br />这两种方法各有利弊，第一种方法是可以得到一个比较纯的dev_2.0的开发分支，而第二种方法则更加的保险，因为要测试嘛。</p>
<p>以上呢，就是我说的两种开发模式了，具体哪种好，并没有定论。这里大致的说一下各自的优缺点<br />第一种开发模式（trunk进行主要开发，集中式）：<br />优点：管理简单<br />缺点：当开发的模块比较多，开发人数/小团队比较多的时候，很容易产生冲突而影响对方的开发。因为所有的改动都有可能触碰对方的改动<br />第二重开发模式（分支进行主要开发，分散式）：<br />优点：各自开发独立，不容易相互影响。<br />缺点：管理复杂，merge的时候很麻烦，容易死人。</p>
<p>其实，这里并没有一定之规，更多的时候是两种模式结合使用。我个人来说是采用第一种方式为主，在某些情况下使用第二种方法。<br />如果你还有其他的好的方法，那么请赐教。:)</p>
]]></content:encoded>
			<wfw:commentRss>http://yinwm.com/2008/01/%e4%bd%bf%e7%94%a8svn%e2%80%94%e2%80%94%e9%a1%b9%e7%9b%ae%e7%9a%84%e7%9b%ae%e5%bd%95%e5%b8%83%e5%b1%80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

