<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-IT—SAm.Ye-文章分类-配置管理</title><link>http://www.cnitblog.com/tilan/category/4238.html</link><description>软件开发 软件配置 项目管理</description><language>zh-cn</language><lastBuildDate>Tue, 27 Mar 2007 06:34:25 GMT</lastBuildDate><pubDate>Tue, 27 Mar 2007 06:34:25 GMT</pubDate><ttl>60</ttl><item><title>基于Trac的项目管理系统构建(Windows篇)</title><link>http://www.cnitblog.com/tilan/articles/23747.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Thu, 08 Mar 2007 05:43:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/23747.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/23747.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/23747.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/23747.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/23747.html</trackback:ping><description><![CDATA[<p>这里我们要构建一个基于Trac的项目管理系统。代码管理使用subversion，项目管理使用Trac。所需要的软件包如下：</p>
		<ul class="list1" style="PADDING-LEFT: 16px; MARGIN-LEFT: 16px">
				<li>
						<a href="http://trac.edgewall.org/wiki/TracDownload" rel="nofollow">Trac 0.10</a>，Trac程序 
</li>
				<li>
						<a href="http://httpd.apache.org/download.cgi" rel="nofollow">Apache 2.0.59</a>，Web服务器 
</li>
				<li>
						<a href="http://subversion.tigris.org/project_packages.html" rel="nofollow">subversion 1.4.3</a>，代码版本管理工具 
</li>
				<li>
						<a href="http://www.python.org/" rel="nofollow">Python 2.4.4</a>，Python解释器 
</li>
				<li>
						<a href="http://httpd.apache.org/modules/python-download.cgi" rel="nofollow">mod_python</a>，Python的Apache模块 
</li>
				<li>
						<a href="http://www.clearsilver.net/downloads/" rel="nofollow">ClearSilver 0.9.4</a>，Python的模版工具 
</li>
				<li>
						<a href="http://www.egenix.com/files/python/mxDateTime.html" rel="nofollow">mxDateTime 2.0.3</a>，Python必须库文件 
</li>
				<li>
						<a href="http://www.postgresql.org/" rel="nofollow">PostgreSQL 8.2.3</a>，数据库服务器 
</li>
				<li>
						<a href="http://pypgsql.sourceforge.net/" rel="nofollow">pyPgSQL 2.5.1</a>，Python访问PostgreSQL数据库的模块 </li>
		</ul>
		<p>很遗憾subversion现在仍然不支持最新的Apache 2.2系列，因此我们只能使用Apache 2.0系列。而pyPgSQL 2.5.1版和ClearSilver 0.9.4不支持Python 2.5，因此只能用 Python 2.4。</p>
		<p>另外，虽然Trac支持SQLite，但SQLite支持的SQL语法有限，实际应用中会有诸多不便，因此我们选择了PostgreSQL作为后台数据库。</p>
		<!-- end Pukiwiki generated code-->
		<a id="more-351">
		</a>
		<!-- begin Pukiwiki generated code-->
		<h2 id="content_8_0">安装错误时怎么办？</h2>
		<p>如果你安装过程中发现某些地方不正常，记住按照下面的方法来纠正：</p>
		<ol class="list1" style="PADDING-LEFT: 16px; MARGIN-LEFT: 16px">
				<li>查看错误信息，看是否能找到提示 
</li>
				<li>检查有无忘了装的软件 
</li>
				<li>检查httpd.conf是否有误 
</li>
				<li>修改之后记得重新启动Apache </li>
		</ol>
		<h2 id="content_8_1">安装Apache和subversion</h2>
		<p>在<a href="http://httpd.apache.org/download.cgi" rel="nofollow">Apache官方网站</a>上下载2.0.59版的msi安装包，执行即可。为方便起见，建议将Apache安装到根目录下，例如 D:\Apache。安装时的一些细节可以参考<a href="http://tech.inspiremedia.org/archives/92.html" rel="nofollow">这篇文章</a>。安装完毕后用浏览器访问 <a href="http://localhost/" rel="nofollow">http://localhost/</a> ，如能看到Apache的起始页面即安装成功。</p>
		<p>从<a href="http://subversion.tigris.org/project_packages.html" rel="nofollow">subversion</a>上下载zip包解压缩即可，目前最新版本为svn-win32-1.4.3.zip。假设解压到 D:\svn下。</p>
		<p>然后将subversion与Apache集成在一起（也可参考<a href="http://tech.inspiremedia.org/archives/70.html" rel="nofollow">这篇文章</a>）。将 D:\svn\bin 下的以下文件复制到 D:\Apache\modules 目录下：</p>
		<ul class="list1" style="PADDING-LEFT: 16px; MARGIN-LEFT: 16px">
				<li>mod_authz_svn.so 
</li>
				<li>mod_dav_svn.so </li>
		</ul>
		<p>将 D:\svn\bin 下的以下文件复制到 D:\Apache\bin 目录下：</p>
		<ul class="list1" style="PADDING-LEFT: 16px; MARGIN-LEFT: 16px">
				<li>libdb44.dll 
</li>
				<li>intl3_svn.dll </li>
		</ul>
		<p>然后建立代码仓库目录 D:\repos。</p>
		<p>然后修改 D:\Apache\Apache2\conf\httpd.conf，查找下面这一行，去掉前面的 # 号。</p>
		<pre> LoadModule dav_module modules/mod_dav.so</pre>
		<p>然后在其附近添加以下这一行：</p>
		<pre> LoadModule dav_svn_module modules/mod_dav_svn.so</pre>
		<p>之后在 httpd.conf 的末尾添加以下内容：</p>
		<pre> &lt;Location /repos&gt;
     DAV svn
     SVNParentPath D:/repos
 &lt;/Location&gt;</pre>
		<p>然后重新启动Apache。之后试着访问一个不存在的页面，如 <a href="http://localhost/abc" rel="nofollow">http://localhost/abc</a>，你会看到<strong>Not Found</strong>页面下方的内容如下：</p>
		<pre> Apache/2.0.59 (Win32) SVN/1.4.3 DAV/2 Server at localhost Port 80</pre>
		<p>如果这里显示了 SVN/1.4.3 则说明安装成功。</p>
		<h2 id="content_8_2">安装Python、mod_python和SVN binding</h2>
		<p>从<a href="http://www.python.org/" rel="nofollow">Python官方网站</a>下载Python 2.5的msi安装包进行安装，假设安装到D:\Python25目录下。</p>
		<p>从<a href="http://httpd.apache.org/modules/python-download.cgi" rel="nofollow">mod_python的下载页面</a> 上下载mod_python 3.3.0b的Win32版(mod_python-3.3.0b.win32-py2.4-Apache2.0.exe)。安装时它会问你Apache的安装位置，输入 D:\Apache\Apache2 即可。</p>
		<p>最后打开 D:\Apache\Apache2\conf\httpd.conf，查找 LoadModule，加入下面这一行：</p>
		<pre> LoadModule python_module modules/mod_python.so</pre>
		<p>然后重新启动Apache。之后试着访问一个不存在的页面，如 <a href="http://localhost/abc" rel="nofollow">http://localhost/abc</a>，你会看到<strong>Not Found</strong>页面下方的内容如下：</p>
		<pre> Apache/2.0.59 (Win32) SVN/1.4.3 mod_python/3.3.0b Python/2.4.4 DAV/2 Server at localhost Port 80</pre>
		<p>如果这里显示了 mod_python/3.3.0b Python/2.4.4 则说明安装成功。</p>
		<p>最后要安装subversion binding使Python支持subversion。到<a href="http://subversion.tigris.org/project_packages.html" rel="nofollow">刚才下载subversion的地方</a> 下载 svn-win32-1.4.3_py2.4.exe 文件并安装。</p>
		<h2 id="content_8_3">安装PostgreSQL和pyPgSQL</h2>
		<p>到<a href="http://www.postgresql.org/" rel="nofollow">PostgreSQL官方主页</a>下载最新版8.2.3(postgresql-8.2.3-1.zip)并安装。</p>
		<p>为了让Python支持PostgreSQL，我们还需要安装pyPgSQL模块。到<a href="http://pypgsql.sourceforge.net/" rel="nofollow">pyPgSQL主页</a>下载2.5.1版并安装。</p>
		<p>安装结束之后，需要将 bin 目录下的以下文件复制到 D:\Python24\Lib\site-packages\pyPgSQL\libpq 下。</p>
		<ul class="list1" style="PADDING-LEFT: 16px; MARGIN-LEFT: 16px">
				<li>libpq.dll 
</li>
				<li>comerr32.dll 
</li>
				<li>libeay32.dll 
</li>
				<li>libintl-2.dll 
</li>
				<li>libiconv-2.dll 
</li>
				<li>krb5_32.dll 
