<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>https://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>https://jackxiang.com/post//</link>
<title><![CDATA[笔记之SubVersion]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Wed, 20 Aug 2008 10:38:16 +0000</pubDate> 
<guid>https://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	笔记之SubVersion<br/>一、获取与安装<br/>SubVersion（以下简称SVN）是一款开源的版本控制系统，与著名的CVS类似，并大有取代之势，当前版本1.4.3，可以从http://subversion.tigris.org/project_packages.html下载。我下载的是Windows版，下载文件svn-1.4.3-setup.exe后，双击，按照提示进行安装。安装时，安装程序会自动将环境配置好。<br/>二、常用操作<br/>创建SVN版本库的命令：<br/>svnadmin create e:&#92;svn<br/>SVN会在e:&#92;svn文件夹下创建一个版本库，版本库用来保存提交到SVN中的文件，并记录相应版本信息。如果e:&#92;svn文件夹没有创建，SVN会自动创建。<br/><br/>导入与拆出文件。要将文件夹导入SVN版本库，可以执行命令：<br/>svn import F:&#92;project1 file:///e:/svn/project -m &quot;firstProject&quot;<br/>其中-m是import子命令的参数，用于记录操作日志，当前步骤的操作日志为“firstProject”，其它svn命令如无特殊说明，-m参数也是同样含义。此时SVN会将F:&#92;project1文件夹导入到刚刚创建的SVN版本库file:///e:/svn中的project目录下。下面执行命令：<br/>svn checkout file:///e:/svn/project F:&#92;project1<br/>此时SVN版本库就被关联到F:&#92;project1文件夹了。<br/>不过将svn checkout操作简单地说成关联是不正确的，这一步操作应当称为拆出文件，其作用是将保存在SVN版本库中的文件取出，存放到指定文件夹下以供编辑。例如建立一个文件夹F:&#92;project2，然后执行命令：<br/>svn checkout file:///e:/svn/project F:&#92;project2<br/>此时SVN版本库也会被取到F:&#92;project2中。下面将利用F:&#92;project1和F:&#92;project2文件夹来模拟两个用户的操作。<br/><br/>添加文件和文件夹。下面在F:&#92;project1文件夹下新建文件1.txt，这是一个文本文件，然后在命令行中定位到该文件夹下，执行命令：<br/>svn add 1.txt<br/>svn commit -m &quot;&quot;<br/>此时1.txt文件就会被添加到SVN版本库中了。这里注意，commit子命令是用来向SVN版本库提交修改内容的，以后每次文件有所变化都应用该命令向SVN执行提交。<br/>与CVS不同，在SVN中是不区分文本文件和二进制文件的，例如在F:&#92;project1文件夹下新建文件2.doc，然后执行命令：<br/>svn add 2.doc<br/>svn commit -m &quot;&quot;<br/>跟之前的命令一样，此时2.doc也被添加到SVN版本库中了。<br/>下面在F:&#92;project1文件夹下再新建一个文件夹dir，然后执行命令：<br/>svn add dir<br/>svn commit -m &quot;&quot;<br/>此时文件夹dir同样会被添加到SVN版本库中。<br/><br/>更新文件和文件夹。下面在命令行中定位到F:&#92;project2文件夹下，此时的F:&#92;project2是个空文件夹，没有任何内容。执行命令：<br/>svn update<br/>文件1.txt、2.doc和文件夹dir都被下载到F:&#92;project2中了。其实svn update的作用是更新本地文件，记得以后每次修改文件之前，都执行一次该命令。<br/><br/>提交与更新文件。下面打开F:&#92;project1中的1.txt文件，修改、保存并关闭，然后在命令中定位到该文件夹下，执行命令：<br/>svn commit -m &quot;edit 1.txt&quot;<br/>此时对1.txt所作的修改会被提交到SVN版本库中。如果想放弃修改，则可以在提交之前执行命令svn revert 1.txt，此时1.txt会被恢复成修改之前的内容。<br/>下面再打开F:&#92;project2中的1.txt文件，发现内容没有改变，关闭，在命令行中定位到该文件夹下，执行命令：<br/>svn update<br/>再次打开F:&#92;project2&#92;1.txt文件，会发现内容已经发生了变化，与F:&#92;project1&#92;1.txt文件一样。<br/><br/>处置修改冲突。下面分别修改F:&#92;project1&#92;1.txt和F:&#92;project2&#92;1.txt文件，注意保证两者内容的不一致，然后首先用svn commit -m &quot;&quot;提交F:&#92;project1&#92;1.txt，再提交F:&#92;project2&#92;1.txt，此时SVN会提示有冲突。这是因为我们对同一个文件作了不同的修改所致，这种情况在日常使用中会经常发生。要解决这个问题，请先在命令行中定位到F:&#92;project2下，执行命令svn update，此时SVN将更新1.txt文件，把有冲突的部分以格式：<br/>&lt;&lt;&lt;&lt;&lt;&lt;&lt; .mine<br/>F:&#92;project2&#92;1.txt文件冲突部分内容<br/>=======<br/>F:&#92;project1&#92;1.txt文件冲突部分内容<br/>&gt;&gt;&gt;&gt;&gt;&gt;&gt; .r4<br/>标记出来，并生成1.txt.mine、1.txt.r3和1.txt.r4文件，以分别记录更新之前的F:&#92;project2&#92;1.txt、修改之前的F:&#92;project2&#92;1.txt和新近修改的F:&#92;project1&#92;1.txt。与CVS不同，SVN提供了三种解决问题的办法：第一种办法需要重新修改F:&#92;project2&#92;1.txt，然后执行命令：<br/>svn resolved 1.txt<br/>svn commit -m &quot;&quot;<br/>其中resolved子命令用来告诉SVN指定文件的冲突已经解决。至此问题解决。关于1.txt.mine、1.txt.r3和1.txt.r4等文件，SVN会在执行svn resolved 1.txt命令时自动删除的。<br/>第二种办法是在SVN自动生成的1.txt.mine、1.txt.r3和1.txt.r4等文件中进行选择，用其中之一直接覆盖1.txt文件，然后执行命令：<br/>svn resolved 1.txt<br/>svn commit -m &quot;&quot;<br/>最后一种办法是放弃修改，或者称为恢复，即执行命令svn revert，此时F:&#92;project2&#92;1.txt变得与F:&#92;project1&#92;1.txt文件内容相同。注意，执行revert子命令时是不需要再执行commit子命令的。<br/><br/>文件和文件夹的查看与比较。先在命令行中定位到F:&#92;project1下，执行svn update命令，然后陆续执行以下命令并观察其效果：<br/>svn status -v 查看版本库中所有文件和文件夹的状态<br/>svn status -v 1.txt 查看1.txt文件的状态<br/>svn status -v dir 查看dir文件夹的状态<br/>svn log 查看版本库中所有文件和文件夹的日志<br/>svn log 1.txt 查看1.txt文件的日志<br/>svn log dir 查看dir文件夹的日志<br/>svn diff 1.txt 若保存在本地的1.txt文件被修改，则与保存在.svn文件夹中的原始拷贝比较差异<br/>svn diff -r4 1.txt 用保存在本地的1.txt文件与保存在SVN版本库中的1.txt文件的特定版本比较差异<br/>svn diff -r4:5 1.txt 比较SVN版本库中1.txt文件两个版本间的差异<br/>svn cat -r4 1.txt 查看1.txt特定版本的内容<br/>svn list[ file:///e:/svn] 查看仓库中的目录内容<br/><br/>文件和文件夹的删除。先在命令行中定位到F:&#92;project1下，然后执行命令：<br/>svn delete 2.doc<br/>svn commit -m &quot;&quot;<br/>此时F:&#92;project1&#92;2.doc文件就被从SVN版本库中删除了。如果想删除文件夹，以F:&#92;project1&#92;dir为例，可以执行命令：<br/>svn delete dir<br/>svn commit -m &quot;&quot;<br/>与删除文件的操作一样。<br/><br/>文件和文件夹的恢复。在SVN中，文件的恢复可以分为两种情况，一种是删除文件但未提交，以F:&#92;project1&#92;1.txt文件为例，先在命令行中定位到F:&#92;project1下，然后执行命令svn delete 1.txt，此时使用命令svn revert 1.txt，1.txt就被恢复了。其实revert子命令是用来放弃修改的，之前在“处置修改冲突”部分也曾提到过该命令。<br/>另一种是删除文件且已提交，以之前删除的F:&#92;project1&#92;2.doc文件为例，执行命令：<br/>svn copy -r 7 file:///e:/svn/project/2.doc 2.doc<br/>svn commit -m &quot;&quot;<br/>其中-r参数的值6是2.doc删除前的最后一个版本，此时F:&#92;project1文件夹下便多了个2.doc文件。不过在SVN中，恢复文件的办法不止一途，还可以使用命令：<br/>svn merge -r 10:7 file:///e:/svn/project<br/>svn commit -m &quot;&quot;<br/>此时dir文件夹也被恢复到F:&#92;project1下了。与copy子命令相比，merge子命令是对文件进行回滚，而copy子命令则是对文件进行复制。关于这两个命令，下边会有更详细的介绍。不过现在我们可以发现一件事，即在SVN中文件和文件夹的处理方式是一样的,或者说在SVN中文件夹也是一种文件。<br/><br/>文件与文件夹的重命名与移动。先在命令行中定位到F:&#92;project1下，执行命令：<br/>svn move 2.doc 3.doc<br/>svn commit -m &quot;&quot;<br/>此时2.doc就被改名为3.doc了。下面再执行命令：<br/>svn move 3.doc dir/3.doc<br/>svn commit -m &quot;&quot;<br/>此时3.doc又被移动到dir下了。由于在SVN中文件夹也被视为一种文件，处理方式与文件一样，因此这里就不再赘述了。<br/><br/>分支（branch）。假定软件K的发行版1.0已完成，而你正在继续开发下一版本，并计划在一段时间后发行版本1.1。可是不久你的客户就开始抱怨说K 1.0有问题，于是你检出了1.0的发行版，找到了这个错误。但是，当前代码的版本正处在一个不稳的状态，并且在一段时间之后才有希望稳定下来，这样就没法基于最新源代码去发行一个修复错误的版本了。这种情况下可以去为所有构成K 1.0发行版的文件创建版本树的一个分支。然后你可以修改这分支而不影响到主干。当修订完成时，你可以选定是否要把它同主干合并或继续保留在这个分支里。<br/><br/>创建分支。先在命令行中定位到F:&#92;project1下，执行命令：<br/>svn copy F:&#92;project1&#92;dir F:&#92;project1&#92;dir2<br/>svn commit -m &quot;&quot;<br/>此时SVN会在本地创建F:&#92;project1&#92;dir的副本F:&#92;project1&#92;dir2，两者内容一致，然后提交内容到SVN版本库中以为F:&#92;project1&#92;dir创建分支。这种作法与之前恢复已提交的删除文件时所使用的copy子命令类似，两者都是在本地创建指定文件或文件夹的副本，然后提交到版本库中，只是后者是为SVN版本库中的内容创建副本。其实SubVersion中所谓的分支，就是特定文件或文件夹的副本，与以往的版本管理工具相比，SubVersion中分支不是逻辑存在的，而是物理存在的。<br/>此外，SVN提供了更简便的方式来建立分支：<br/>svn copy file:///e:/svn/project file:///e:/svn/new_project -m &quot;&quot;<br/>或<br/>svn copy F:&#92;YPJCCK&#92;VersionControl&#92;svn&#92;project1&#92; file:///e:/svn/new_project -m &quot;&quot;<br/>两者都会在SVN版本库中创建分支并直接提交，其差异在于前者是以SVN版本库中的内容为基础，而后者是以本地内容为基础。<br/>此外，SubVersion中还有一个概念，标签（tag）。标签是一个文件在一段时间里的快照，在SubVersion中每次提交的修订版本都是一个快照。SubVersion中标签已与分支的概念相同。<br/><br/>获取分支。先在命令行中定位到F:&#92;project2下，执行命令：<br/>svn update dir2<br/>此时dir2会被下载到F:&#92;project2中。如果想下载之前的版本也可以利用该命令，例如：<br/>svn update -r 10<br/>此外，我们还可以转换工作拷贝对应的分支，在F:&#92;project2下执行命令：<br/>svn switch file:///e:/svn/new_project<br/>然后执行命令svn update，此时F:&#92;project2就被更新成new_project分支了。<br/><br/>在不同分支下修改文件。下面分别修改F:&#92;project1&#92;1.txt和F:&#92;project2&#92;1.txt文件，注意保证两者内容的不一致，然后使用svn commit -m &quot;&quot;进行提交。这两个文件均会被正确提交，而SVN也并未因为两者内容不一致提示版本冲突，只是提示新增了两个版本，这说明之前创建分支已经成功。<br/><br/>合并分支。在命令行中定位到F:&#92;project1下，执行命令：<br/>svn merge -r 17:Head file:///e:/svn/new_project<br/>咦，这条命令看起来似乎有点眼熟，没错，前边介绍文件恢复时曾介绍过，不过当时是从高版本回退到低版本，而现在则是将分支合并到主干。其实merge子命令的真正作用是比较两个指定版本的区别，然后将结果应用到当前工作目录。这里Head代表最新版本，17则是之前修改分支时产生的版本。由于之前分别修改了F:&#92;project1&#92;1.txt和F:&#92;project2&#92;1.txt，并且刻意保证了两者内容的不同，因此在将new_project分支合并到主分支时，SVN会提示冲突。关于冲突的处置，与之前介绍的处置修改冲突方法一样，这里不再赘述。修改过1.txt文件后，执行命令：<br/>svn resolved 1.txt<br/>svn commit -m &quot;&quot; <br/>合并完成。<br/>此外，merge子命令还有四种形式（按照帮助的说法应该是两种）：<br/>svn merge F:&#92;project1@16 F:&#92;project2@18（本地副本的比较）<br/>svn merge file:///e:/svn/project@16 file:///e:/svn/new_project@18（版本库内容的比较）<br/>svn merge F:&#92;project1@16 file:///e:/svn/new_project@18（本地副本与版本库内容的比较）<br/>svn merge file:///e:/svn/project@16 F:&#92;project2@18（版本库内容与本地副本的比较）<br/>其作用也是将指定版本比较后，把结果应用到当前工作目录。这里@之后的数值代表版本，其中版本库路径后是可以省略的，缺省为Head，本地副本则必须指定。<br/><br/>属性操作。属性用来存放特别信息，可以为文件保存更多信息，是对工作拷贝的有益补充。<br/>下面在命令行中定位到F:&#92;project1下，执行命令：<br/>svn propset test1 &#039;test&#039; 1.txt<br/>svn propset test2 -F 2.txt 1.txt<br/>前者为1.txt文件设置属性test1，属性值为test；后者为1.txt文件设置属性test2，并指定本地已存在文件2.txt的内容作为属性值。注意，通过-F参数，可以为属性指定任何文件作为值，包括二进制文件。<br/>下面执行命令：<br/>svn proplist 1.txt<br/>svn propget test1 1.txt<br/>前者用于查看1.txt文件有哪些属性；后者用于查看test1属性的值。<br/>执行命令：<br/>svn propedit test1 1.txt --editor-cmd notepad<br/>指定使用notepad（Windows中的记事本，别告诉我你不知道）编辑1.txt文件的test1属性。修改后，关闭记事本即可。<br/>现在我不想要test2属性了，执行命令：<br/>svn propdel test2 1.txt<br/>再次使用svn proplist 1.txt命令查看，test2属性已删除。<br/>注意，经过以上一系列操作，1.txt文件已经被修改，因此需要使用svn commit -m &quot;&quot;命令进行提交。<br/>此外，SVN自身也提供了一些属性，这些属性以svn开头，例如svn:executable、svn:mime-type等。关于这些属性，请参考其他文档，这里不介绍。<br/><br/>导出。在命令行中执行命令：<br/>svn export file:///E:/svn/project F:&#92;project<br/>或<br/>svn export F:&#92;project1 F:&#92;project<br/>此时版本库或工作副本中的内容都被导出到F:&#92;project文件夹中。注意，F:&#92;project会自动生成，并且该文件夹中的内容比较干净，不包含版本控制信息。<br/><br/>生成补丁。在命令行中定位到F:&#92;project1下，执行以下任意一条命令：<br/>svn diff -r10:19 1.txt &gt; test.diff（在1.txt的两个指定版本间比较）<br/>svn diff -r10 1.txt &gt; test.diff（在1.txt的当前版本与指定版本间比较）<br/>svn diff -r10 &gt; test.diff（在当前模块的当前版本与指定版本间比较）<br/>svn diff file:///e:/svn/project file:///e:/svn/new_project &gt; test.diff（在两个路径间比较）<br/>会生成输出信息到文件test.diff中。这些版本间的差异信息被称为补丁，而test.diff文件则称为补丁文件。注意，当不写“&gt; test.diff”时，例如svn diff -r10:19 1.txt，信息会直接输出到屏幕。<br/>三、子命令别名<br/>在SVN中，一些子命令是有别名的，通过别名可以简化操作，例如commit子命令的别名为ci，这样就可以将命令：<br/>svn commit -m &quot;&quot;<br/>简化为：<br/>svn ci -m &quot;&quot;<br/>下面列出了前面用到的一些子命令的别名：<br/>checkout：co<br/>commit：ci<br/>copy：cp<br/>delete：del，remove，rm<br/>diff：di<br/>help：?，h<br/>list：ls<br/>move：mv，rename，ren<br/>propdel：pdel，pd<br/>propedit：pedit，pe<br/>propget：pget，pg<br/>proplist：plist，pl<br/>propset：pset，ps<br/>status：stat，st<br/>switch：sw<br/>update：up<br/>四、update子命令的输出<br/>在执行update或commit子命令的过程中，会看到一些标志性的字母，那么这些字母表示些什么呢？<br/>A 在工作副本中添加文件并将这一操作更新到CVS仓库<br/>D 在工作副本中删除文件并将这一操作更新到CVS仓库<br/>U 更新工作副本中不存在或者没有修改过的文件<br/>C 有冲突<br/>G 合并成功<br/>注意，SVN的update子命令可能会有两列输出，两列输出时第一列表示的是文件本身，第二列表示的是文件属性。 <br/><br/><br/><br/><br/><br/>
]]>
</description>
</item><item>
<link>https://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] 笔记之SubVersion]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>https://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>