</li>
				<li>ssleay32.dll </li>
		</ul>
		<h2 id="content_8_4">安装ClearSilver和mxDateTime</h2>
		<p>在<a href="http://www.clearsilver.net/downloads/" rel="nofollow">ClearSilver的下载页面</a>选择0.9.4的py2.4版下载 (win32/clearsilver-0.9.14.win32-py2.4.exe)并安装。</p>
		<p>
				<a href="http://trac.edgewall.org/wiki/TracInstall" rel="nofollow">Trac官方文档</a>中虽然没有说明mxDateTime，但是建立项目时Trac会报错，要求你安装mxDateTime库。从<a href="http://www.egenix.com/files/python/mxDateTime.html" rel="nofollow">mxDateTime主页</a>下载并安装。</p>
		<h2 id="content_8_5">安装Trac</h2>
		<p>最后终于轮到主角Trac出场了。在<a href="http://trac.edgewall.org/wiki/TracDownload" rel="nofollow">Trac下载页面</a>上下载 Trac安装程序(trac-0.10.3.win32.exe)并安装。</p>
		<p>然后建立项目目录 D:\projects。</p>
		<p>然后打开 D:\Apache\Apache2\conf\httpd.conf，在最末尾添加以下内容：</p>
		<pre> &lt;Location /projects&gt;
     SetHandler mod_python
     PythonHandler trac.web.modpython_frontend 
     PythonOption TracEnvParentDir D:/projects
     PythonOption TracUriRoot /projects
 &lt;/Location&gt;</pre>
		<p>然后重新启动Apache，访问 <a href="http://localhost/projects/" rel="nofollow">http://localhost/projects/</a>，你会看到<strong>Available Projects</strong>字样，则说明安装成功。至此安装全部完毕。</p>
		<h2 id="content_8_6">建立项目</h2>
		<p>下面我们要建立一个实际开发中使用的项目。我们为这个项目命名为 hello。</p>
		<p>首先要建立一个代码仓库。打开命令行，输入以下命令：</p>
		<pre> D:
 cd D:\repos
 md hello
 cd hello
 D:\svn\bin\svnadmin create .</pre>
		<p>然后打开浏览器，访问 <a href="http://localhost/repos/hello/" rel="nofollow">http://localhost/repos/hello/</a> 。如果你上面的设置都正确，你将会看到下面的内容：</p>
		<pre> Revision 0: /
 ----------------------------------------------
 Powered by Subversion version 1.4.3 (r23084).</pre>
		<p>即说明代码仓库建立成功，而 <a href="http://localhost/repos/hello/" rel="nofollow">http://localhost/repos/hello/</a> 就是代码仓库的 URL。</p>
		<p>然后建立数据库。从开始菜单中启动PostgreSQL的 pg Admin III工具，新建一个数据库 hello，注意将字符编码设置为UTF8。</p>
		<p>然后建立Trac项目。打开命令行，输入以下命令：</p>
		<pre> D:
 cd D:\projects
 D:\Python24\python.exe D:\Python24\Scripts\trac-admin hello initenv</pre>
		<p>trac-admin 为Trac的管理工具，hello为项目名，initenv命令指示Trac新建一个项目。然后按照下面的内容输入：</p>
		<pre> Project Name [My Project]&gt; Hello World
 Database connection string [sqlite:db/trac.db]&gt; postgres://&lt;username&gt;:&lt;password&gt;@localhost/hello
 Repository type [svn]&gt; svn
 Path to repository [/path/to/repos]&gt; D:/repos/hello
 Templates directory [D:\Python24\share\trac\templates]&gt;</pre>
		<p>数据库连接那一行，&lt;username&gt;和&lt;password&gt;分别为安装PostgreSQL时设置的用户名和密码。如果创建失败，则需要删除 D:\projects\hello 之后再重试。</p>
		<p>最后打开浏览器，访问 <a href="http://localhost/projects/hello" rel="nofollow">http://localhost/projects/hello</a> 即可看到Trac的界面了。</p>
		<h2 id="content_8_7">设置HTTP认证</h2>
		<p>在Trac界面右上方有个Login菜单，通过这个菜单登录之后，创建bug或者做其他修改时就不用每次都输入用户名。不过这个菜单需要单独配置才能正常工作。</p>
		<p>首先我们要生成密码文件。打开命令行，输入以下命令：</p>
		<pre> D:
 cd D:\projects
 D:\Apache\Apache2\bin -c .htpasswd admin
 Automatically using MD5 format.
 New password: *****
 Re-type new password: *****
 Adding password for user admin</pre>
		<p>即可生成密码文件 .htpasswd。以后向该密码文件里追加用户只需这样即可。</p>
		<pre> D:\Apache\Apache2\bin .htpasswd user</pre>
		<p>然后编辑 httpd.conf，在最末尾加入以下内容：</p>
		<pre> &lt;LocationMatch "/projects/[^/]+/login"&gt;
     AuthType Basic
     AuthName "Trac"
     AuthUserFile D:/projects/trac.htpasswd
     Require valid-user
 &lt;/LocationMatch&gt;</pre>
		<p>然后重新启动Apache</p>
		<script type="text/javascript">
				<!--
google_ad_client = "pub-3874079075380071";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-03-19: 3G-move, 三星, 摩托罗拉, 索爱, 诺基亚
google_ad_channel = "1730597762+1709572468+0778807001+6838187825+8377398382";
//-->
		</script>
		<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
		</script><img src ="http://www.cnitblog.com/tilan/aggbug/23747.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-03-08 13:43 <a href="http://www.cnitblog.com/tilan/articles/23747.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每日构建采用软件的评估报告</title><link>http://www.cnitblog.com/tilan/articles/21912.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Tue, 16 Jan 2007 03:21:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/21912.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/21912.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/21912.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/21912.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/21912.html</trackback:ping><description><![CDATA[<h1 align="left">
				<font size="5">一、目的：</font>
		</h1>
		<div>选择一个符合本公司软件开发实际需求的每日构建软件，并有一定前瞻性。</div>
		<h2>二、评估项目</h2>
		<div>             1、基本功能 ：</div>
		<div>                     （1）、能调用多种版本控制软件取得代码。</div>
		<div>                     （2）、对代码进行编译，并自动管理版本号。</div>
		<div>                     （3）、对编译结果能及时并且自动反馈，编译时的任何错误都能被追踪。</div>
		<div>                     （4）、可以调用测试软件进行测试。</div>
		<div>                     （5）、构建成功完成后能作出软件“快照”，可直接供测试和发布。</div>
		<div>                     （6）、是否支持多语言编译。</div>
		<div>                     （7）、可灵活定义构建流程。</div>
		<div>              2、易用性：</div>
		<div>                            界面是否简单易用。</div>
		<div>              3、后期维护和扩展性：</div>
		<div>                     （1）、每日构建流程的创建是否简便</div>
		<div>                     （2）、项目进行中对每日构建的流程的变更是否简便。</div>
		<div>                     （3）、其他功能的支持，比如集成文件复制，删除，属性更改；压缩、ftp文件传输等。</div>
		<div>                     </div>
		<div>              4、软件费用：</div>
		<div>                     每日构建软件自身成本，以及使用和维护时产生的费用成本。</div>
		<div> </div>
		<h3>
				<font size="5">三、评估对象</font>
		</h3>
		<div>              由于时间等方面的原因，只对两个每日构建软件进行评估。</div>
		<div>       分别是FinalBuilder2和开源软件Want。</div>
		<h3>
				<font size="5">四、评估方法</font>
		</h3>
		<div>       从实际开发流程出发，从VSS取代码，进行编译和发布</div>
		<h3>
				<font size="5">五、评估结果</font>
		</h3>
		<div>       </div>
		<div>   1、针对评估项目：</div>
		<table cellspacing="0" cellpadding="0" width="569" border="0">
				<tbody>
						<tr>
								<td nowrap="" width="53">
										<div align="left">　</div>
								</td>
								<td nowrap="" width="144">
										<div align="left">　</div>
								</td>
								<td nowrap="" width="180">
										<div align="center">
												<b>FinalBuilder2</b>
										</div>
								</td>
								<td nowrap="" width="192">
										<div align="center">
												<b>Want</b>
										</div>
								</td>
								<td width="0" height="28">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="53" rowspan="7">
										<div align="center">
												<b>基本功能</b>
										</div>
								</td>
								<td nowrap="" width="144">
										<div>支持多种版本控制软件</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">VSS、CVS、QVCS等多种，没有的可以扩充</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">不直接支持，可以改代码</div>
								</td>
								<td width="0" height="23">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div>编译代码，生成版本号</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">支持</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">支持</div>
								</td>
								<td width="0" height="24">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div>及时自动反馈编译结果</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">可以通过日志、e-mail等多种方式反馈</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">日志和界面</div>
								</td>
								<td width="0" height="27">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div>支持测试软件</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">支持AQTIME，可以用命令行扩充</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">支持DUNIT单元测试，其余的要改代码或调用</div>
								</td>
								<td width="0" height="24">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div>构建成功完成可直接供测试和发布</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">可以通过文件复制、ftp等方式直接发布</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">不直接支持，可以改代码</div>
								</td>
								<td width="0" height="30">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div>支持多语言编译。</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">支持DELPHI、JAVA、.NET等</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">只支持DELPHI，但可以改代码</div>
								</td>
								<td width="0" height="23">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div>灵活定义构建流程</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">可以，并可以对构建程序编写脚本事件</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">不太方便</div>
								</td>
								<td width="0" height="25">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="53" rowspan="2">
										<div align="center">
												<b>易用性</b>
										</div>
								</td>
								<td nowrap="" width="144" rowspan="2">
										<div>界面是否简单易用</div>
								</td>
								<td nowrap="" width="180" rowspan="2">
										<div>是，完全GUI界面，也支持命令行</div>
								</td>
								<td nowrap="" width="192" rowspan="2">
										<div align="left">不太方便，控制台程序，配置时需编写XML文件</div>
								</td>
								<td width="0" height="21">
								</td>
						</tr>
						<tr>
								<td width="0" height="21">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="53" rowspan="3">
										<div align="center">
												<b>后期维护和扩展性</b>
										</div>
								</td>
								<td nowrap="" width="144">
										<div>快速创建构建流程</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">是</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">需花时间熟悉，编写XML文件</div>
								</td>
								<td width="0" height="26">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div align="left">快速变更构建的流程</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">是</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">需花时间熟悉，修改XML文件</div>
								</td>
								<td width="0" height="25">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="144">
										<div>其他功能的支持，比如集成文件复制，删除，属性更改；压缩、ftp文件传输等。</div>
								</td>
								<td nowrap="" width="180">
										<div align="left">是</div>
								</td>
								<td nowrap="" width="192">
										<div align="left">支持压缩等，但大部分要动代码</div>
								</td>
								<td width="0" height="49">
								</td>
						</tr>
						<tr>
								<td nowrap="" width="53" rowspan="2">
										<div align="center">
												<b>软件费用：</b>
										</div>
								</td>
								<td nowrap="" width="144" rowspan="2">
										<div align="left">费用</div>
								</td>
								<td nowrap="" width="180" rowspan="2">
										<div align="left">EUR:300,后期费用少</div>
								</td>
								<td nowrap="" width="192" rowspan="2">
										<div align="left">免费，后期费用多</div>
								</td>
								<td width="0" height="21">
								</td>
						</tr>
						<tr>
								<td width="0" height="21">
								</td>
						</tr>
				</tbody>
		</table>
		<div> </div>
		<div>2、总体描述：</div>
		<div> （1）、二者在测试时都发现小BUG，由于WANT是开源软件，迅速解决问题，但FB2有新闻组支持，第二天也得到反馈。</div>
		<div>                          在SOURCEFORGE上，对WANT的BUG提交最迟是去年10月，要么是很成熟，要么是人气不足了。后者可能性更大。</div>
		<div>（2）、WANT的架构是比较灵活的，比如对多语言编译的扩充，从代码上看，是可以在其架构上进行。</div>
		<div>              而FB2的扩充只能是通过调用批文件等或版本升级来进行，但它已经提供了大多数主流语言的编译。</div>
		<div>（3）、在构建流程的配置上，WANT是通过手写XML文件配置，虽然有它附带辅助工具DOF2WANT来自动从DOF文件生成xml，但实际情况是生成的文件并不能直接或少许改动后使用，还是有比较大的工作量。单个WANT程序只能编译一个工程文件，如果是群组，必须依次调用，日后组织困难。</div>
		<div>FB2是通过图形界面配置，直观易用，流程的顺序和是否使用通过鼠标控制就可以配置，并可以方便的把多个流程组合并顺序使用。</div>
		<div>（4）、FB2还提供了一些其他功能：构建过程中人机交换功能、注册表的读写、检测磁盘剩余空间、创建虚拟驱动器，调用InstallShield，对INTERNET的访问、运行脚本（支持四种脚本语言）等功能。</div>
		<div>（5）、从每日构建的理论来说，WANT更像是每日编译，虽然它比直接写编译批文件功能强大一些。FB2相对来说是比较完善的，它的流程化更加清晰，更人性化。</div>
		<div>WANT的优势在于开源，可以不断进行完善来达到FB2的功能和便利优势，但所需人工费用很大。</div>
		<div>因此，从性价比上看，FB2对一个想通过实施每日构建来提高软件质量和管理质量的公司来说，应该是个比较好的选择。</div><img src ="http://www.cnitblog.com/tilan/aggbug/21912.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-01-16 11:21 <a href="http://www.cnitblog.com/tilan/articles/21912.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 在ant中使用cvs功能自动完成每日构建</title><link>http://www.cnitblog.com/tilan/articles/21907.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Tue, 16 Jan 2007 02:58:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/21907.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/21907.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/21907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/21907.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/21907.html</trackback:ping><description><![CDATA[<p>实现的主要功能是：自动从cvs中check out模块，然后编译，把编译后的class打成jar，再commit到cvs服务器的指定位置。 <br />build.xml <br /></p>
		<div class="code_title">代码</div>
		<div class="code_div">
				<div class="dp-highlighter">
						<div class="bar">
						</div>
						<ol class="dp-xml">
								<li class="alt">
										<span>
												<span class="tag">&lt;?</span>
												<span class="tag-name">xml</span>
												<span> </span>
												<span class="attribute">version</span>
												<span>=</span>
												<span class="attribute-value">"1.0"</span>
												<span class="tag">?&gt;</span>
												<span>  </span>
										</span>
								</li>
								<li class="">
										<span>
										</span>
										<span class="tag">&lt;</span>
										<span class="tag-name">project</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"gnt Auto build"</span>
										<span> </span>
										<span class="attribute">basedir</span>
										<span>=</span>
										<span class="attribute-value">"."</span>
										<span> </span>
										<span class="attribute">default</span>
										<span>=</span>
										<span class="attribute-value">"build"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- The CVSROOT value --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"cvsroot"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">":pserver:dhf:@192.168.0.200:D:/cvs_repository_z"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"cvs.password"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">""</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>     </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.dir"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"${basedir}/ywzcpt"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.module.name"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.dir"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"${basedir}/zfyw"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.module.name"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"zfyw"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"external.dir"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"${basedir}/external"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"external.module.name"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"external"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"cvs-op"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"co "</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- Initializing --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"init"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">tstamp</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>            </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">format</span>
										<span> </span>
										<span class="attribute">property</span>
										<span>=</span>
										<span class="attribute-value">"today"</span>
										<span> </span>
										<span class="attribute">pattern</span>
										<span>=</span>
										<span class="attribute-value">"yyyy-MM-dd hh:mm:ss"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">tstamp</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"${today}"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"prepare"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"init"</span>
										<span> </span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvspass</span>
										<span> </span>
										<span class="attribute">cvsroot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">password</span>
										<span>=</span>
										<span class="attribute-value">"${cvs.password}"</span>
										<span> </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"prepare"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvs</span>
										<span> </span>
										<span class="attribute">cvsRoot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">package</span>
										<span>=</span>
										<span class="attribute-value">"${external.module.name}"</span>
										<span>    </span>
								</li>
								<li class="">
										<span>             </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comments">&lt;!-- Retrieve the ywzcpt module --&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-check-out"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">delete</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span class="tag">/&gt;</span>
										<span>    </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvs</span>
										<span> </span>
										<span class="attribute">cvsRoot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">package</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span>    </span>
								</li>
								<li class="alt">
										<span>             </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-check-out"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">delete</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span class="tag">/&gt;</span>
										<span>    </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">cvs</span>
										<span> </span>
										<span class="attribute">cvsRoot</span>
										<span>=</span>
										<span class="attribute-value">"${cvsroot}"</span>
										<span> </span>
										<span class="attribute">package</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span>    </span>
								</li>
								<li class="alt">
										<span>             </span>
										<span class="attribute">passfile</span>
										<span>=</span>
										<span class="attribute-value">"ant-cvs.cvspass"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- cvs checkout --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"external-check-out"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-check-out"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-check-out"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="comments">&lt;!-- build XSP framework --&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"build"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|     Start Building GNT for compilation      |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">antcall</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-build"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|      End Building GNT for compilation       |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+=============================================+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>       </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-build"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt-check-out"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|    Start Building ywzcpt for compilation    |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span> </span>
										<span class="attribute">output</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.log"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.add"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"add ./build/log/*.log ./build/*.jar ./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"ywzcpt.commit"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>="commit -m '${today}' ./build/log/*.log ./build/*.jar    </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"commit-build"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>           </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+     End Building ywzcpt for compilation     |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>       </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-build"</span>
										<span> </span>
										<span class="attribute">depends</span>
										<span>=</span>
										<span class="attribute-value">"zfyw-check-out, ywzcpt-build"</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"|    Start Building ywzcpt for compilation    |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span> </span>
										<span class="attribute">output</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.log"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.add"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>=</span>
										<span class="attribute-value">"add ./build/log/*.log ./build/*.jar ./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">property</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"zfyw.commit"</span>
										<span> </span>
										<span class="attribute">value</span>
										<span>="commit -m '${today}' ./build/log/*.log ./build/*.jar    </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>./build/*.war"</span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">ant</span>
										<span> </span>
										<span class="attribute">antfile</span>
										<span>=</span>
										<span class="attribute-value">"build.xml"</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${zfyw.module.name}"</span>
										<span> </span>
										<span class="attribute">target</span>
										<span>=</span>
										<span class="attribute-value">"commit-build"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>           </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+     End Building ywzcpt for compilation     |"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">echo</span>
										<span> </span>
										<span class="attribute">message</span>
										<span>=</span>
										<span class="attribute-value">"+---------------------------------------------+"</span>
										<span> </span>
										<span class="tag">/&gt;</span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">target</span>
										<span> </span>
										<span class="attribute">name</span>
										<span>=</span>
										<span class="attribute-value">"clean"</span>
										<span> </span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>        </span>
										<span class="tag">&lt;</span>
										<span class="tag-name">delete</span>
										<span> </span>
										<span class="attribute">dir</span>
										<span>=</span>
										<span class="attribute-value">"${ywzcpt.module.name}"</span>
										<span class="tag">/&gt;</span>
										<span>    </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">target</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
								<li class="">
										<span>     </span>
								</li>
								<li class="alt">
										<span>
										</span>
										<span class="tag">&lt;/</span>
										<span class="tag-name">project</span>
										<span class="tag">&gt;</span>
										<span>  </span>
								</li>
						</ol>
				</div>
		</div>
		<script><![CDATA[ender_code();]]&gt;</script>
		<br />ywzcpt/build.xml片断： <br /><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-xml"><li class="alt"><span><span>主要实现commit功能   </span></span></li><li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">target</span><span> </span><span class="attribute">name</span><span>=</span><span class="attribute-value">"commit-build"</span><span class="tag">&gt;</span><span>  </span></li><li class="alt"><span>    </span><span class="tag">&lt;</span><span class="tag-name">cvs</span><span> </span><span class="attribute">cvsRoot</span><span>=</span><span class="attribute-value">"${cvsroot}"</span><span> </span><span class="attribute">passfile</span><span>=</span><span class="attribute-value">"${root.dir}/ant-cvs.cvspass"</span><span>  </span></li><li class=""><span>         </span><span class="attribute">command</span><span>=</span><span class="attribute-value">"${ywzcpt.add}"</span><span class="tag">/&gt;</span><span>  </span></li><li class="alt"><span>    </span><span class="tag">&lt;</span><span class="tag-name">cvs</span><span> </span><span class="attribute">cvsRoot</span><span>=</span><span class="attribute-value">"${cvsroot}"</span><span> </span><span class="attribute">passfile</span><span>=</span><span class="attribute-value">"${root.dir}/ant-cvs.cvspass"</span><span>  </span></li><li class=""><span>         </span><span class="attribute">command</span><span>=</span><span class="attribute-value">"${ywzcpt.commit}"</span><span class="tag">/&gt;</span><span>  </span></li><li class="alt"><span></span><span class="tag">&lt;/</span><span class="tag-name">target</span><span class="tag">&gt;</span><span>  </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><br />最后，在win2k中制定一个计划任务，就可以了。


<script type="text/javascript"><!--
google_ad_client = "pub-3874079075380071";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-03-19: 3G-move, 三星, 摩托罗拉, 索爱, 诺基亚
google_ad_channel = "1730597762+1709572468+0778807001+6838187825+8377398382";
//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><img src ="http://www.cnitblog.com/tilan/aggbug/21907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-01-16 10:58 <a href="http://www.cnitblog.com/tilan/articles/21907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 的版本控制-------关于体系结构、模型和示例的概述</title><link>http://www.cnitblog.com/tilan/articles/21894.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Mon, 15 Jan 2007 15:10:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/21894.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/21894.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/21894.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/21894.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/21894.html</trackback:ping><description><![CDATA[<p>2006 年 11 月 06 日</p>
		<blockquote>版本控制系统或资源管理系统是现代软件开发的一个重要方面。不使用版本控制系统就如同超速驾驶一辆汽车：很刺激，也可能会更快抵达目的地，但事故却在所难免。本文概述了软件配置管理（SCM）系统及其优势，内容涵盖 CVS、Subversion、Arch 和 Git。本文还讨论了最常见的 SCM 体系结构。本文在最后给出了新出现的一些方法及这些方法与先前方法的区别。 </blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>
				<a name="N1004B">
						<span class="atitle">什么是软件配置管理？</span>
				</a>
		</p>
		<p>在学校学习的重要工具中，通常<i>不会</i> 包含 SCM。软件（或资源）控制，正如其名字所暗示的那样，是一种工具和一种相关的过程，而这种过程被用于维护源代码及其演进。SCM 提供的主要功能如下：</p>
		<ul>
				<li>在存储库（repository）中维护一个文件。 
</li>
				<li>在存储库中维护文件的修订。 
</li>
				<li>检测源更改冲突并为多个开发人员的环境提供合并。 
</li>
				<li>跟踪变更的发起方。 
</li>
				<li>为了实现一致、可重复的构建提供文件（相关修订）的配置管理。 </li>
		</ul>
		<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N1006C">
																				<b>SCM 的适用性</b>
																		</a>
																		<br />
																		<i>资源控制</i> 主要是指源代码和相关文件的控制，而<i>资源管理</i> 则可应用于任何类型的资源。包含超文本标记语言（HTML）和二进制图像文件、一般文本文档或其他任何文件的 Web 站点是 SCM 系统进行修订控制的对象。 </td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>所以，SCM 允许您控制存储库中的一组文件并跟踪这些文件的修订。其他开发人员更改了存储库中的这些文件后，SCM 会标识出这些变更与您所做的变更之间存在的冲突，然后自动将其合并或通知您存在冲突。这个功能非常重要，因为它允许多个开发人员修改同一组文件。SCM 还能跟踪出谁做了何种变更。SCM 还允许您将文件按逻辑划分为相关的文件组，比如组成软件图像或可执行文件的源文件。 </p>
		<p>
				<a name="N1007B">
						<span class="atitle">SCM 的术语</span>
				</a>
		</p>
		<p>在深入研究 SCM 体系结构的类型和细节之前，先要熟悉一下术语的含义。<i>存储库</i> 是文件存储和管理的中心位置（有时又被称为<i>树</i>）。从存储库中取出文件放到本地系统的工作文件夹的过程被称作<i>签出</i>。如果变更了本地文件而又想同步变更存储库，就需要执行<i>更新</i>。如果要将变更后的文件签入到存储库，就需执行<i>提交</i>。如果所变更的文件先前已经被变更并已由别人提交，则会发生<i>合并</i>，表明两组变更集将会被合并在一起。若由于变更冲突的原因不能合并时，则必已发生了<i>冲突</i>。在此情况下，提交被拒绝，并要求开发人员手工合并变更。当提交了变更之后，就会创建此文件的一个新的<i>修订</i>。</p>
		<p>一个或多个开发人员可以对主树（存储库的当前头）或位于主树旁的单个的<i>分支</i>进行操作。这就让开发人员可以操作分支而不会影响到主树。当分支稳定后，再将分支与主树进行合并。</p>
		<p>要标记源树演进过程中的重要阶段，可以对一组文件修订应用<i>标签</i>。这会将这组文件组合成一个有用的集合（有时会用作针对于惟一构建的文件的一个发布）。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/linux/l-vercon/index.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100A8">
						<span class="atitle">体系结构</span>
				</a>
		</p>
		<p>各种 SCM 间有许多的差异，其中有两种最基本的区别很值得研究：</p>
		<ul>
				<li>集中式存储库与分布式存储库 
</li>
				<li>变更集模型与快照模型 </li>
		</ul>
		<p>
				<a name="N100BA">
						<span class="smalltitle">
								<strong>
										<font face="Arial">集中式存储库与分布式存储库</font>
								</strong>
						</span>
				</a>
		</p>
		<p>现代 SCM 体系结构的最为重要的差异之一是存储库是集中式的还是分布式（分散的）。当前最为常见的体系结构是集中式存储库。这个<i>星型</i> 体系结构由中心的源存储库和工作于这个存储库的多个开发人员组成（参见图 1）。开发人员从中心存储库签出源代码到本地的沙箱内，进行变更后，将它提交回中心存储库。其他开发人员就可以再访问这些变更。</p>
		<br />
		<a name="figure1">
				<b>图 1. 在集中式体系结构中，所有开发人员都通过同一个中心存储库进行工作</b>
		</a>
		<br />
		<img height="199" alt="集中式的 SCM 体系结构" src="http://www.ibm.com/developerworks/cn/linux/l-vercon/figure1.gif" width="457" />
		<br />
		<p>中心存储库也可以创建分支，允许多个开发人员协作于针对位于存储库（但必须在 <i>mainline</i> 或 <i>tip</i> 之外）的资源的一组变更。</p>
		<p>分布式体系结构则允许开发人员为其变更创建其自己本地的存储库。本地开发人员的存储库与原始的存储库（已被分布）很相似。主要的区别是：在集中化的方式中，变更是在沙箱内完成的，而在分布式方法中则允许开发人员工作于分离的存储库。开发人员进行变更、提交变更到其本地的存储库，之后，在不影响主干的前提下，与其他开发人员的变更合并。这样，本地开发人员就使得变更集对上线（upline）开发人员可用（参见图 2）。</p>
		<br />
		<a name="figure2">
				<b>图 2. 在分散体系结构中，开发人员通过其各自的存储库员同步工作</b>
		</a>
		<br />
		<img height="679" alt="分散的 SCM 体系结构" src="http://www.ibm.com/developerworks/cn/linux/l-vercon/figure2.gif" width="566" />
		<br />
		<p>分散体系结构很有意思，因为它允许不同的开发人员在对等网络内同步工作。当工作准备好（最好是稳定）后，开发人员可以分发变更集（或修补）以使他人也可以使用这些特性。这是当今许多开源系统的模型，包括 Linux® 内核。</p>
		<p>
				<a name="N100F6">
						<span class="smalltitle">
								<strong>
										<font face="Arial">变更集模型与快照模型</font>
								</strong>
						</span>
				</a>
		</p>
		<p>早先的和现代的 SCM 的体系结构的另一个有趣的区别是 delta 变更的存储方式。它们理论上是相同的，且产生的结果也相同，但在修订的存储方式上二者却大不相同。</p>
		<p>在快照模型中，整个存储库的每个修订（带优化以减少树的大小）的全部文件都被存储。而在变更集模型中，只有 delta 被存储于修订之间，这样就创建了一个精简的存储库（参见图 3）。 </p>
		<br />
		<a name="figure3">
				<b>图 3. 快照模型和变更集模型各有所长</b>
		</a>
		<br />
		<img height="302" alt="快照模型与变更集模型的对比" src="http://www.ibm.com/developerworks/cn/linux/l-vercon/figure3.gif" width="353" />
		<br />
		<p>从图 3 可以看出，模型不同但结果却相同。在快照模型中，可以快速获得修订，但需要更多的空间来存储它们。而变更集模型需要的空间少，但需要更多时间来获得某个修订，原因是 delta 必须应用于基本修订。在本文后面的部分将介绍如何建立优化来最小化必须要应用的 delta 的数量。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/linux/l-vercon/index.html#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10114">
						<span class="atitle">示例 SCM</span>
				</a>
		</p>
		<p>让我们来看一下按体系结构（集中或分布）划分的一些 SCM。您很快就会看到，其中一些 SCM 支持两种模型。</p>
		<p>
				<a name="N1011D">
						<span class="smalltitle">
								<strong>
										<font face="Arial">CVS</font>
								</strong>
						</span>
				</a>
		</p>
		<p>并发版本系统（Concurrent Versions System，CVS）是当今最为常用的 SCM。它是一种集中式的解决方案，采用了快照模型，开发人员使用集中式的存储库来进行软件的协作开发。CVS 十分常见而且是 Linux 发布版的一部分。其简单和方便的语法（对大多数人而言）使其迅速成为了多个或单个开发人员 SCM 的一种理想选择。</p>
		<p>清单 1 给出了一组 CVS 命令示例和简短的相关描述。要获得关于 CVS 的更多信息，请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/l-vercon/index.html#resources"><font color="#5c81a7">参考资料</font></a> 部分。</p>
		<br />
		<a name="listing1">
				<b>清单 1. CVS 命令示例</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode"># Create a new repository
<span class="boldcode"><strong>cvs -d /home/user/new_repository init</strong></span>

# Connect to the central repository
<span class="boldcode"><strong>export CVSROOT=:pserver:user@example.com:/cvs_root</strong></span>

# Check out a sandbox for module project from the central repository
<span class="boldcode"><strong>cvs checkout project</strong></span>

# Update a local sandbox from the central repository
<span class="boldcode"><strong>cvs update</strong></span>

# Check in changes from the local sandbox to the central repository
<span class="boldcode"><strong>cvs commit</strong></span>

# Add new files to the local sandbox (need to be committed)
<span class="boldcode"><strong>cvs add &lt;file/subdirectory&gt;</strong></span>

# Show changes made in the local sandbox
<span class="boldcode"><strong>cvs diff</strong></span></pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>对于喜欢用指向-单击方式操作的用户，CVS 提供了许多开源的图形化前端以供使用，包括 WinCVS 和 TortoiseCVS（集成了 Microsoft® Windows Explorer）。</p>
		<p>尽管 CVS 被广泛采用，但它仍然有一些不足之处。CVS 不允许重命名文件，而且对一些特殊文件（如 symlink）的支持不是很好。变更可以按文件跟踪，而非按变更本身，这点十分讨厌。合并有时也会出现问题（CVS 内部会为此使用 diff3）。</p>
		<p>然而，CVS 总体而言还是很有用的，能够实现其需要实现的任务，而且所有主流的平台都支持 CVS。如果喜欢用 CVS 而又想回避其缺点，则可以考虑使用 Subversion。</p>
		<p>
				<a name="N10155">
						<span class="smalltitle">
								<strong>
										<font face="Arial">Subversion</font>
								</strong>
						</span>
				</a>
		</p>
		<p>Subversion（SVN）是为了替代 CVS 而设计的，消除了 CVS 原有的问题和缺点。与 CVS 一样，Subversion 也是一种集中化的解决方案，采用的是快照模型。它的命令也模仿了 CVS 的，但增加了一些对诸如删除文件、重命名文件或恢复为原始文件等的处理功能。</p>
		<p>Subversion 还允许远程访问，可以采用很多协议，比如超文本传输协议 (HTTP)、安全 HTTP或定制的 SVN 协议，此协议还支持通过 Secure Shell (SSH)的隧道技术。</p>
		<p>清单 2 给出了 Subversion 所支持的一些命令及 CVS 中所没有的一些扩展。要获得关于 Subversion 的更多信息，请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/l-vercon/index.html#resources"><font color="#5c81a7">参考资料</font></a> 部分。很明显，Subversion 的命令集和 CVS 的很相似，这使它极受 CVS 用户的欢迎。</p>
		<br />
		<a name="listing2">
				<b>清单 2. Subversion 的命令示例</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode"># Create a new repository
<span class="boldcode"><strong>svnadmin create /home/user/new_repository</strong></span>

# Check out a sandbox from the central repository
<span class="boldcode"><strong>svn checkout file:///server/svn/existing_repository new_repository</strong></span>

# Update a local sandbox from the central repository
<span class="boldcode"><strong>svn update</strong></span>

# Check in changes from the local sandbox to the central repository
<span class="boldcode"><strong>svn commit</strong></span>

# Add new files to the local sandbox (need to be committed)
<span class="boldcode"><strong>svn add &lt;file/subdirectory&gt;</strong></span>

# Show changes made in the local sandbox
<span class="boldcode"><strong>svn diff</strong></span>

# Rename a file in the local sandbox (requires commit to the repository)
<span class="boldcode"><strong>svn rename &lt;old_file&gt; &lt;new_file&gt;</strong></span>

# Remove files (also removed from repository, requires commit)
<span class="boldcode"><strong>svn delete &lt;file/subdirectory&gt;</strong></span></pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>与 CVS 一样，Subversion 集成了一些图形化的前端如 ViewCVS 和 TortoiseSVN。另外也有一些工具可以把 CVS 存储库转化为 Subversion（例如 cvs2svn.py），但这些工具并不能处理复杂版本的分支和标记。和许多开源项目一样，随着时间的推移，这种情况会有所改变。Subversion 还集成了 TortoiseMerge 作为一个单独的查看器和修补程序。</p>
		<p>Subversion 解决了许多让 CVS 用户困扰的问题，比如特殊文件的版本化和自动的提交和签出。如果您喜欢用 CVS 和集中式存储库的方式，那么 Subversion 就是您所需的 SCM。</p>
		<p>现在让我们先放下对集中方式的讨论，看看被人们视为 SCM 未来的协作式分散存储库。</p>
		<p>
				<a name="N10191">
						<span class="smalltitle">
								<strong>
										<font face="Arial">Arch</font>
								</strong>
						</span>
				</a>
		</p>
		<p>Arch 是分散 SCM 的规范，它提供许多不同的实现，包括 ArX、Bazaar、GNU arch 和 Larch。Arch 不仅可以作为一种分散 SCM 运作，如 <a href="http://www.ibm.com/developerworks/cn/linux/l-vercon/figure2.gif"><font color="#5c81a7">图 2</font></a> 所示，还可使用变更集模型（参见 <a href="http://www.ibm.com/developerworks/cn/linux/l-vercon/figure3.gif"><font color="#5c81a7">图 3</font></a>）。Arch SCM 是开源开发的一种很流行的方法，因为开发人员可在单独的存储库上进行开发，同时又能够控制全部资源。这是因为分布式存储库就是具有修订控制的实际存储库。可以在本地存储库利用变更创建一个修补来供上游的开发人员使用。这就是分散模型的真正的强势所在。</p>
		<p>与 Subversion 相似，Arch 解决了 CVS 中所存在的许多问题，包括元数据的变更，例如修订文件许可、处理文件删除和重命名以及自动的签入（将签入组在一起而非作为单独的文件）。</p>
		<p>清单 3 中显示了 Arch SCM 中的一些常见命令，还给出了 GNU arch，因为它是由 Arch 的设计者 Tom Lord 开发的。GNU arch 提供了 SCM 应有的一些基本功能，包括 Subversion 中的一些新特性。</p>
		<br />
		<a name="listing3">
				<b>清单 3. GNU arch (tla) 的命令示例</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode"># Register a public archive
<span class="boldcode"><strong>tla register-archive http://www.mtjones.com/arch</strong></span>

# Check out a local repository from the upstream repository
<span class="boldcode"><strong>tla get project@mtjones.com--dev/project--stable myproject</strong></span>

# Update from the local repository
<span class="boldcode"><strong>tla update</strong></span>

# Check in changes to the local repository
<span class="boldcode"><strong>tla commit</strong></span>

# Add new files to the local repository (need to be committed)
<span class="boldcode"><strong>tla add &lt;file&gt;</strong></span>

# Show changes made in the local repository (patch format)
<span class="boldcode"><strong>tla what-changed</strong></span>

# Rename a file in the local repository (requires commit to the repository)
<span class="boldcode"><strong>tla mv &lt;old_file&gt; &lt;new_file&gt;</strong></span>

# Remove files (also removed from repository, requires commit)
<span class="boldcode"><strong>tla rm &lt;file&gt;</strong></span></pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>Arch 还允许用 <code>star-merge</code> 合并来自上游存储库的变更。为了最小化必须应用到基本修订的修补的数量（根据变更集模型）， <code>cacherev</code> 命令将会在存储库中创建基本修订的一个新的快照。 </p>创建基本修订的一个新快照 
<p>Arch 的优势之一是虽然它是为分散操作所设计的，但也可以用于集中存储库范例。</p><p><code>tla</code> 用户对其不满之处是它太过复杂。其他的 Arch 实现，例如 <code>baz</code> 则非常简单。如果 <code>tla</code> 不能满足要求，可以尝试使用后者。</p><p>现在让我们来看一下最后一个分散式的 SCM，它由 Linux 内核的维护者 Linus Torvalds 本人编写。</p><p><a name="N101E7"><span class="smalltitle"><strong><font face="Arial">Git</font></strong></span></a></p><p>Git SCM 由 Linus Torvalds 开发，用来替代 Bitkeeper SCM（参阅 <a href="http://www.ibm.com/developerworks/cn/linux/l-vercon/index.html#resources"><font color="#5c81a7">参考资料</font></a> 部分）。 它非常简单，是一种分散式的基于变更集的 SCM 且用作 Linux 内核的 SCM。它使用文件组模型而非跟踪单个的文件。使用 SHA1 压缩并混编变更集以验证其完整性（参见清单 4）。 </p><br /><a name="listing4"><b>清单 4. Git 的命令示例</b></a><br /><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr><td class="code-outline"><pre class="displaycode"># Get a Git repository (first time)
git clone \
  rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \
  linux-2.6

rsync -a \
  --progress rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/ \
  .git/

# Update a Git repository from the defined upstream Git repository
<span class="boldcode"><strong>git pull rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</strong></span>

# Checkout from the Git repository into the local working repository
<span class="boldcode"><strong>git checkout</strong></span>

# Update from the local Git repositor3
<span class="boldcode"><strong>git-update-cache</strong></span>

# Commit changes to the local Git repository
<span class="boldcode"><strong>git commit</strong></span>

# Add new files to the local repository
<span class="boldcode"><strong>git-update-cache --add &lt;file&gt;</strong></span>

# Show changes made to the local working directory
<span class="boldcode"><strong>git diff</strong></span>

# Remove files (requires commit)
<span class="boldcode"><strong>git-update-cache --remove &lt;file&gt;</strong></span></pre></td></tr></tbody></table><br /><p>Git SCM 在其自己的 Git 存储库内是自托管的，这意味着您必须引导 Git 来将其安装到本机。Git 的命令集与您到目前为止看到的那些命令十分类似，而且相对简单。</p><p>您可能会问：“为什么不使用现有的 SCM 中的一种呢？” 问得很好。 Git 非常有趣，吸引着许多 Linux 内核黑客，所以它很可能成为下一个主流的 SCM。Linus 将 Git 描述为一个高速的目录内容管理器，虽然它所做的工作不多但完成得十分高效。 </p><br /><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr><td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /><img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td></tr></tbody></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tbody><tr align="right"><td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td valign="center"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /></td><td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/linux/l-vercon/index.html#main"><b><font color="#5c81a7">回页首</font></b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N1021A"><span class="atitle">收益</span></a></p><p>无论您使用何种 SCM，都会获得一些普遍的收益。使用 SCM，可以跟踪文件中的变更来判断变更对软件的影响程度。当发生不正确的变更时，可以发现这些变更并将它们恢复回原始资源中。可以组合文件修订集并标记它们来制作发布，而发布又可以在任何时间签出以供重复构建代码的特定发布（SCM 的要求）。</p><p>不管使用集中式存储库还是分布式存储库，使用快照模型还是变更集模型，所带来的收益都是相同的。因为任何现代软件开发项目都必须要有 SCM，所以越早越多地使用它们就会受益越多。</p><br /><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr><td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /><img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td></tr></tbody></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tbody><tr align="right"><td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td valign="center"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /></td><td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/linux/l-vercon/index.html#main"><b><font color="#5c81a7">回页首</font></b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N10226"><span class="atitle">前景展望</span></a></p><p>本文只讨论了现在最为常用的 SCM 的一些最基础的知识。还有许多其他的开源 SCM 可以使用，例如 Aegis、Bazaar-NG、DARCS 和 Monotone。当然，SCM 也引起了一些争论，而这些争论通常很难有正确的答案。如果使用一种工具后效率极高，那就使用这种工具吧！SCM 大多时候都用在团队开发的情况下，而很少用于孤立的个人开发的环境中（除非您是个独断专行的老板，喜欢自己做所有决定）。所以，您尽可以尝试所有的可能性来熟悉一些不同的风格。SCM 是软件开发中的必需工具，也是您的开发工具箱中的必备部分。 </p><br /><br /><p><a name="resources"><span class="atitle">参考资料 </span></a></p><b>学习</b><br /><ul><li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/library/l-vercon/?S_TACT=105AGX52&amp;S_CMP=cn-a-l" target="_blank"><font color="#5c81a7">英文原文</font></a> 。<br /><br /></li><li>在 LinuxMafia，浏览大量的 Linux <a href="http://linuxmafia.com/faq/Apps/scm.html"><font color="#5c81a7">SCM</font></a> 。 <br /><br /></li><li>阅读 David Wheeler 关于开源 SCM 的 <a href="http://www.dwheeler.com/essays/scm.html"><font color="#5c81a7">有趣论文</font></a>，内容涵盖 CVS、Subversion、Arch 和 Monotone。 <br /><br /></li><li>Nick Moffitt 在 <a href="http://www.linuxjournal.com/node/7671/print"><font color="#5c81a7">Revision Control with Arch: Introduction to Arch</font></a>（Linux Journal，2004 年 11 月）中为我们介绍了 Arch 的一个十分有趣的方面。 <br /><br /></li><li>Tom Copeland 在 “<a href="http://www.ibm.com/developerworks/cn/java/j-statcvs/"><font color="#5c81a7">StatCVS 提供了对 CVS 储存库活动的深入观察</font></a>”（developerWorks，2005 年 2 月）一文中展示了如何用 StatCVS 从 CVS 历史数据中创建图表。 <br /><br /></li><li>在 “<a href="http://www.eweek.com/article2/0,1895,1788876,00.asp"><font color="#5c81a7">Torvalds Gives Inside Skinny on Git</font></a>”（eWeek，2005 年 4 月）一文中向 Linus 本人学习 Git 的更多知识。 <br /><br /></li><li>在 <a href="http://linux.yyz.us/git-howto.html"><font color="#5c81a7">Kernel Hackers' Guide</font></a> 中了解 Git。 <br /><br /></li><li>这里的 <a href="http://better-scm.berlios.de/comparison/comparison.html"><font color="#5c81a7">版本控制系统比较</font></a> 提供了多种 SCM 间的对比。 <br /><br /></li><li>通过本文作者编著的 <a href="http://www.charlesriver.com/Books/BookDetail.aspx?productID=91525"><font color="#5c81a7">GNU/Linux Application Programming</font></a> 一书（Charles River Media，2005 年 1 月）全面学习 Linux 编程，从工具到 API 等等。 <br /><br /></li><li>要获得关于 CVS 的更详尽的信息，请参阅 <a href="http://www.ibm.com/developerworks/cn/views/linux/tutorials.jsp?cv_doc_id=87496"><font color="#5c81a7">开发者和爱好者的 CVS</font></a>（developerWorks，2001 年 3 月）。 <br /><br /></li><li>在 <a href="http://www.ibm.com/developerworks/cn/linux/"><font color="#5c81a7">developerWorks Linux 专区</font></a>可以找到为 Linux 开发人员准备的更多资源。 <br /><br /></li><li>随时关注 <a href="http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGX52&amp;S_CMP=cn-a-l"><font color="#5c81a7">developerWorks 技术事件和网络广播</font></a>。 </li></ul><br /><b>获得产品和技术</b><br /><ul><li><a href="http://www.nongnu.org/cvs/"><font color="#5c81a7">CVS</font></a> 是应用最早和最广泛的 SCM 之一。 <br /><br /></li><li><a href="http://subversion.tigris.org/"><font color="#996699">Subversion</font></a> 是 CVS 的一个强有力的替代品。 <br /><br /></li><li><a href="http://www.gnu.org/software/gnu-arch"><font color="#5c81a7">GNU arch</font></a> 是由 Tom Lord 完成的 Arch SCM 规范的一个实现。 <br /><br /></li><li>参阅 sourceforge 的 <a href="http://aegis.sourceforge.net/"><font color="#5c81a7">Aegis</font></a>，这是一个基于事务的 SCM。 <br /><br /></li><li>关于 IBM 的 SCM，请访问 <a href="http://www.ibm.com/software/rational/offerings/scm.html"><font color="#5c81a7">Rational change and configuration management</font></a> 页面。 <br /><br /></li><li><a href="http://www.ibm.com/developerworks/offers/sek/?S_TACT=105AGX52&amp;S_CMP=cn-a-l"><font color="#5c81a7">订购 SEK for Linux</font></a>，这有两张 DVD，含最新的 IBM for Linux 的试用软件，包括 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere®。 <br /><br /></li><li>使用 <a href="http://www.ibm.com/developerworks/downloads/?S_TACT=105AGX52&amp;S_CMP=cn-a-l"><font color="#5c81a7">IBM 试用软件</font></a> 构建您的下一个 Linux 开发项目，这些软件可以从 developerWorks 直接下载。 <br /><br /></li></ul><br /><b>讨论</b><br /><ul><li>通过参与 <a href="http://www.ibm.com/developerworks/blogs/?S_TACT=105AGX52&amp;S_CMP=cn-a-l"><font color="#5c81a7">developerWorks blogs</font></a> 加入 <a href="http://www.ibm.com/developerworks/community?S_TACT=105AGX52&amp;S_CMP=cn-a-l"><font color="#5c81a7">developerWorks 社区</font></a>。 <br /></li></ul><script type="text/javascript"><!--
google_ad_client = "pub-3874079075380071";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-03-19: 3G-move, 三星, 摩托罗拉, 索爱, 诺基亚
google_ad_channel = "1730597762+1709572468+0778807001+6838187825+8377398382";
//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><img src ="http://www.cnitblog.com/tilan/aggbug/21894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/tilan/" target="_blank">关注IT</a> 2007-01-15 23:10 <a href="http://www.cnitblog.com/tilan/articles/21894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件工程</title><link>http://www.cnitblog.com/tilan/articles/21893.html</link><dc:creator>关注IT</dc:creator><author>关注IT</author><pubDate>Mon, 15 Jan 2007 15:03:00 GMT</pubDate><guid>http://www.cnitblog.com/tilan/articles/21893.html</guid><wfw:comment>http://www.cnitblog.com/tilan/comments/21893.html</wfw:comment><comments>http://www.cnitblog.com/tilan/articles/21893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/tilan/comments/commentRss/21893.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/tilan/services/trackbacks/21893.html</trackback:ping><description><![CDATA[<font face="Verdana"> </font>
		<a href="http://www.itisedu.com/phrase/200602281725525.html" target="_new">
				<font face="Verdana">软件工程</font>
		</a>
		<font face="Verdana">(</font>
		<a href="http://www.itisedu.com/phrase/200604240910235.html" target="_new">
				<font face="Verdana">Software Engineering</font>
		</a>
		<font face="Verdana">，简称为SE)是一门研究用工程化方法构建和维护有效的、实用的和高质量的</font>
		<a href="http://www.itisedu.com/phrase/200604232134205.html" target="_new">
				<font face="Verdana">软件</font>
		</a>
		<font face="Verdana">的学科。它涉及到</font>
		<a href="http://www.itisedu.com/phrase/200602281700255.html" target="_new">
				<font face="Verdana">程序设计语言</font>
		</a>
		<font face="Verdana">，</font>
		<a href="http://www.itisedu.com/phrase/200602271218062.html" target="_new">
				<font face="Verdana">数据库</font>
		</a>
		<font face="Verdana">，</font>
		<a href="http://www.itisedu.com/phrase/200603282233345.html" target="_new">
				<font face="Verdana">软件开发</font>
		</a>
		<font face="Verdana">工具，系统平台，标准，</font>
		<a href="http://www.itisedu.com/phrase/200603061631585.html" target="_new">
				<font face="Verdana">设计模式</font>
		</a>
		<font face="Verdana">等方面。</font>
		<p>
				<font face="Verdana">      在现代社会中，软件应用于多个方面。典型的软件比如有电子邮件，</font>
				<a href="http://www.itisedu.com/phrase/200603112246585.html" target="_new">
						<font face="Verdana">嵌入式系统</font>
				</a>
				<font face="Verdana">，人机界面，办公套件，</font>
				<a href="http://www.itisedu.com/phrase/200602281634075.html" target="_new">
						<font face="Verdana">操作系统</font>
				</a>
				<font face="Verdana">，编译器，数据库，游戏等。同时，各个行业几乎都有</font>
				<a href="http://www.itisedu.com/phrase/200602281627065.html" target="_new">
						<font face="Verdana">计算机软件</font>
				</a>
				<font face="Verdana">的应用，比如工业，农业，银行，航空，政府部门等。这些应用促进了经济和社会的发展，使得人们的工作更加高效，同时提高了生活质量。</font>
		</p>
		<p>
				<font face="Verdana">      软件工程师是对应用软件创造软件的人们的统称，软件工程师按照所处的领域不同可以分为系统分析员，软件设计师，系统<a href="http://www.itisedu.com/phrase/200604231335565.html" target="_new">架构师</a>，<a href="http://www.itisedu.com/phrase/200604232224305.html" target="_new">程序</a>员，测试员等等。人们也常常用程序员来泛指各种软件工程师。</font>
		</p>
		<p>
				<font face="Verdana">     软件工程(SoftWare Engineering)的<a href="http://www.itisedu.com/phrase/200603061723295.html" target="_new">框架</a>可概括为：目标、过程和原则。</font>
		</p>
		<p>
				<font face="Verdana">     (1)软件工程目标：生产具有正确性、可用性以及开销合宜的产品。正确性指软件产品达到预期功能的程度。可用性指软件基本结构、实现及文档为用户可用的程度。开销合宜是指软件开发、运行的整个开销满足用户要求的程度。这些目标的实现不论在理论上还是在实践中均存在很多待解决的问题，它们形成了对过程、过程模型及工程方法选取的约束。</font>
		</p>
		<p>
				<font face="Verdana">     (2)软件工程过程：生产一个最终能满足<a href="http://www.itisedu.com/phrase/200603101518295.html" target="_new">需求</a>且达到工程目标的软件产品所需要的步骤。软件工程过程主要包括开发过程、运作过程、维护过程。它们覆盖了需求、设计、实现、确认以及维护等活动。需求活动包括问题分析和<a href="http://www.itisedu.com/phrase/200603062220345.html" target="_new">需求分析</a>。问题分析获取需求定义，又称<a href="http://www.itisedu.com/phrase/200603061756235.html" target="_new">软件需求</a>规约。需求分析生成功能规约。设计活动一般包括概要设计和详细设计。概要设计建立整个<a href="http://www.itisedu.com/phrase/200602281706245.html" target="_new">软件系统</a>结构，包括<a href="http://www.itisedu.com/phrase/200604161433025.html" target="_new">子系统</a>、模块以及相关层次的说明、每一模块的接口定义。详细设计产生程序员可用的模块说明，包括每一模块中数据结构说明及加工描述。实现活动把设计结果转换为可执行的程序代码。确认活动贯穿于整个开发过程，实现完成后的确认，保证最终产品满足用户的要求。维护活动包括使用过程中的扩充、修改与完善。伴随以上过程，还有管理过程、支持过程、培训过程等。</font>
		</p>
		<p>
				<font face="Verdana">      (3)软件工程的原则是指围绕工程设计、工程支持以及工程管理在软件开发过程中必须遵循的原则。</font>
		</p>
		<p>
				<font face="Verdana">
						<strong>一、软件工程概述</strong>
				</font>
		</p>
		<p>
				<font face="Verdana">      概念：应需而生</font>
		</p>
		<p>
				<font face="Verdana">　　软件工程是一<a href="http://www.itisedu.com/phrase/200603090857555.html" target="_new">类</a>工程。工程是将理论和知识应用于实践的科学。就软件工程而言，它借鉴了传统工程的原则和方法，以求高效地开发高质量软件。其中应用了<a href="http://www.itisedu.com/phrase/200603021438435.html" target="_new">计算机</a>科学、数学和管理科学。计算机科学和数学用于构造模型与算法，工程科学用于制定规范、设计范型、评估成本及确定权衡，管理科学用于计划、资源、质量和成本的管理。</font>
		</p>
		<p>
				<font face="Verdana">      软件工程这一概念，主要是针对20世纪60年代“<a href="http://www.itisedu.com/phrase/200603112323405.html" target="_new">软件危机</a>”而提出的。它首次出现在1968年NATO（北大西洋公约组织）会议上。自这一概念提出以来，围绕软件项目，开展了有关开发模型、方法以及支持工具的研究。其主要成果有：提出了瀑布模型，开发了一些结构化<a href="http://www.itisedu.com/phrase/200602281641255.html" target="_new">程序设计</a>语言（例如PASCAL语言，Ada语言）、<a href="http://www.itisedu.com/phrase/200602281749185.html" target="_new">结构化方法</a>等。并且围绕<a href="http://www.itisedu.com/phrase/200604240825565.html" target="_new">项目管理</a>提出了费用估算、文档<a href="http://www.itisedu.com/phrase/200604161505135.html" target="_new">复审</a>等方法和工具。综观60年代末至80年代初，其主要特征是，前期着重研究系统实现技术，后期开始强调开发管理和软件质量。</font>
		</p>
		<p>
				<font face="Verdana">      70年代初，自“<a href="http://www.itisedu.com/phrase/200603061612405.html" target="_new">软件工厂</a>”这一概念提出以来，主要围绕<a href="http://www.itisedu.com/phrase/200602282140185.html" target="_new">软件过程</a>以及<a href="http://www.itisedu.com/phrase/200602281831545.html" target="_new">软件复用</a>，开展了有关软件生产技术和软件生产管理的研究与实践。其主要成果有：提出了应用广泛的<a href="http://www.itisedu.com/phrase/200603010948085.html" target="_new">面向对象语言</a>以及相关的<a href="http://www.itisedu.com/phrase/200602281513385.html" target="_new">面向对象方法</a>，大力开展了计算机辅助软件工程的研究与实践。尤其是近几年来，针对软件复用及软件生产，软件<a href="http://www.itisedu.com/phrase/200604161439595.html" target="_new">构件</a>技术以及软件质量控制技术、质量保证技术得到了广泛的应用。目前各个软件企业都十分重视资质认证，并想通过这些工作进行企业管理和技术的提升。软件工程所涉及的要素可概括如下： </font>
		</p>
		<p>
				<font face="Verdana">      根据这一框架，可以看出：软件工程涉及了软件工程的目标、软件工程原则和软件工程活动。</font>
		</p>
		<p>
				<font face="Verdana">      目标：我的眼里只有“产品”</font>
		</p>
		<p>
				<font face="Verdana">      软件工程的主要目标是：生产具有正确性、可用性以及开销合宜的产品。正确性意指软件产品达到预期功能的程度。可用性指软件基本结构、实现及文档为用户可用的程度。开销合宜性是指软件开发、运行的整个开销满足用户要求的程度。这些目标的实现不论在理论上还是在实践中均存在很多问题有待解决，它们形成了对过程、过程模型及工程方法选取的约束。</font>
		</p>
		<p>
				<font face="Verdana">      软件工程活动是“生产一个最终满足需求且达到工程目标的软件产品所需要的步骤”。主要包括需求、设计、实现、确认以及支持等活动。需求活动包括问题分析和需求分析。问题分析获取需求定义，又称软件需求规约。需求分析生成功能规约。设计活动一般包括概要设计和详细设计。概要设计建立整个<a href="http://www.itisedu.com/phrase/200603131358465.html" target="_new">软件体系结构</a>，包括子系统、模块以及相关层次的说明、每一模块接口定义。详细设计产生程序员可用的模块说明，包括每一模块中数据结构说明及加工描述。实现活动把设计结果转换为可执行的程序代码。确认活动贯穿于整个开发过程，实现完成后的确认，保证最终产品满足用户的要求。支持活动包括修改和完善。伴随以上活动，还有管理过程、支持过程、培训过程等。 </font>
		</p>
		<p>
				<font face="Verdana">      框架：四项基本原则是基石 </font>
		</p>
		<p>
				<font face="Verdana">　　软件工程围绕工程设计、工程支持以及工程管理，提出了以下四项基本原则：</font>
		</p>
		<p>
				<font face="Verdana">      第一，选取适宜开发范型。该原则与系统设计有关。在系统设计中，软件需求、硬件需求以及其他因素之间是相互制约、相互影响的，经常需要权衡。因此，必须认识需求定义的易变性，采用适宜的开发范型予以控制，以保证软件产品满足用户的要求。</font>
		</p>
		<p>
				<font face="Verdana">      第二，采用合适的设计方法。在软件设计中，通常要考虑软件的模块化、抽象与信息隐蔽、局部化、一致性以及适应性等特征。合适的设计方法有助于这些特征的实现，以达到软件工程的目标。</font>
		</p>
		<p>
				<font face="Verdana">      第三，提供高质量的工程支持。“工欲善其事，必先利其器”。在软件工程中，<a href="http://www.itisedu.com/phrase/200602282117345.html" target="_new">软件工具</a>与环境对软件过程的支持颇为重要。软件工程项目的质量与开销直接取决于对软件工程所提供的支撑质量和效用。</font>
		</p>
		<p>
				<font face="Verdana">      第四，重视开发过程的管理。软件工程的管理，直接影响可用资源的有效利用，生产满足目标的软件产品，提高软件组织的生产能力等问题。因此，仅当软件过程得以有效管理时，才能实现有效的软件工程。</font>
		</p>
		<p>
				<font face="Verdana">      这一软件工程框架告诉我们，软件工程的目标是可用性、正确性和合算性；实施一个软件工程要选取适宜的开发范型，要采用合适的设计方法，要提供高质量的工程支撑，要实行开发过程的有效管理；软件工程活动主要包括需求、设计、实现、确认和支持等活动，每一活动可根据特定的软件工程，采用合适的开发范型、设计方法、支持过程以及过程管理。根据软件工程这一框架，软件工程学科的研究内容主要包括：软件开发范型、软件开发方法、软件过程、软件工具、<a href="http://www.itisedu.com/phrase/200602282250045.html" target="_new">软件开发环境</a>、计算机辅助软件工程(CASE) 及软件经济学等。 </font>
		</p>
		<p>
				<font face="Verdana">      作用：高效开发高质量软件 </font>
		</p>
		<p>
				<font face="Verdana">　　自从软件工程概念提出以来，经过30多年的研究与实践,虽然“软件危机”没得到彻底解决，但在软件开发方法和技术方面已经有了很大的进步。尤其应该指出的是，自80年代中期，美国工业界和政府部门开始认识到，在软件开发中，最关键的问题是软件开发组织不能很好地定义和管理其软件过程，从而使一些好的开发方法和技术都起不到所期望的作用。也就是说，在没有很好定义和管理软件过程的软件开发中，开发组织不可能在好的软件方法和工具中获益。</font>
		</p>
		<p>
				<font face="Verdana">      根据调查，中国的现状几乎和美国10多年前的情况一样，软件开发过程没有明确规定，文档不完整，也不规范，软件项目的成功往往归功于软件开发组的一些杰出个人或小组的努力。这种依赖于个别人员上的成功并不能为全组织的软件生产率和质量的提高奠定有效的基础，只有通过建立全组织的过程改善，采用严格的软件工程方法和管理，并且坚持不懈地付诸实践，才能取得全组织的软件过程能力的不断提高。</font>
		</p>
		<p>
				<font face="Verdana">      这一事实告诉我们，只有坚持软件工程的四条基本原则，既重视软件技术的应用，又重视软件工程的支持和管理，并在实践中贯彻实施，才能高效地开发出高质量的软件。 </font>
		</p>
		<p>
				<font face="Verdana">
						<strong>二、软件工程的七条基本原理</strong>
				</font>
		</p>
		<p>
				<font face="Verdana">      自从1968年提出“软件工程”这一术语以来，研究软件工程的专家学者们陆续 提出了100多条关于软件工程的准则或信条。 美国著名的软件工程专家 Boehm 综合这些专家的意见，并总结了TRW公司多年的开发软件的经验，于1983年提出了软件工程的七条基本原理。 </font>
		</p>
		<p>
				<font face="Verdana">　　Boehm 认为，着七条原理是确保软件产品质量和开发效率的原理的最小集合。 <br />　　它们是相互独立的，是缺一不可的最小集合；同时，它们又是相当完备的。 </font>
		</p>
		<p>
				<font face="Verdana">　　人们当然不能用数学方法严格证明它们是一个完备的集合，但是可以证明，在此之前已经提出的100多条软件工程准则都可以有这七条原理的任意组合蕴含或派生。 </font>
		</p>
		<p>
				<font face="Verdana">　　下面简要介绍软件工程的七条原理： </font>
		</p>
		<p>
				<font face="Verdana">　　1 用分阶段的生命周期计划严格管理 <br />　　这一条是吸取前人的教训而提出来的。统计表明，50%以上的失败项目是由于计划不周而造成的。在软件开发与维护的漫长生命周期中，需要完成许多性质各异的工作。这条原理意味着，应该把<a href="http://www.itisedu.com/phrase/200603061230195.html" target="_new">软件生命周期</a>分成若干阶段，并相应制定出切实可行的计划，然后严格按照计划对软件的开发和维护进行管理。 Boehm 认为，在整个软件生命周期中应指定并严格执行6类计划：项目概要计划、里程碑计划、项目控制计划、产品控制计划、验证计划、运行维护计划。 </font>
		</p>
		<p>
				<font face="Verdana">　　2 坚持进行阶段评审 <br />　　统计结果显示： 大部分错误是在编码之前造成的，大约占63%; &lt;2&gt; 错误发现的越晚，改正它要付出的代价就越大，要差2到3个数量级。 因此，软件的质量保证工作不能等到编码结束之后再进行，应坚持进行严格的阶段评审，以便尽早发现错误。 </font>
		</p>
		<p>
				<font face="Verdana">　　3 实行严格的产品控制 <br />　　开发人员最痛恨的事情之一就是改动需求。但是实践告诉我们，需求的改动往往是不可避免的。这就要求我们要采用科学的产品控制技术来顺应这种要求。也就是要采用变动控制，又叫基准<a href="http://www.itisedu.com/phrase/200602271137552.html" target="_new">配置管理</a>。当需求变动时，其它各个阶段的文档或代码随之相应变动，以保证软件的一致性。 </font>
		</p>
		<p>
				<font face="Verdana">　　4 采纳现代程序设计技术 <br />　　从六、七时年代的结构化软件开发技术，到最近的<a href="http://www.itisedu.com/phrase/200603101726185.html" target="_new">面向对象</a>技术，从第一、第二代语言，到第四代语言，人们已经充分认识到：方法大似气力。采用先进的技术即可以提高软件开发的效率，又可以减少软件维护的成本。 </font>
		</p>
		<p>
				<font face="Verdana">　　5 结果应能清楚地审查 <br />　　软件是一种看不见、摸不着的逻辑产品。软件开发小组的工作进展情况可见性差，难于评价和管理。为更好地进行管理，应根据软件开发的总目标及完成期限， 尽量明确地规定开发小组的责任和产品标准，从而使所得到的标准能清楚地审查。 </font>
		</p>
		<font face="Verdana">
				<p>
						<br />　　6 开发小组的人员应少而精 <br />　　开发人员的素质和数量是影响软件质量和开发效率的重要因素，应该少而精。 <br />　　这一条基于两点原因：高素质开发人员的效率比低素质开发人员的效率要高几倍到几十倍，开发工作中犯的错误也要少的多； 当开发小组为N人时，可能的通讯信道为N(N-1)/2, 可见随着人数N的增大，通讯开销将急剧增大。 </p>
				<p>　　7 承认不断改进软件工程实践的必要性 <br />　　遵从上述六条基本原理，就能够较好地实现软件的工程化生产。但是，它们只是对现有的经验的总结和归纳，并不能保证赶上技术不断前进发展的步伐。因此，Boehm提出应把承认不断改进软件工程实践的必要性作为软件工程的第七条原理。根据这条原理，不仅要积极采纳新的软件开发技术，还要注意不断总结经验，收集进度和消耗等数据，进行出错<a href="http://www.itisedu.com/phrase/200603051002565.html" target="_new">类型</a>和问题报告统计。这些数据既可以用来评估新的 软件技术的效果，也可以用来指明必须着重注意的问题和应该优先进行研究的工具和技术。 </p>
				<p>      面向方面的编程（Aspect Oriented <a href="http://www.itisedu.com/phrase/200604232129205.html" target="_new">Programming</a>，简称<a href="http://www.itisedu.com/phrase/200604231341385.html" target="_new">AOP</a>）被认为是近年来软件工程的另外一个重要发展。这里的方面指的是完成一个功能的<a href="http://www.itisedu.com/phrase/200603090845215.html" target="_new">对象</a>和函数的集合。在这一方面相关的内容有泛型编程（Generic Programming）和模板。</p>
				<p>参考<br />      胡崑山，《中国软件产业发展现状与人才需求》，2003年9月1日，            http://software.ccidnet.com/pub/article/c372_a62973_p1.html </p>
				<p>
						<font face="Verdana">
								<strong>三、软件工程的目标与常用模型</strong>
						</font>
				</p>
				<p>
						<font face="Verdana">      软件工程的目标是提高软件的质量与生产率，最终实现软件的工业化生产。质量是软件需求方最关心的问题，用户即使不图物美价廉，也要求个货真价实。生产率是软件供应方最关心的问题，老板和员工都想用更少的时间挣更多的钱。质量与生产率之间有着内在的联系，高生产率必须以质量合格为前提。如果质量不合格，对供需双方都是坏事情。从短期效益看，追求高质量会延长软件开发时间并且增大费用，似乎降低了生产率。从长期效益看，高质量将保证软件开发的全过程更加规范流畅，大大降低了软件的维护代价，实质上是提高了生产率，同时可获得很好的信誉。质量与生产率之间不存在根本的对立，好的软件工程方法可以同时提高质量与生产率。 </font>
				</p>
				<p>
						<font face="Verdana">      软件供需双方的代表能在餐桌上谈笑风生，归功于第一线开发人员的辛勤工作。质量与生产率的提高就指望程序员与程序经理。对开发人员而言，如果非得在质量与生产率之间分个主次不可，那么应该是质量第一，生产率第二。这是因为：（1）质量直接体现在软件的每段程序中，高质量自然是开发人员的技术追求，也是职业道德的要求。（2）高质量对所有的用户都有价值，而高生产率只对开发方有意义。（3）如果一开始就追求高生产率，容易使人急功近利，留下隐患。宁可进度慢些，也要保证每个环节的质量，以图长远利益。 </font>
				</p>
				<p>
						<font face="Verdana">      软件的质量因素很多，如正确性，性能、可靠性、容错性、易用性、灵活性、可扩充性、可理解性、可维护性等等。有些因素相互重叠，有些则相抵触，真要提高质量可不容易啊！ </font>
				</p>
				<p>
						<font face="Verdana">      软件工程的主要环节有：人员管理、项目管理、可行性与需求分析、系统设计、程序设计、测试、维护等，如图1.1所示。 </font>
				</p>
				<p align="center">
						<img src="http://www.itisedu.com/manage/Upload/image/200632922318332.gif" border="0" />
				</p>
				<p>
						<font face="Verdana">      软件工程模型建议用一定的流程将各个环节连接起来，并可用规范的方式操作全过程，如同工厂的生产线。常见的软件工程模型有：线性模型（图1.2），渐增式模型（图1.3），螺旋模型，快速原型模型，形式化描述模型等等 [Pressmam 1999, Sommerville 1992]。 </font>
				</p>
				<font face="Verdana">
						<p align="center">
								<img src="http://www.itisedu.com/manage/Upload/image/2006329223120904.gif" border="0" />
								<br />  </p>
				</font>
				<p>
						<font face="Verdana">      最早出现的软件工程模型是线性模型（又称瀑布模型）。线性模型太理想化，太单纯，已不再适合现代的软件开发<a href="http://www.itisedu.com/phrase/200603061709535.html" target="_new">模式</a>，几乎被业界抛弃。偶而被人提起，都属于被贬对象，未被留一丝惋惜。但我们应该认识到，“线性”是人们最容易掌握并能熟练应用的思想方法。当人们碰到一个复杂的“非线性”问题时，总是千方百计地将其分解或转化为一系列简单的线性问题，然后逐个解决。一个软件系统的整体可能是复杂的，而单个子程序总是简单的，可以用线性的方式来实现，否则干活就太累了。线性是一种简洁，简洁就是美。当我们领会了线性的精神，就不要再呆板地套用线性模型的外表，而应该用活它。例如渐增式模型实质就是分段的线性模型，如图1.3所示。螺旋模型则是接连的弯曲了的线性模型。在其它模型中都能够找到线性模型的影子。 </font>
				</p>
				<p>
						<font face="Verdana">      套用固定的模型不是程序员的聪明之举。比如“程序设计”与“测试”之间的关系，习惯上总以为程序设计在先，测试在后，如图1.4（a）所示。而对于一些复杂的程序，将测试分为同步测试与总测试更有效，如图1.4（b）所示。 </font>
				</p>
				<p align="center">
						<img src="http://www.itisedu.com/manage/Upload/image/2006329223139948.gif" border="0" />
				</p>
				<font face="Verdana">
						<p>
								<br />      不论是什么软件工程模型，总是少不了图1.1中的各个环节。本书擗开具体的软件工程模型，顺序讲述人员管理、项目管理、可行性与需求分析、系统设计、程序设计、测试，以及维护与再生工程。其中程序设计部分以C++/C语言为例。 </p>
				</font>
				<p>
				</p>
		</font>
		<font face="Verdana">
				<strong>四、软件<a href="http://www.itisedu.com/phrase/200603122156385.html" target="_new">体系结构</a>和工具的选择</strong>
		</font>
		<p>
				<font face="Verdana">　　软件体系结构表示了一个软件系统的高层结构，主要特点有：1）软件系统结构是一个高层次上的抽象，它并不涉及具体的系统结构（比如<a href="http://www.itisedu.com/phrase/200604291152445.html" target="_new">B/S</a>还是<a href="http://www.itisedu.com/phrase/200604291148225.html" target="_new">C/S</a>），也不关心具体的实现。2）软件体系结构必须支持系统所要求的功能，在设计软件体系结构的时候，必须考虑系统的动态行为。3）在设计软件体系结构的时候，必须考虑有现有系统的兼容性、安全性和可靠性。同时还要考虑系统以后的扩展性和伸缩性。所以有时候必须在多个不同方向的目标中进行决策。</font>
		</p>
		<p>
				<font face="Verdana">　　当前已经有一些关于规范化软件体系结构，比如：ISO的开放系统互联模型、X Window系统等等。软件系统的结构通常被定义为两个部分：一个是计算部件。另一个就是部件之间的交互。如果把软件系统看成一幅图的话，计算部件就是其中的节点，而部件之间的交互就是节点之间的弧线。部件之间的连接可以被认为是一种连接器，比如过程调用、事件广播、数据库查询等等。正确的体系结构设计是软件系统成功的关键。</font>
		</p>
		<p>
				<font face="Verdana">　　我们理解了软件工程的重要性以后，我们没有相应的工具，我们也很难很好的完成一个系统。在需求分析和设计阶段，我们需要什么样的工具呢？</font>
		</p>
		<p>
				<font face="Verdana">　　当然最好是基于<a href="http://www.itisedu.com/phrase/200602271429302.html" target="_new">UML</a>的CASE工具。当前比较流行的就是Rose，它是一个很好的分析和建立对象和对象关系的工具。在具体编码的时候，我们需要<a href="http://www.itisedu.com/phrase/200603292355295.html" target="_new">版本控制</a>工具，MS的SourceSafe就是一个很好的版本管理工具和项目管理工具。具体的开发工具当然很多，但是如果你是一个对VC侵淫了多年的程序员，你一定会选择它，因为它会让你感到什么是真正的面向对象的编程，而你在用VB，<a href="http://www.itisedu.com/phrase/200604041117205.html" target="_new">PowerBuilder</a>，<a href="http://www.itisedu.com/phrase/200604042241255.html" target="_new">Delphi</a>时很少会有同样的感受。至于数据库模式构建，我一向是采用<a href="http://www.itisedu.com/phrase/200604040934365.html" target="_new">Sybase</a>的S-Design，更好的工具就不知道了。</font>
		</p>
		<p>
				<font face="Verdana">　　另外需要注意的是，我们需要建立文档编写的若干模板，以便开发人员按照这个模板编写规范的技术和说明文档。帮助文档可以用微软的HTML Help Workshop(hhw.exe)制作，你也可以编译成.chm格式，它打包了文本和图形，只有一个<a href="http://www.itisedu.com/phrase/200602282323195.html" target="_new">文件</a>，使用和分发比较方便。最后，如果开发人员不是集中在一个地方的话，最好建立一个邮件列表，开发人员可以通过邮件系统讨论开发中的各项事宜。 </font>
		</p>
		<p>
				<font face="Verdana">
						<strong>