﻿<?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>BlogJava-jasmine214--love-随笔分类-配置管理</title><link>http://www.blogjava.net/jasmine214--love/category/47037.html</link><description>只有当你的内心总是充满快乐、美好的愿望和宁静时，你才能拥有强壮的体魄和明朗、快乐或者宁静的面容。</description><language>zh-cn</language><lastBuildDate>Sun, 15 Apr 2012 12:05:08 GMT</lastBuildDate><pubDate>Sun, 15 Apr 2012 12:05:08 GMT</pubDate><ttl>60</ttl><item><title>linux下SVN搭建完整过程及SVN使用相关内容</title><link>http://www.blogjava.net/jasmine214--love/archive/2012/04/10/373673.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Tue, 10 Apr 2012 01:23:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2012/04/10/373673.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/373673.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2012/04/10/373673.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/373673.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/373673.html</trackback:ping><description><![CDATA[<div>  <p>SVN<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">环境搭建完整步骤</span></p>  <p>&nbsp;</p>  <p><strong>1</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>SVN</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span></strong></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">从</span>VM<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">新建虚拟机</span></p>  <p>1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）安装路径：</span>D<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">：</span>\ubuntu-test</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">使用</span>ubuntu <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">软件：</span>c:\svn<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装软件</span>\ubuntu-10.04.1-desktop.i386.iso</p>  <p>Network adapter<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">：</span>Bridged</p>  <p>Ubuntu<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">登录账号</span>/<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">密码：</span>kiki/kiki</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装完成，重启</span>ubuntu<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，打开</span>terminal<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，自动获得了一个</span>IP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（</span>172.28.6.13<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）。</span></p>  <p>&nbsp;</p>  <p>2) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设置，安装过程</span></p>  <p>a) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设置</span> ip <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>dns<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">上网。</span></p>  <p>&nbsp;&nbsp;&nbsp; Step1,</p>  <p>sudo &#8211;s <span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">转成</span>root<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">用户，方便操作。</span></p>  <p>&nbsp;&nbsp;&nbsp; Step2,</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设置</span><span>IP, vi /etc/network/interfaces</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">加入：</span></p>  <p>auto eth0</p>  <p>iface eth0 inet static</p>  <p>address 172.28.6.239</p>  <p>netmask 255.255.0.0</p>  <p>gateway 172.28.16.1</p>  <p>&nbsp;&nbsp;&nbsp; Step3,</p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sudo nano /etc/resolv.conf</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">是一个编辑工具，设置</span>DNS<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">加入：</span><span>nameserver 10.58.100.1</span></p>  <p>&nbsp;&nbsp;&nbsp; Step4,</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">重新启动</span><span> networking </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">服务：</span></p>  <p>sudo /etc/init.d/networking restart</p>  <p>&nbsp;&nbsp;&nbsp; <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">总结：设置</span>OK<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span>ping 172.28.6.69<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">成功。</span></p>  <p>&nbsp;</p>  <p>b) apt-get update <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">先更新一下源。</span></p>  <p>c) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span>VIM</p>  <p>&nbsp;&nbsp;&nbsp; apt-get install vim </p>  <p>d) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span>openssh-server</p>  <p>e)&nbsp; <span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span>subversion</p>  <p>f) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span>subversion-tools</p>  <p>g) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span>apache2</p>  <p>h) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span>libapache2-svn</p>  <p>i) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">安装</span>tree </p>  <p>j) <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设置</span>apache2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">下的</span>SVN</p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vim /etc/apache2/dav_svn.conf</span></p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设置如下：</span></p>  <p>&lt;Location <span style="background:red;">/test/&gt;</span></p>  <p>&nbsp;DAV svn</p>  <p>&nbsp; SVNListParentPath on</p>  <p>&nbsp;&nbsp; SVNParentPath /home/repo/</p>  <p><span>&nbsp; # SVNIndexXSLT "/apache2-default/svnindex.xsl" </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（注释掉，否则会有</span>xml<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的错误，不能显示）</span></p>  <p>&nbsp; AuthType Basic</p>  <p><span>&nbsp; AuthName "Subversion Repository"</span></p>  <p><span>&nbsp; AuthUserFile /etc/apache2/dav_svn.passwd</span></p>  <p>&nbsp;&nbsp;&nbsp; Require valid-user</p>  <p><span>&nbsp; AuthzSVNAccessFile /etc/apache2/dav_svn.authz&nbsp; z</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">居然泄露了，害我找了好久的原因</span></p>  <p><span style="background:red;">&lt;/</span>Location&gt;</p>  <p>&nbsp;</p>  <p>PS<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">：</span></p>  <p>1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）刚安装好的</span>apache2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">没有</span>dav_svn.passwd<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">文件，</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">使用</span>vim <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">创建，</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">然后</span><span>htpasswd -b dav_svn.passwd kiki kiki&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">更新密码。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">创建</span>dav_svn.auth<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">文件，设置</span>*=rw<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">方便测试。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">权限文件设置注意：</span><span style="background:red;">[]</span>*=rw,<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">并且具备权限继承性，子目录的权限将代替父目录的权限。</span></p>  <p>2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）创建测试所用的版本库，路径在：</span>/home/repo/test1,<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">其中</span>test1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">是版本库。</span></p>  <p>3<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）重启</span>apache<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">服务</span><span> &nbsp;/etc/init.d/apache2 restart</span></p>  <p>4) &nbsp;<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">设置创建的帐户文件所属者为</span>www-data.</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设置创建的库所属者为</span>www-data,</p>  <p><span>root@kiki-desktop:/etc/apache2# chown www-data:www-data dav_svn.passwd</span></p>  <p><span>root@kiki-desktop:/etc/apache2# chmod 777 dav_svn.passwd</span></p>  <p><span>root@kiki-desktop:/home# chown -R www-data:www-data repo</span></p>  <p>5<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）访问：</span><a href="http://ip/test/">http://IP/<span style="background:red;">test/</span></a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">库名，</span>SSH<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">远程登录</span>ubuntu<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">出现中文乱码时，设置</span>LANG=&#8221;&#8221;;</p>  <p>&nbsp;</p>  <p><strong>2</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>SVN</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">版本对比</span></strong></p>  <p>2.1<span>&nbsp;&nbsp; Subversion 1.6</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的新东西</span></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#auth-related-improvements"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>改进的认证数据处理</span></span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#repository-root-relative-urls"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>版本库根的相对</span>URL</span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#externals">svn:externals<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>的改进</span></span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#tree-conflicts"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>目录树冲突的检测</span></span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#filesystem-improvements"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>文件系统存储改进</span></span></a></p>  <p><span><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#ctypes-python-bindings">Ctypes Python<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">绑定</span></a></span></p>  <p><span style="background:red;"><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#improved-interactive-conflict-resolution"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">改进的交互式冲突解决</span></a></span></p>  <p><span style="background:red;"><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#sparse-directory-exclusion"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">稀疏目录的排除选项</span></a></span></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#svnserve-logging">svnserve<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>的日志支持</span></span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#historical-uris"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>察看历史的新</span>HTTP URI<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">语法</span></span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#cmdline"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>命令行客户端改进</span></span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#apis">API<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>变更、改进以及多种语言绑定</span></span></a></p>  <p><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99#bug-fixes"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>超过</span>65<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">项新的</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修正和提升</span></span></a></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">参考：</span><a href="http://www.subversion.org.cn/?action-viewnews-itemid-99">http://www.subversion.org.cn/?action-viewnews-itemid-99</a></p>  <p>&nbsp;</p>  <p>2.2<span>&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">以下为共进实际情况：</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">服务器：</span>10.58.100.247  Subversion1.5</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">客户端：</span>10.58.102.3<span>&nbsp;&nbsp;&nbsp; Subversion1.6</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">改进和</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修正</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">改进的交互式冲突解决</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">客户端</span>)</p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image002.jpg" border="0" height="558" width="701"  alt="" /></p>  <p>svn up:</p>  <p><span style="position: absolute;z-index:1;left:0px;margin-left:28px;margin-top:75px;width:111px; height:12px"><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image003.gif" height="12" width="111"  alt="" /></span><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image005.jpg" border="0" height="99" width="180"  alt="" /></p>  <p><span style="position: absolute;z-index:2;left:0px;margin-left:16px;margin-top:231px;width:567px; height:12px"><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image006.gif" height="12" width="567"  alt="" /></span><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image008.jpg" border="0" height="599" width="600"  alt="" /></p>  <p>&nbsp;</p>  <p><strong>3</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>SVN</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">备份</span></strong></p>  <p>1. 10.58.101.6&nbsp;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">截图：</span> </p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image010.gif" border="0" height="137" width="638"  alt="" /><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image012.gif" border="0" height="152" width="642"  alt="" /></p>  <p>&nbsp;</p>  <p>2. 10.58.100.247&nbsp;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">截图</span></p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image014.gif" border="0" height="194" width="582"  alt="" /><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image016.gif" border="0" height="136" width="650"  alt="" /><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image018.gif" border="0" height="267" width="718"  alt="" /><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image020.gif" border="0" height="654" width="657"  alt="" /></p>  <p>2. 10.58.101.6<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">截图：</span></p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image022.gif" border="0" height="403" width="847"  alt="" /></p>  <p>&nbsp;</p>  <p>1. Rsync<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">（</span>remote synchronize<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）是一个远程数据同步工具，可通过</span>LAN/WAN<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">快速同步多台主机间的文件。</span>Rsync<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">使用所谓的</span>&#8220;Rsync<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">算法</span>&#8221;<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">来使本地和远</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">程两个主机之间的文件达到同步，这个算法只传送两个文件的不同部分，而不是每次都整份传送，因此速度相当快。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">第一次连通完成时，会把整份文件传输一次，以后则就只需进行增量备份。</span></p>  <p>&nbsp;</p>  <p>2. Rsync<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">支持大多数的类</span>Unix<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">系统，无论是</span>Linux<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>Solaris<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">还是</span>BSD<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">上都经过了良好的测试。此外，它在</span>windows<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">平台下也有相应的版</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">本，如</span>cwRsync<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>Sync2NAS<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">等工具。</span></p>  <p>&nbsp;</p>  <p>3. Rsync<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">的基本特点如下：</span> </p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span>1.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">可以镜像保存整个目录树和文件系统；</span> </p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span>2.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">可以很容易做到保持原来文件的权限、时间、软硬链接等；</span> </p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span>3.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">无须特殊权限即可安装；</span> </p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span>4.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">优化的流程，文件传输效率高；</span> </p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span>5.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">可以使用</span>rsh<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>ssh<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">等方式来传输文件，当然也可以通过直接的</span>socket<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">连接；</span> </p>  <p>6.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">支持匿名传输</span></p>  <p>4. rsync<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">是一个功能非常强大的工具，其命令也有很多功能特色选项，我们下面就对它的选项一一进行分析说明。</span> Rsync<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的命令格式可以为以下六种：</span> </p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span><span>rsync [OPTION]... SRC DEST</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span><span>rsync [OPTION]... SRC [USER@]HOST:DEST</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　　</span><span>rsync [OPTION]... [USER@]HOST:SRC DEST</span></p>  <p>5. <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">从远程</span>rsync<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">服务器中拷贝文件到本地机。当</span>SRC<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">路径信息包含</span>&#8221;::&#8220;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分隔符时启动该模式。如：</span><span>rsync -av &nbsp;<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#111;&#111;&#116;&#64;&#49;&#55;&#50;&#46;&#49;&#54;&#46;&#55;&#56;&#46;&#49;&#57;&#50;&#58;&#58;&#119;&#119;&#119;">root@172.16.78.192::www</a> &nbsp;/databack </span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">　</span> <span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">从本地机器拷贝文件到远程</span>rsync<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">服务器中。当</span>DST<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">路径信息包含</span>&#8221;::&#8220;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分隔符时启动该模式。如：</span><span>rsync -av &nbsp;/databack &nbsp;<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#111;&#111;&#116;&#64;&#49;&#55;&#50;&#46;&#49;&#54;&#46;&#55;&#56;&#46;&#49;&#57;&#50;&#58;&#58;&#119;&#119;&#119;">root@172.16.78.192::www</a> </span></p>  <p>&nbsp;</p>  <p>-a, --archive <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">归档模式，表示以递归方式传输文件，并保持所有文件属性，等于</span>-rlptgoD</p>  <p>&nbsp;</p>  <p>-v, --verbose <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">详细模式输出</span></p>  <p>&nbsp;</p>  <p><strong>4</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>SVN</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分支策略（常用分支模式</span>-</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">摘自</span>svn</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">指南</span>.doc</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></strong></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">参考资料：</span></p>  <p>Subversion1.4<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">手册</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.subversion.org.cn/svnbook/1.4/svn.branchmerge.maint.html">http://www.subversion.org.cn/svnbook/<span style="background:red;">1.4</span>/svn.branchmerge.maint.html</a></span></p>  <p>Subversion1.6<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">手册</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://i18n-zh.googlecode.com/svn/www/svnbook/zh/svn.tour.cycle.html#svn.tour.cycle.resolve</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">常用分支模式</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">版本控制在软件开发中广泛使用，这里是团队里程序员最常用的两种分支</span>/<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">合并模式的介绍，如果你不是使用</span>Subversion<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">软件开</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">发，可随意跳过本小节，如果你是第一次使用版本控制的软件开发者，请更加注意，以下模式被许多老兵当作最佳实践，这个过程并不只是针对</span> Subversion<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，在任何版本控制系统中都一样，但是在这里使用</span>Subversion<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">术语会感觉更方便一点。</span></p>  <p>&nbsp;</p>  <p><a name="svn.branchmerge.commonuses.patterns.rele"></a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">发布分支</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">大多数软件存在这样一个生命周期：编码、测试、发布，然后重复。这样有两个问题，第一，开发者需要在质量保证小组测试假定稳定</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">版本时继续开发新特性，新工作在软件测试时不可以中断，第二，小组必须一直支持老的发布版本和软件；如果一个</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在最新的代码中发现，它一定也存在已发</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">布的版本中，客户希望立刻得到错误修正而不必等到新版本发布。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这是版本控制可以做的帮助，典型的过程如下：</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开发者提交所有的新特性到主干。</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">每日的修改提交到</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">：新特性，</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修正和其他。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这个主干被拷贝到&#8220;发布&#8221;分支。</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">当小组认为软件已经做好发布的准备</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">如，版本</span>1.0)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">然后</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">会被拷贝到</span>/branches/1.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">项目组继续并行工作，一个小组开始对分支进行严酷的测试，同时另一个小组在</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">继续新的工作</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">如，准备</span>2.0)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，如果一个</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在任何一个位置被发现，错误修正需要来回运送。然而这个过程有时候也会结束，例如分支已经为发布前的最终测试&#8220;停滞&#8221;了。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分支已经作了标签并且发布，当测试结束，</span>/branches/1.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">作为引用快照已经拷贝到</span>/tags/1.0.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，这个标签被打包发布给客户。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分支多次维护。当继续在</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">上为版本</span>2.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">工作，</span>bug<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">修正继续从</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">运送到</span>/branches/1.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，如果积累了足够的</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修正，管理部门决定发布</span>1.0.1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">版本：拷贝</span>/branches/1.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">到</span>/tags/1.0.1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，标签被打包发布。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">整个过程随着软件的成熟不断重复：当</span>2.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">完成，一个新的</span>2.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分支被创建，测试、打标签和最终发布，经过许多年，版本库结束了许多版本发布，进入了&#8220;维护&#8221;模式，许多标签代表了最终的发布版本。</span></p>  <p>&nbsp;</p>  <p><a name="svn.branchmerge.commonuses.patterns.feat"></a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">特性分支</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">一个特性分支是本章中那个重要例子中的分支，你正在那个分支上工作，而</span>Sally<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">还在</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">继续工作，这是一个临时分支，用来作复杂的修改而不会干扰</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的稳定性，不象发布分支</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">也许要永远支持</span>)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，特性分支出生，使用了一段时间，合并到主干，然后最终被删除掉，它们在有限的时间里有用。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">还有，关于是否创建特性分支的项目政策也变化广泛，一些项目永远不使用特性分支：大家都可以提交到</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，好处是系统的简单&#8212;没有人需要知道分支和合并，坏处是主干会经常不稳定或者不可用，另外一些项目使用分支达到极限：没有修改曾经直接提交到主干，即使最细小的修改都要创建短暂的分支，然后小心的审核合并到主干，然后删除分支，这样系统保持主干一直稳定和可用，但是造成了巨大的负担。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">许多项目采用折中的方式，坚持每次编译</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">并进行回归测试，只有需要多次不稳定提交时才需要一个特性分支，这个规则可以用这样一个问题检验：如果开发者在好几天里独立工作，一次提交大量修改</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这样</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">就不会不稳定。</span>)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，是否会有太多的修改要来回顾？如果答案是&#8220;是&#8221;，这些修改应该在特性分支上进行，因为开发者增量的提交修改，你可以容易的回头检查。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">最终，有一个问题就是怎样保持一个特性分支&#8220;同步&#8221;于工作中的主干，在前面提到过，在一个分支上工作数周或几个月是很有风险的，主干的修改也许会持续涌入，因为这一点，两条线的开发会区别巨大，合并分支回到主干会成为一个噩梦。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这种情况最好通过有规律的将主干合并到分支来避免，制定这样一个政策：每周将上周的修改合并到分支，注意这样做时需要小心，需要手工记录合并的过程，以避免重复的合并</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在</span><a href="http://i18n-zh.googlecode.com/svn/www/svnbook-1.4/svn.branchmerge.copychanges.html#svn.branchmerge.copychanges.bestprac.track" title="手工跟踪合并"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>&#8220;手工跟踪合并&#8221;一节</span></span></a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">描述过</span>)<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">，你需要小心的撰写合并的日志信息，精确的描述合并包括的范围</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在</span><a href="http://i18n-zh.googlecode.com/svn/www/svnbook-1.4/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.wholebr" title="合并分支到另一分支"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>&#8220;合并分支到另一分支&#8221;一节</span></span></a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">中描述过</span>)<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">，这看起来像是胁迫，可是实际上是容易做到的。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在一些时候，你已经准备好了将&#8220;同步的&#8221;特性分支合并回到主干，为此，开始做一次将主干最新修改和分支的最终合并，这样以后，除了你的分支修改的部分，最新的分支和主干将会绝对一致，所以在这个特别的例子里，你会通过直接比较分支和主干来进行合并：</span></p>  <p>$ cd trunk-working-copy</p>  <p>&nbsp;</p>  <p>$ svn update</p>  <p>At revision 1910.</p>  <p>&nbsp;</p>  <p><span>$ svn merge http://svn.example.com/repos/calc/trunk@1910 \</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://svn.example.com/repos/calc/branches/mybranch@1910</span></p>  <p>U&nbsp;real.c</p>  <p>U&nbsp;integer.c</p>  <p>A&nbsp;newdirectory</p>  <p>A&nbsp;newdirectory/newfile</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">&#8230;</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">通过比较</span>HEAD<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修订版本的主干和</span>HEAD<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修订版本的分支，你确定了只在分支上的增量信息，两条开发线都有了分枝的修改。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">可以用另一种考虑这种模式，你每周按时同步分支到主干，类似于在工作拷贝执行</span>svn update<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的命令，最终的合并操作类似于在工作拷贝运行</span>svn commit<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，毕竟，工作拷贝不就是一个非常浅的分支吗？只是它一次只可以保存一个修改。</span></p>  <p>&nbsp;</p>  <p>&nbsp;</p>  <p><strong>5</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>Subversion</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">管理代码最佳实践</span></strong></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">代码管理实践</span><span> <br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">代码仓库均采用</span>svn<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">来管理</span> </p>  <p><span><br /> 5.1&nbsp;&nbsp; </span><span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">代码目录的创建：</span><span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">一般创建三个目录分别为</span> <span><br /> trunk(</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">主干</span>)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span> <span><br /> tags</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（标签</span>/<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">标记</span>)<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">，</span> <span><br /> branches(</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分支</span>)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。</span> <span><br /> tags</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>branches<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">下一般为根据需要从</span>trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">目录拷贝过来的。</span> </p>  <p><span><br /> 5.2&nbsp;&nbsp; tags</span><span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">的创建要求：</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">代码在一种平台下通过编译（必须）</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">代码编译出来的版本通过一定的冒烟测试。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在项目要求的平台都可以编译通过。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">一般有一个安装包给测试时，就需要在</span>tags<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">下建立对应代码的标签。</span> <span><br /> tags</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">下的代码一般不可以修改。</span><span> <br /> <br /> 5.3&nbsp;&nbsp; </span><span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">两种代码管理模式介绍</span><span>: <br /> a</span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、始终分支系统</span>(OpenOffice<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">社区采用管理方式</span><span>) <br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">典型特征</span>:<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">项目较大，代码较多，编译时间较长，参与人员比较多时。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">每个用户对每项编码任务的创建或操作都是在私有分支中进行的。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">编码完成后，原编码者、同级或经理将对所有私有分支的更改进行审查并将它由合并到</span> /trunk <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">中。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">里程碑的创建</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">集成人员集成将开发人员提交的功能集成到主干上，编译通过后，提交的主干上，集成了一定的功能后，创建一个里程碑版本，一般建议按周创建里程碑版本。并在</span>tags<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">下创建相应的代码快照，并将安装包传至指定位置。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开发人员基于里程碑版本开发。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开发人员一般基于最新的里程碑版本创建分支，并在分支上工作，并在自己的分支上提交，在提交到</span>svn<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">之前需要编译通过。开发人员需要根据自己开发情况来同步到主干的里程碑代码。如果需要集成到主干上，需要同步到最近的里程碑。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">测试人员</span><span>. <br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">测试人员对开发人员的代码进行测试，达到一定的测试标准后，测试通过，然后交由集成人员来集成。</span> <span><br /> <br /> </span></p>  <p>b<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、按需分支系统（</span>Subversion<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">社区采用管理方式）</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">适用方式代码较少，或者参与开发的人员较少</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开发人员可以直接在主干上提交。开发负责人来编译版本给测试。</span><span> <br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开发者把所有的新特性提交到主干。</span> <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">每日的修改提交到</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">：新特性，</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修正和其他。新近的开发人员不能提交代码，交由有经验的开发人员验证后来提交到主干上。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">当开发小组认为软件已经做好基本发布的准备</span>(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">如，版本</span>1.0)<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">然后</span>/trunk<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">会被拷贝到</span>/branches/1.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。这个主干被拷贝到</span>&#8220;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">发布</span>&#8221;<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">分支。然后在发布分支上继续修改</span><span>bug. <br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">如果</span>bug<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修正经测试达到一定的要求认为可以完成时，可以拷贝到</span>/tags/1.0.0<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，这个标签被建立并发布给相关人员。</span><span> <br /> <br /> </span></p>  <p>5.4<span>&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">向</span>svn<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">库提交提交代码要求</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">针对每次提交到主干上的代码均需要编译通过</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">代码每次提交到</span>svn<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">上均需要添加注释。</span> <span><br /> </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">每个人都用自己账号来提交代码。</span> </p>  <p>&nbsp;</p>  <p><strong>6</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、参考资料</span></strong></p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">分支模式在</span>SVN<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">环境下的应用</span></p>  <p style="margin-left:36.0pt"><a href="http://www.webwoo.net/SVN/svnsy/2009/1211/51007.html">http://www.webwoo.net/SVN/svnsy/2009/1211/51007.html</a></p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><a href="http://www.cnblogs.com/itech/archive/2011/08/01/2123354.html"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;"><span>持续集成之&#8220;分支策略&#8221;</span></span></a></p>  <p style="margin-left:36.0pt"><a href="http://wwling2001.blogbus.com/logs/164479726.html">http://wwling2001.blogbus.com/logs/164479726.html</a></p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>SVN<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">常用分支模式</span></p>  <p style="margin-left:36.0pt"><a href="http://i18n-zh.googlecode.com/svn/www/svnbook-1.4/svn.branchmerge.commonuses.html">http://i18n-zh.googlecode.com/svn/www/svnbook-1.4/svn.branchmerge.commonuses.html</a></p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">配置管理一问一答</span></p>  <p style="margin-left:36.0pt">http://qa.uml.net.cn/Question/List.aspx?t=1&amp;tid=13&amp;tn=%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86&amp;area=0</p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">百度</span>-<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">主干开发，分支提测</span></p>  <p style="margin-left:36.0pt"><a href="http://www.cnblogs.com/topiemie/">http://www.cnblogs.com/topiemie/</a></p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>subversion<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">管理代码最佳实践</span></p>  <p style="margin-left:36.0pt">http://www.zxbc.cn/html/20081212/68890.html</p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>Subversion<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">中文站</span></p>  <p style="margin-left:36.0pt"><a href="http://www.subversion.org.cn/?action-category-catid-1">http://www.subversion.org.cn/?action-category-catid-1</a></p>  <p style="margin-left:57.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;"><span>l<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>Subversion FAQ(<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">常见问题解答</span>)</p>  <p style="margin-left:36.0pt">http://subversion.apache.org/faq.zh.html</p>  </div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/373673.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2012-04-10 09:23 <a href="http://www.blogjava.net/jasmine214--love/archive/2012/04/10/373673.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单带子目录的makefile练习</title><link>http://www.blogjava.net/jasmine214--love/archive/2012/01/10/368261.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Tue, 10 Jan 2012 13:18:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2012/01/10/368261.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/368261.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2012/01/10/368261.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/368261.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/368261.html</trackback:ping><description><![CDATA[<div>　　开始学linux。我练习写的第一个带子目录的makefile文件。<br />　　1。建立文件夹 wulong<br />　　wulong中含 三个文件夹 include   source  pro 和makefile文件。<br />　　include 中包含 hai.h头文件。<br />　　source 中包含 hello.c文件。<br />　　pro 中包含 haia.c  haib.c文件。<br />　　<br />　　makefile文件内容有两种写法：<br />　　makefile 第一种写法：<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　CC=gcc                ＃选择编译器类型为gcc<br />　　VPATH= include : pr : source   #列明文件存放目录<br />　　<br />　　hello: hello.o haia.o haib.o     <br />　　        $(CC) -o hello hello.o haia.o haib.o<br />　　hello.o:hello.c hai.h<br />　　        $(CC) -c hello.c<br />　　haia.o: haia.c hai.h<br />　　        $(CC) -c haia.c<br />　　haib.o: haib.c hai.h<br />　　        $(CC) -c haib.c<br />　　.PHONY: clean<br />　　clean:<br />　　        rm hello $(obj)<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　<br />　　<br />　　<br />　　makefile第二种写法（简化版）：<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　CC=gcc              #选择编译种类<br />　　<br />　　VPATH= include : pr : source #在include pr source 三目录下查找文件<br />　　<br />　　obj= hello.o haia.o haib.o   ＃<br />　　<br />　　hello:$(obj)                   ＃<br />　　        $(CC) -o hello $(obj)<br />　　<br />　　$(obj): hai.h<br />　　<br />　　.PHONY: clean<br />　　clean:<br />　　        rm hello $(obj)<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　<br />　　<br />　　hai.h文件内容为：<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　#include "stdio.h"<br />　　extern  void haiprinta();<br />　　extern  void haiprintb();<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　<br />　　hello.c内容为：<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　#include "../include/hai.h"<br />　　<br />　　int main(void)<br />　　{<br />　　haiprinta();<br />　　haiprintb();<br />　　return 0;<br />　　}<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　<br />　　haia.c内容为：<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊<br />　　#include "../include/hai.h"<br />　　<br />　　void haiprinta()<br />　　{<br />　　printf("hai aaaaaaaaaa\n");<br />　　}<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　<br />　　<br />　　haib.c内容为：<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　#include "../include/hai.h"<br />　　<br />　　void haiprintb()<br />　　{<br />　　printf("haib bbbbbbbbbbbbbb\n");<br />　　}<br />　　／／＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊<br />　　<br />　　2。make 调用makefile生成 可执行文件 hello<br />　　<br />　　3. 运行 hello显示打印结果：<br />　　[HAI@localhost wulong]$ ./hello <br />　　hai aaaaaaaaaa<br />　　haib bbbbbbbbbbbbbb<br />　　[HAI@localhost wulong]$ <br />　　<br />　　到此结束，恭喜！</div><br />原文：<div>http://blog.tianya.cn/blogger/post_show.asp?BlogID=2058037&amp;PostID=17326631</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/368261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2012-01-10 21:18 <a href="http://www.blogjava.net/jasmine214--love/archive/2012/01/10/368261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCM如何进入一个项目</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/12/27/367318.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Tue, 27 Dec 2011 03:27:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/12/27/367318.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/367318.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/12/27/367318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/367318.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/367318.html</trackback:ping><description><![CDATA[<div><h3>[原创]配置管理员(CM)如何接手一个正在进展中的项目？</h3>配置管理员(CM)如何接手一个正在进展中的项目？<br /> <br /> 出自：bbs.scmroad.com 作者：laofo<br /> <br /> 在公司常常会遇到这种情况：<br /> 以前因为种种原因，项目没有专职的CM,但是有了自己的SCM系统，可能有开发人员暂时兼管着，而你这时临危受命。当你刚开始介入项目的时候，应该怎么展开呢？<br /> <br /> 我个人觉得先从了解项目开始：<br /> <br /> [b]1. 参加项目例会(project meeting)[/b]<br /> &nbsp; &nbsp;认识认识人，哪个是PM，哪个是QA，哪些是Tester。。。这个时候可能需要你的经理或者PM把你介绍给大家。看看美女帅哥，这就是你第一次参加项目理会的重点。<br /> &nbsp; &nbsp;开完第一次项目例会之后，一定要去看看project  plan，对这个项目周期，人员等等都要有个大概的认识。第二次参加会议的时候，就有一个CM发言的时间了，这个时候就是你的时间，记得把平时工作中发现 的关于CM的问题提出来，和PM，QA等一起商量如何解决。而有的事情（比如违反公司开发流程的事情）更要坚定不移的提出来，如果PM觉得有充足的理由不 遵守公司的流程，记得记下为什么作出的这个决定，也许Email，Document更能帮助你回忆，所以一定要保留下相关的信息。当然这些东西并不是让你 第二次开会的时候就能都找出来，可能刚开始的 一段时间，了解项目进度才是你最主要的工作。<br /> &nbsp; &nbsp;注：有的公司可能Team Leader（TL）管这些事情，而PM只管进度。那么你多数情况下联系的就是TL了。<br /> &nbsp; &nbsp;<br /> [b]2. 主动加入到项目的maillist当中去[/b]<br /> &nbsp; &nbsp;你可以自己要求，也可以向PM提出。这样项目一有事情，你也能得到通知了。<br /> &nbsp; &nbsp;<br /> [b]3. 要有SCM系统的授权[/b]<br /> &nbsp; &nbsp;因为项目已经有自己的SCM系统，你也就省去了一些搭建的时间。这个时候你需要向PM提出权限申请。<br /> &nbsp; &nbsp;CM一定要有SCM系统的full control previleges。<br /> &nbsp;  &nbsp;CM不一定会改变些SCM系统什么东西（如果有需要，CM肯定会改变的），但是CM一定要有SCM系统的全部控制权限，虽然有的时候你可能还接手不了整 个项目，因为你毕竟是项目中间加进来的一个人，但是一定要有这个权限。CM这个时候可以和开发人员一起管理SCM系统。事实上，最开始的阶段是你向开发人 员在学习这个系统。<br />  <br /> [b]4. 理解构建过程[/b]<br /> &nbsp; &nbsp;有的构建是通过makefile，有的是通过nat，或者nant，。。。那么这个时候你就要下点功夫去理解这些构建的脚本了。<br /> &nbsp;  &nbsp;CM不一定控制和负责所有构建脚本的编写和维护。因为有的系统很大，目录要分很多的层，开发人员对最底层的构建肯定要比CM熟悉的多，而这些最底层的脚 本也变化的很频繁，CM不必也没有那么多精力去维护这么多构建脚本。所以建议CM一般只要控制和维护最顶上的1到3层之间的构建脚本就可以了。<br /> &nbsp; &nbsp;注：如果项目还没有通过脚本来构建项目，那现在你就来完成它吧。<br /> <br /> [b]5. CM plan[/b]<br /> &nbsp; &nbsp;无论什么时候，CM plan都是你始终应该关注的重点。这里规定了你该做什么，怎么做，什么时候做等等问题。<br /> &nbsp; &nbsp;如果项目还没有CM plan，或者还没有正式的CM  plan，请撰写并且完善它。完成之后记得发给PM，QA，你的直接领导等等人士去review，没有问题了就发布出来。这是考核你工作的标准，事无巨 细，觉得对以后CM工作有帮助的，就要在project meeting上提出来，然后更新到CM plan中去。<br /> &nbsp; &nbsp;记得把CM plan放到SCM系统中去，同时让所有的人有权限访问。<br /> &nbsp; &nbsp;公司有什么编码规范啊，流程的规定啊，都可以作为CM plan的参考文献附在后边，哪怕给个链接地址也好。<br /> &nbsp; &nbsp;实际工作中遇到不明白的或者不清楚的时候，请记得参考CM plan，看看CM plan中是怎么规定的。<br /> &nbsp; &nbsp;注：如果公司有CM plan的模版，或者其它项目有CM plan，那么你不妨拿来参考一下。闭门造车的行为我不推荐，从前人的文档中，结合自己的经验，挑挑拣拣找出适合这个项目的，就是最好的。<br /> &nbsp; &nbsp;<br /> [b]6.&nbsp;&nbsp;关于CCB[/b]<br /> &nbsp; &nbsp;因为以前更本没有CM，所以CCB这块也是缺失的，而有的公司的流程把这一块弥补了。<br /> &nbsp; &nbsp;<br /> [b]7. 关于SCM系统的使用[/b]<br /> &nbsp; &nbsp;如果你以前没使用过，那么自己平时就要去学习。多向知道的人请教。先把最基本的，经常用的知识学到。80％的东西都可以放到以后去学习。<br /> &nbsp; &nbsp;<br /> 。。。。<br /> <br /> 通过以上几点，你都可以慢慢的融入到项目中去。而后续的工作，比如完善流程，SCM系统等等都是后话了。<br /> <br /> 以上只是我自己的一些经历，欢迎大家提出意见和建议，同时更欢迎大家把自己的亲身精力写出来，与到家分享。<br />摘自：</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/367318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-12-27 11:27 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/12/27/367318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2012工作计划</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/11/26/364896.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Sat, 26 Nov 2011 13:35:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/11/26/364896.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/364896.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/11/26/364896.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/364896.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/364896.html</trackback:ping><description><![CDATA[<div>  <p><a href="../archive/2011/01/14/342987.html">2012<span style="font-family: 宋体;"><span>工作计划</span></span></a></p>  <p><span style="font-family: 宋体;">工作总结需含概以下内容：</span></p>  <p>1<span style="font-family: 宋体;">、</span>&nbsp;&nbsp; <span style="font-family: 宋体;">简述您上一个年度所具体负责的工作、工作业绩，以及您对自己的工作业绩是否满意；</span></p>  <p>2<span style="font-family: 宋体;">、</span>&nbsp;&nbsp; <span style="font-family: 宋体;">简述您的下一步工作及学习计划，以及您今后的工作目标定位；</span></p>  <p>3<span style="font-family: 宋体;">、</span>&nbsp;&nbsp; <span style="font-family: 宋体;">期望公司及部门改善的地方；</span></p>  <p>&nbsp;</p>  <p>1. <span style="font-family: 宋体;">从事版本管理工作之后，</span>2011<span style="font-family: 宋体;">主要完成如下工作：</span></p>  <p style="margin-left: 10.5pt;">1<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">编写软件配置管理文档：如软件配置管理计划，及软件配置状态报告。</span></p>  <p style="margin-left: 10.5pt;">2<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">根据深圳</span>SCM<span style="font-family: 宋体;">主管的配置管理整理方案，完成对上海各事业部的配置库目录结构的整理及权限文件的整理，提高代码资源的管控。</span></p>  <p style="margin-left: 10.5pt;">3<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">在上海公司使用统一编译服务器，统一项目编译环境，保证代码及时提交入库。</span></p>  <p style="margin-left: 10.5pt;">4<span style="font-family: 宋体;">）</span>. <span style="font-family: 宋体;">推广持续集成，自动编译，提高网关研发同事出版本的效率</span>,<span style="font-family: 宋体;">及代码编译不通过的提醒，自测可以直接从</span>CI<span style="font-family: 宋体;">工具</span>hudson<span style="font-family: 宋体;">中取得，同时保证研发自测版本与测试部版本的一致性；</span> </p>  <p style="margin-left: 10.5pt;">5<span style="font-family: 宋体;">）</span>. <span style="font-family: 宋体;">增加</span>SVN<span style="font-family: 宋体;">密码修改模块，通过自己查找资料，经过环境搭建测试，完成</span>SVN<span style="font-family: 宋体;">密码修改模块，同时统一上海代码服务器的账号文件，清除废弃及重复的账号，避免相同的服务器使用多个账号，避免了混乱麻烦的状况。。</span></p>  <p style="margin-left: 10.5pt;">6<span style="font-family: 宋体;">）</span>. SVN<span style="font-family: 宋体;">服务器备份，使用本地备份及异地备份，全量备份与增量备份相结合的方式，进行代码库数据的备份，避免一旦服务器出现异常导致无法使用带来的巨大损失。</span></p>  <p style="margin-left: 10.5pt;">7<span style="font-family: 宋体;">）</span>. <span style="font-family: 宋体;">深圳同事提交代码出现卡死的情况，针对深圳同事的具体情况，使用账户模拟场景，再现问题，及研究</span>SVN<span style="font-family: 宋体;">触发的脚本，找出问题根源，并测试通过，改善了同事的工作过程。</span></p>  <p style="margin-left: 10.5pt;">8<span style="font-family: 宋体;">）</span>. <span style="font-family: 宋体;">深圳配置管理主管指导交流，提高了我自己对配置管理的认识，同时按照深圳高工给出的配置管理方案对上海代码库进行整理，目前已经完成</span>EOC<span style="font-family: 宋体;">，无线，网关的代码库整理工作，然后我们会严格按照配置管理策略来指导及执行项目的配置管理工作。</span></p>  <p>&nbsp;</p>  <p>2. 2012<span style="font-family: 宋体;">的工作及学习计划如下：</span></p>  <p style="margin-left: 10.5pt;">1<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">策划一组</span>SVN<span style="font-family: 宋体;">系列培训，提供研发同事使用</span>SVN<span style="font-family: 宋体;">的熟练程度。</span></p>  <p style="margin-left: 10.5pt;"><span>&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体;">大致会包括如下的培训内容：</span></p>  <p style="margin-left: 31.5pt;">SVN<span style="font-family: 宋体;">客户端使用；</span></p>  <p style="margin-left: 31.5pt;">SVN<span style="font-family: 宋体;">服务器使用；</span></p>  <p style="margin-left: 31.5pt;">SVN<span style="font-family: 宋体;">常见问题解决方法；</span></p>  <p style="margin-left: 10.5pt;">2<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">精通</span>shell<span style="font-family: 宋体;">，使版本管理工作更高效。</span></p>  <p style="margin-left: 10.5pt;">3<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">努力参与项目，使软件配置管理更加深入项目，做好软件配置管理的本职工作，改善研发过程。</span></p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">按照软件配置管理计划来参与项目，完善软件配置状态报告，及项目基线管理及版本管理；</span></p>  <p style="margin-left: 10.5pt;">4<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">精通</span>SVN<span style="font-family: 宋体;">，提高应对版本库出现的各种问题的解决能力。</span></p>  <p style="margin-left: 10.5pt;">5<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">深入了解软件配置管理思想，在工作中要尽可能的去体会以及应用在工作中。需要多搜集资料，学习别人的经验，同时结合本公司现状，加以应用。力求把上海的配置管理工作做好，做到位。</span></p>  <p style="margin-left: 10.5pt;">6<span style="font-family: 宋体;">）．尝试实现</span>SVN<span style="font-family: 宋体;">二次开发，提高研发过程。</span></p>  <p style="margin-left: 10.5pt;">7<span style="font-family: 宋体;">）</span>.<span style="font-family: 宋体;">开展软件配置管理系统培训，普及软件配置管理知识，培训内容包括：</span></p>  <p style="margin-left: 10.5pt;"><span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SCM</span><span style="font-family: 宋体;">基本概念培训；</span></p>  <p style="margin-left: 10.5pt;"><span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SCM</span><span style="font-family: 宋体;">规范培训；</span></p>  <p style="margin-left: 10.5pt;"><span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SCM</span><span style="font-family: 宋体;">策略培训；</span></p>  <p>&nbsp;</p>  <p>&nbsp;</p>  </div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/364896.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-11-26 21:35 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/11/26/364896.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件产品发布流程-2种说法的分析</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/11/24/364733.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Thu, 24 Nov 2011 07:23:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/11/24/364733.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/364733.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/11/24/364733.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/364733.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/364733.html</trackback:ping><description><![CDATA[<div>  <p>严格按照软件产品发布流程发布软件版本是建立和完善软件产品版本控制，保证软件产品质量的关键过程之一。参与软件产品发布的人员主要是测试负责人和<span>BM（Build Master）。</span></p>  <p>公司软件产品发布的规程如下：</p>  <p>1、 发布准备。<span><br /> </span>发布之前，所有程序<span>freezed由测试人员进行确认测试；</span><span><br /> </span>检查<span>qcs系统内登记的所有bug都已经被fixed，或者遗留的bug不影响系统的使用，如果有严重bug未解决（级别为must fixed）不能发布；</span><span><br /> </span>程序打包前做冒烟测试。</p>  <p>2、 测试负责人编写<span>release产品质量报告进行质量分析和总结。</span></p>  <p>3、 源码、文档入库。<span><br /> </span>源码包括数据库创建脚本（含静态数据）、编译构建脚本和所有源代码；<span><br /> </span>文档包括需求、设计、测试文档，安装手册、使用手册、二次开发手册、产品介绍（<span>ppt）、使用demo等。</span></p>  <p>4、<span>BM进行程序打包；标记源码、文档版本tag。</span></p>  <p>5、<span> BM填写发布基线通知并通知相关人员；BM经理对发布基线进行审计。</span></p>  <p>6、在<span>qcs系统上新建产品发布计划，填写配置项，执行发布计划（发布产品）。</span></p>  <p>7、上传程序包、使用文档至<span>download站点。</span></p>  <p>8、&nbsp;编写发布说明<span>readme.txt（或者release note）。</span><span><br /> </span>Readme的内容应该包括产品版本说明、产品概要介绍、本次发布包含的文件包、文档说明、本次发布包含或者新增的功能特性说明、遗留问题及影响说明、版权声明以及其他需要说明的事项。</p>  <p>9、 正式发布通知。<span><br /> </span>通知开发、测试、市场、销售各相关部门并附上产品发布说明和产品介绍。</p>  <p>10、后续工作。<span><br /> </span>产品发布后，在使用过程中可能还会发现一些<span>bug。在不影响正常使用的情况下，这些bug将在下一版本发布时解决；如果bug严重影响使用，必须打patch或者按照流程重新发布。</span></p>  <p>11、 临时发布。<span><br /> </span>软件产品未正式发布前，可能需要一个临时版本供开发人员或者用户应急使用，这时候需要临时发布一个版本。这个版本只包括基本的程序包和必要的使用说明。临时发布需要通知相关开发、测试人员；<span>BM需要为源码、文档打tag标记。</span><span><br /> <br /> </span>12、 软件产品发布后，即建立了一条发布基线。<span> <br /> </span>所有用户安装及二次开发必须在此基线上进行，开发人员不能直接从<span>cvs或vss上check 代码编译交付用户使用或者进行二次开发。</span></p>  <p><strong><span style="font-family: 宋体; font-weight: normal;"><br /></span></strong></p><p><strong><span style="font-family: 宋体; font-weight: normal;">另一种说法：</span></strong></p>  <p>公司软件产品发布的规程如下：<span><br /> </span>1.FAE首先向版本管理员提交需求<span>;</span><span><br /> </span>2.版本管理员将需求提交给项目经理<span>,由经理确认需求以及发布基线;</span><span><br /> </span>3.发布准备<span>:发布之前，先将当前主干中的所有程序freezed,并从主干中拉出一条发布分支branch,由开发人员对其进行功能测试:检查所有bug是否都已经被fixed，或者遗留的bug不影响软件的使用，如果有严重bug未解决暂时不能发布。</span><span><br /> </span>4.如果测试通过<span>,则由相关开发人员进行程序打包；标记源码、文档版本tag。</span><span><br /> </span>5.开发人员将标记的源码和文档地址交予版本管理员<span>,由版本管理员编写发布说明release list.release list内容应包括本次发布包含的文件包、文档说明;各类文件的存放路径,提供者及tag信息;本次发布包含或者新增的功能特性说明；遗留问题及影响说 明；版权声明以及其他需要说明的事项。</span><span><br /> </span>6.管理员在<span>jira上建立测试任务并邮件通知相关测试人员。</span><span><br /> </span>7.FAE测试<span>,测试完成后，FAE向版本管理员反馈测试结果（确认所提需求是否全部实现，不然则列出哪些功能还存在不足或BUG）:如果测试没有通过， 将由版本管理员向开发组请求重新release内部版本，再交FAE重新测试;如果测试通过，则由版本管理员为当前的版本进行标记和命名,同时提交到发布 库中.</span><span><br /> </span>8.正式发布通知。邮件通知各相关部门并附上产品发布说明和产品介绍。<span><br /> </span>9.由<span>FAE将发布后的版本打包release给客户;</span><span><br /> </span>10.后续工作。产品发布后，在使用过程中可能还会发现一些<span>bug。在不影响正常使用的情况下，这些bug将在下一版本发布时解决；如果bug严重影响使用，必须打patch或者按照流程重新发布。</span><span><br /> </span>11. 临时发布。软件产品未正式发布前，可能需要一个临时版本供开发人员或者用户应急使用，这时候需要临时发布一个版本。这个版本只包括基本的程序包和必要的使用说明。临时发布需要通知相关开发、测试人员；管理员需要为源码、文档打<span>tag标记。</span><span><br /> </span>12. 软件产品发布后，即建立了一条发布基线。所有用户安装及二次开发必须在此基线上进行，开发人员不能直接从<span>svn上check 代码编译交付用户使用或者进行二次开发。</span></p>  <h1>&nbsp;</h1>  <p>&nbsp;</p>  </div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/364733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-11-24 15:23 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/11/24/364733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>版本库迁移（合并）的实现</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/11/15/363790.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Tue, 15 Nov 2011 01:50:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/11/15/363790.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/363790.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/11/15/363790.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/363790.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/363790.html</trackback:ping><description><![CDATA[<div><div id="sina_keyword_ad_area2"> 			<p><strong>一、windows</strong></p> <p>版本库迁移（合并）：指的是将两个独立的、有各自版本信息的版本库合并为一个版本库，并保留被合并的两个库的版本信息。</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 环境：windows+SVN+apache</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 我的版本库路径：E:\svnrepository（即我的版本库是在这个路径下建立的）</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 操作步骤：</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1、在E:\svnrepository下建立两个版本库：local和local1，版本库local是我原先的版本，版本号已经到了25了,此版本库一层目录是liruixuan，二层目录是test；在新建的版本库local1中进行三次提交，增加文件夹ivy，在ivy里面增加文件test.txt，产生三条版本信息，记为test2(1,2,3)；</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 现在把版本库local1根目录下的所有内容（文件夹ivy，还有里面的test.txt）迁移到版本库local的目录liruixuan\test下；</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 2、运行cmd打开命令解释程序，首先输入命令：</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>svnadmin dump E:\svnrepository\local1 &gt;&nbsp;<wbr>&nbsp;<wbr> E:\svnrepository\20091222 ，此命令是将版本库local1的所有内容转储为名叫20091222的文件，当然，这个文件名可以随便；运行结果如下图：</p> <p><span> <img src="http://hiphotos.baidu.com/ivy%5Flee1984/pic/item/67218d355e969f0b5bb5f52f.jpg" alt="版本库迁移（合并）的实现" title="版本库迁移（合并）的实现" border="0" /></span><br /></p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 3、然后输入命令：</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> svnadmin load E:\svnrepository\local --parent-dir liruixuan\test &lt; E:\svnrepository\20091222，此命令是将local1的转储文件2009122读入版本库local的liruixuan\test目录下，参数&#8220;--parent-dir&#8221;是为了指定local下的具体路径，方法就是在&#8220;--parent-dir&#8221;后键入具体路径，这里的测试选择了二级目录liruixuan\test；运行结果如下图：</p> <p><span><img src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" alt="版本库迁移（合并）的实现" title="版本库迁移（合并）的实现" border="0" /></span><br /></p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 4、更新版本库local，你会发现liruixuan\test下面多了个文件夹ivy，里面有个文件test.txt ，查看local的log，会发现原版本库local的版本信息已增加了三个版本，达到了28，新增了版本信息26、27、28，对应的就是原local1的版本信息local1(1、2、3)，但除了Revision号由原来的1、2、3变为26、27、28外，其它没有变化。</p> <p>&nbsp;<wbr></p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 如果你想把迁入的版本库local1里的内容再细致的分到local的不同目录下，干脆直接用命令 svnadmin load E:\svnrepository\local &lt; E:\svnrepository\20091222 把local1的内容迁移到local的根目录下，然后再用TortoiseSVN的版本库浏览器做细致调整，反正版本信息都已经合并在一起了，后面的操作都是在一个版本库下。</p> <p>&nbsp;<wbr></p> <p><strong>二、linux</strong></p> <p>版本库迁移（合并）：指的是将两个独立的、有各自版本信息的版本库合并为一个版本库，并保留被合并的两个库的版本信息。</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 环境：linux+collabnet</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 我的版本库路径：/svn/repositories（即我的版本库是在这个路径下建立的）</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 操作步骤：</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1、在/svn/repositories下 建立两个版本库：first和last，版本库first是我原先的版本，版本号已经到了25了,此版本库一层目录是liruixuan，二层目录是 test；在新建的版本库last中进行三次提交，增加文件夹ivy，在ivy里面增加文件test.txt，产生三条版本信息，记为test2(1,2,3)；</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 现在把版本库last根目录下的所有内容（文件夹ivy，还有里面的test.txt）迁移到版本库first的目录liruixuan/test下；</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 2、输入命令：</p> <p>&nbsp;<wbr>&nbsp;<wbr>svnadmin dump /svn/repositories/last&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><strong>&gt;&nbsp;<wbr>&nbsp;<wbr></strong> /svn/repositories/20091222 ，此命令是将版本库last的所有内容转储为名叫20091222的文件，当然，这个文件名可以随便；运行结果如下图：</p> <p>&nbsp;<wbr>*dumpd revision 0.</p> <p>*dumpd revision 1.</p> <p>........<br /></p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 3、然后输入命令：</p> <p>&nbsp;<wbr>svnadmin load /svn/repositories/first --parent-dir liruixuan/test <strong>&lt;</strong> /svn/repositories/20091222，此命令是将last的转储文件2009122读入版本库first的liruixuan/test目录下，参数&#8220;--parent-dir&#8221;是为了指定first下的具体路径，方法就是在&#8220;--parent-dir&#8221;后键入具体路径，这里的测试选择了二级目录liruixuan/test；运行结果如下图：</p> <p>无图</p> <p><br /></p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 4、更新版本库first，你会发现liruixuan/test下面多了个文件夹ivy，里面有个文件test.txt ，查看first的log，会发现原版本库first的版本信息已增加了三个版本，达到了28，新增了版本信息26、27、28，对应的就是原last的版本信息local1(1、2、3)，但除了Revision号由原来的1、2、3变为26、27、28外，其它没有变化。</p> <p>&nbsp;<wbr></p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 如果你想把迁入的版本库last里的内容再细致的分到first的不同目录下，干脆直接用命令 svnadmin load /svn/repositories/first &lt; /svn/repositories/20091222 把last的内容迁移到first的根目录下，然后再用TortoiseSVN的版本库浏览器做细致调整，反正版本信息都已经合并在一起了，后面的操作都是在一个版本库下。</p>							 		</div></div>原文：<div>http://blog.sina.com.cn/s/blog_5d8165e00100fxd3.html</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/363790.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-11-15 09:50 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/11/15/363790.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RSYNC常见问题 </title><link>http://www.blogjava.net/jasmine214--love/archive/2011/10/28/362222.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 28 Oct 2011 02:22:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/10/28/362222.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/362222.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/10/28/362222.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/362222.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/362222.html</trackback:ping><description><![CDATA[<div><p>问题一：</p><p><span style="color: #ff0000;">@ERROR: chroot failed</span></p><p><span style="color: #ff0000;">rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]</span></p><p>原因：</p><p><span style="color: #0055ff;">服务器端的目录不存在或无权限。创建目录并修正权限可解决问题。</span></p><p>&nbsp;</p><p>问题二：</p><p><span style="color: #ff0000;">@ERROR: auth failed on module tee</span></p><p><span style="color: #ff0000;">rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]</span></p><p>原因：</p><p><span style="color: #0055ff;">服务器端该模块（tee）需要验证用户名密码，但客户端没有提供正确的用户名密码，认证失败。提供正确的用户名密码解决此问题。</span></p><p>&nbsp;</p><p>问题三：</p><p><span style="color: #ff0000;">@ERROR: Unknown module &#8216;tee_nonexists&#8217;</span></p><p><span style="color: #ff0000;">rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]</span></p><p>原因：</p><p><span style="color: #0055ff;">服务器不存在指定模块。提供正确的模块名或在服务器端修改成你要的模块以解决问题。</span></p><p>&nbsp;</p><p>问题四：</p><p><span style="color: #ff0000;">password file must not be other-accessible</span></p><p><span style="color: #ff0000;">continuing without password file</span></p><p><span style="color: #ff0000;">Password:</span></p><p>原因：</p><p><span style="color: #0055ff;">这是因为rsyncd.pwd rsyncd.secrets的权限不对，应该设置为600。如：chmod 600 rsyncd.pwd</span></p><p>&nbsp;</p><p>问题五：</p><p><span style="color: #ff0000;">rsync: failed to connect to 218.107.243.2: No route to host (113)</span></p><p><span style="color: #ff0000;">rsync error: error in socket IO (code 10) at clientserver.c(104) [receiver=2.6.9]</span></p><p>原因：</p><p><span style="color: #0055ff;">对方没开机、防火墙阻挡、通过的网络上有防火墙阻挡，都有可能。关闭防火墙，其实就是把tcp udp的873端口打开。</span></p><p>&nbsp;</p><p>问题六：</p><p><span style="color: #ff0000;">rsync error: error starting client-server protocol (code 5) at main.c(1524) [Receiver=3.0.7]</span></p><p>原因：</p><p><span style="color: #0055ff;">/etc/rsyncd.conf配置文件内容有错误。请正确核对配置文件。</span></p><p>&nbsp;</p><p>问题七：</p><p><span style="color: #ff0000;">rsync: chown "" failed: Invalid argument (22)</span></p><p>原因：</p><p><span style="color: #0055ff;">权限无法复制。去掉同步权限的参数即可。(这种情况多见于Linux向Windows的时候)</span></p></div>原文：<div>http://hi.baidu.com/_k_morisato_/blog/item/a54b0ffb1dab3c9f9e5146ae.html</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/362222.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-10-28 10:22 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/10/28/362222.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下subversion分支合并-专题培训</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/09/19/359022.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Mon, 19 Sep 2011 13:29:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/09/19/359022.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/359022.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/09/19/359022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/359022.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/359022.html</trackback:ping><description><![CDATA[http://www.subversion.org.cn/svnbook/1.4/svn.branchmerge.commonuses.html<br /><div>http://www.vevepay.com/blog/?p=786</div><div>http://www.subversion.org.cn/svnbook/1.4/svn.branchmerge.commonuses.html</div><div>http://panweizeng.com/svn-branching-merging.html</div><br /><div><div><h1>Linux下subversion分支合并</h1></div><div clearfix=""><p>将svn的分支合并到主干的操作不是很麻烦，但是网上的文章大部分都写的比较复杂，而且抄来抄去，今天有同事问我怎么合并，在这里我顺便把步骤写下来吧，假设分支名称为：projectA/20110826，现在要合并到trunk上，步骤如下：</p><p>1）查询该分支创建时revision（在输出的最后一行，比如：1447）；<br />svn log &#8211;verbose &#8211;stop-on-copy http://192.168.x.x/svnrepos/project/branches/projectA/20110826</p><p>2）可以先演练一遍，看看有哪些冲突（HEAD表示trunk中的最新的revision）；<br />svn merge &#8211;dry-run -r1447:HEAD http://192.168.x.x/svnrepos/project/branches/projectA/20110826</p><p>3）觉得没什么大问题，可以开始正式合并了；<br />svn merge -r1447:HEAD http://192.168.x.x/svnrepos/project/branches/projectA/20110826</p><p>4）解决冲突，然后提交，合并完成。<br />svn commit -m &#8220;merge the branch projectA/20110826 to the trunk&#8221; .</p></div></div> <img src ="http://www.blogjava.net/jasmine214--love/aggbug/359022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-09-19 21:29 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/09/19/359022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git资料</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/09/15/358696.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Thu, 15 Sep 2011 06:27:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/09/15/358696.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/358696.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/09/15/358696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/358696.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/358696.html</trackback:ping><description><![CDATA[<div><div>http://www.linuxsir.org/main/doc/git/gittutorcn.htm</div><br />http://phoenixtoday.blogbus.com/logs/33458940.html</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/358696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-09-15 14:27 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/09/15/358696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCM相关术语了解</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/09/13/358509.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Tue, 13 Sep 2011 01:52:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/09/13/358509.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/358509.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/09/13/358509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/358509.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/358509.html</trackback:ping><description><![CDATA[<p>1) <span style="font-family: 宋体;">基线：</span></p>  <p><span style="font-family: 宋体;">代表多个源代码文件的一组版本。</span><span> <br /> </span><span style="font-family: 宋体;">比如有三个文件，</span>aaa.c<span style="font-family: 宋体;">、</span>bbb.c<span style="font-family: 宋体;">和</span>ccc.h<span style="font-family: 宋体;">。可以对这三个文件做一个基线，取</span>aaa.c<span style="font-family: 宋体;">的版本</span>1.1<span style="font-family: 宋体;">，取</span>bbb.c<span style="font-family: 宋体;">的版本</span>1.3<span style="font-family: 宋体;">，取</span>ccc.h<span style="font-family: 宋体;">的版本</span>1.0<span style="font-family: 宋体;">。</span>(1.1,1.3,1.0)<span style="font-family: 宋体;">就是一个基线。换</span><span><br /> </span><span style="font-family: 宋体;">句话说，通常在</span>vss<span style="font-family: 宋体;">和</span>cvs<span style="font-family: 宋体;">里面做</span>label<span style="font-family: 宋体;">，就是在做基线。</span></p>  <p>&nbsp;</p>  <p>2) <span style="font-family: 宋体;">基线提升：</span></p>  <p><span style="font-family: 宋体;">一个文档如果经过讨论被通过了，被固定了，就可以说这个文档被</span>&#8220;<span style="font-family: 宋体;">基线化</span>&#8221;<span style="font-family: 宋体;">了，然后所有人就可以在这个</span>&#8220;<span style="font-family: 宋体;">基线</span>&#8221;<span style="font-family: 宋体;">的基础上工作。</span><span> <br /> <br /> </span><span style="font-family: 宋体;">当然，文档不可能一成不变，所以当对文档的修改仍然会不断进行，但这种修改并不会随时随地的添加到被</span>&#8220;<span style="font-family: 宋体;">基线化</span>&#8221;<span style="font-family: 宋体;">了的文档中去。因为既然是</span>&#8220;<span style="font-family: 宋体;">基线</span>&#8221;<span style="font-family: 宋体;">，就不能随便动。</span><span> <br /> <br /> </span><span style="font-family: 宋体;">但是到了一定时候，修改积累到一定程度，就需要把很多修改合并到原来的文档中去了，并生成一个新版本的文档作为团队中所有的人的参考标准，并把老的版本淘汰掉。这就叫做</span>&#8220;<span style="font-family: 宋体;">基线提升</span>&#8221;<span style="font-family: 宋体;">。</span></p>  <p>&nbsp;</p>  <p>4<span style="font-family: 宋体;">）发行基线</span><span><br /> </span><span style="font-family: 宋体;">你会对你要发行的代码，文档版本进行</span>label, <span style="font-family: 宋体;">比如</span><span>Release2.2,<br /> </span><span style="font-family: 宋体;">这样，你可以随时取出此版本作</span>build<span style="font-family: 宋体;">，进行测试，发布。</span><span><br /> <br /> 5</span><span style="font-family: 宋体;">）产品基线</span><span><br /> </span><span style="font-family: 宋体;">当发布时，你会对产品中所有的配置项进行</span>label,<span style="font-family: 宋体;">包括可执行命令，文档手册，库文件。。。</span></p>  <p>&nbsp;</p>  <p>8) <span style="font-family: 宋体;">基线</span>(Baseline)<span style="font-family: 宋体;">说起</span>. <span style="font-family: 宋体;">基线是软件文档或源码</span>(<span style="font-family: 宋体;">或其它产出物</span>)<span style="font-family: 宋体;">的一个稳定版本</span>,<span style="font-family: 宋体;">它是进一步开发的基础</span>.<span style="font-family: 宋体;">所以</span>,<span style="font-family: 宋体;">当基线形成后</span>,<span style="font-family: 宋体;">项目负责</span>SCM<span style="font-family: 宋体;">的人需要通知相关人员基线已经形成</span>,<span style="font-family: 宋体;">并</span> <span style="font-family: 宋体;">且哪儿可以找到这基线了的版本</span>.<span style="font-family: 宋体;">这个过程可被认为内部的发布</span>.<span style="font-family: 宋体;">至于对外的正式发布</span>,<span style="font-family: 宋体;">更是应当从基线了的版本中发布</span><span>. <br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">基线是项目储存库中每个工件版本在特定时期的一个</span>&#8220;<span style="font-family: 宋体;">快照</span>&#8221;<span style="font-family: 宋体;">。它提供一个正式标准，随后的工作基于此标准，并且只有经过授权后才能变更这个标准。建立一个初始基线后，以后每次对其进行的变更都将记录为一个差值，直到建成下一个基线。</span><span><br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">参与项目的开发人员将基线所代表的各版本的目录和文件填入他们的工作区。随着工作的进展，基线将合并自从上次建立基线以来开发人员已经交付的工作。变更</span> <span style="font-family: 宋体;">一旦并入基线，开发人员就采用新的基线，以与项目中的变更保持同步。调整基线将把集成工作区中的文件并入开发工作区。</span><span><br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">建立基线的三大原因是：重现性、可追踪性和报告。</span><span><br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">重现性是指及时返回并重新生成软件系统给定发布版的能力，或者是在项目中的早些时候重新生成开发环境的能力。可追踪性建立项目工件之间的前后继承关系。</span> <span style="font-family: 宋体;">其目的在于确保设计满足要求、代码实施设计以及用正确代码编译可执行文件。报告来源于一个基线内容同另一个基线内容的比较。基线比较有助于调试并生成发布</span> <span style="font-family: 宋体;">说明。</span><span><br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">建立基线后，需要标注所有组成构件和基线，以便能够对其进行识别和重新建立。</span><span><br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">建立基线有以下几个优点：</span><span><br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">基线为开发工件提供了一个定点和快照。</span><span> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">新项目可以从基线提供的定点之中建立。作为一个单独分支，新项目将与随后对原始项目（在主要分支上）所进行的变更进行隔离。</span><span> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">各开发人员可以将建有基线的构件作为他在隔离的私有工作区中进行更新的基础。</span><span> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">当认为更新不稳定或不可信时，基线为团队提供一种取消变更的方法。</span><span> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">您可以利用基线重新建立基于某个特定发布版本的配置，这样也可以重现已报告的错误。</span><span> <br /> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">使用</span> <span><br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">定期建立基线以确保各开发人员的工作保持同步。但是，在项目过程中，应该在每次迭代结束点（次要里程碑），以及与生命周期各阶段结束点相关联的主要里程碑处定期建立基线：</span><span><br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">生命周期目标里程碑（先启阶段）</span><span> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">生命周期构架里程碑（精化阶段）</span><span> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">初始操作性能里程碑（构建阶段）</span><span> <br /> &nbsp; &nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体;">产品发布里程碑（产品化阶段）</span></p>  <div style="border-width: medium medium 3pt; border-style: none none dotted; border-color: -moz-use-text-color -moz-use-text-color windowtext; padding: 0cm 0cm 1pt;">  <p style="border: medium none; padding: 0cm;">&nbsp;</p>  </div>  <h2><span style="font-size: 7pt; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp; </span>区别对待缺陷和新增功能</h2>  <p><span style="font-size: 10pt;">通过进一步了解我们发现紧急的变更一般是指影响系统正常使用的软件缺陷，这些缺陷需要及时的修 复；而新增功能请求一般不是那么紧急的，允许开发团队有一段时间来开发实现。但开发人员目前是把所有紧急和非紧急的变更请求混杂在一起实现的，往往是一个 紧急的缺陷已经修复，但另外一个正在开发中的新增功能也修改了同一组文件版本，造成两者之间的版本依赖，从而导致紧急的缺陷修复不能按时提交。</span></p>  <p><span style="font-size: 10pt;">我们建议把缺陷的修复工作和新增功能的开发工作区分开来，这就涉及到多个版本的并行开发，开发团队主要面临以下三个版本的开发：</span></p>  <p><span style="font-size: 10pt; font-family: Wingdings;">&#216;</span><span style="font-size: 7pt; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">v1.0</span><span style="font-size: 10pt;">中的缺陷修复</span></p>  <p><span style="font-size: 10pt; font-family: Wingdings;">&#216;</span><span style="font-size: 7pt; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">v1.0</span><span style="font-size: 10pt;">的新增功能版本</span><span style="font-size: 10pt;">v1.1</span></p>  <p><span style="font-size: 10pt; font-family: Wingdings;">&#216;</span><span style="font-size: 7pt; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">下一个版本</span><span style="font-size: 10pt;">v2.0</span></p>  <p><span style="font-size: 10pt;">***********************************************************************************</span></p>  <h2>发布版本构建(build)而不是源代码</h2>  <p><span style="font-size: 10pt;">这样缺陷修复和新增功能开发相互独立，保证紧急的缺陷修复不会受到新增功能的影响。</span></p>  <div style="border-width: medium medium 3pt; border-style: none none dotted; border-color: -moz-use-text-color -moz-use-text-color windowtext; padding: 0cm 0cm 1pt;">  <p style="border: medium none; padding: 0cm;"><span style="font-size: 10pt; font-family: 宋体;">由于软件构建的结果很可能会受构建平台及相应编译器版本所影响，最终在生产系统上的运行代码</span><span style="font-size: 10pt;">(</span><span style="font-size: 10pt; font-family: 宋体;">在生产系统上构建得到</span><span style="font-size: 10pt;">)</span><span style="font-size: 10pt; font-family: 宋体;">与准生产环境上的运行代码</span><span style="font-size: 10pt;">(</span><span style="font-size: 10pt; font-family: 宋体;">在准生产环境上构建得到</span><span style="font-size: 10pt;">)</span><span style="font-size: 10pt; font-family: 宋体;">可能不完全一致，有可能造成质量隐患。<span style="color: red;">比较通行的做法是所有平台上运行的构建代码应该只在构建服务器上生成一次，一次编译到处运行，这样才能保证各个平台上所用到的同版本运行代码是同一次构建的产物。</span></span></p>  </div>  <h2><span style="font-size: 7pt; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp; </span>版本发布管理</h2>  <p><span style="font-size: 10pt;">对于所发布的构建版本，我们也需要进行有序的管理，可以用版本号来唯一标识每一个发布版本。一 般可以把用于开发团队内部系统测试的称之为内部发布版本，把提交给客户的称之为外部发布版本，这两种软件发布版本都要统一编号管理。在我们的例子中，内部 发布版本可以简单地用构建号来表示，如：</span></p>  <p><span style="font-size: 10pt;">v1.0_build_008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">表示版本</span><span style="font-size: 10pt;">v1.0</span><span style="font-size: 10pt;">开发过程中生成的第</span><span style="font-size: 10pt;">8</span><span style="font-size: 10pt;">次构建外部发布版本可以由版本号和发布号组合而成，如：</span></p>  <p><span style="font-size: 10pt;">v1.0_rel01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">表示版本</span><span style="font-size: 10pt;">v1.0</span><span style="font-size: 10pt;">的第一个外部发布版本</span></p>  <p><span style="font-size: 10pt;">对于</span><span style="font-size: 10pt;">v1.0</span><span style="font-size: 10pt;">中的缺陷修复，我们可以通过补丁的方式来发布，一个补丁中可以包含有多个缺陷修复，被修复的缺陷需要在补丁的发布说明</span><span style="font-size: 10pt;">(Release Notes)</span><span style="font-size: 10pt;">中写明，补丁名称可以由版本号、发布号和补丁号组合而成，如：</span></p>  <p><span style="font-size: 10pt;">v1.0_rel01_p001&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">表示针对发布版本</span><span style="font-size: 10pt;">v1.0_rel01</span><span style="font-size: 10pt;">的第</span><span style="font-size: 10pt;">001</span><span style="font-size: 10pt;">号补丁</span></p>  <p><span style="font-size: 10pt;">对于</span><span style="font-size: 10pt;">v1.0</span><span style="font-size: 10pt;">中新增功能，我们需要制定一个发布计划，根据客户新增功能请求的紧急程度来分期分批实现，一次发布中可以包含多个新增功能，并且包括所有已改正的软件缺陷，这些改动都必须在发布说明中写明，发布版本号可以在前一个发布版本的基础上递增，如：</span></p>  <p><span style="font-size: 10pt;">v1.1_rel02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">表示版本</span><span style="font-size: 10pt;">v1.1</span><span style="font-size: 10pt;">的第二个外部发布版本</span></p>  <p><span style="font-size: 10pt;">对于下一个版本</span><span style="font-size: 10pt;">v2.0</span><span style="font-size: 10pt;">的开发，则与版本</span><span style="font-size: 10pt;">v1.0</span><span style="font-size: 10pt;">开发的发布管理完全一致，如：</span></p>  <p><span style="font-size: 10pt;">v2.0_build_002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt;">表示版本</span><span style="font-size: 10pt;">v2.0</span><span style="font-size: 10pt;">开发过程中生成的第</span><span style="font-size: 10pt;">2</span><span style="font-size: 10pt;">次构建</span></p>  <p>&nbsp;</p>  <p><span style="font-size: 10pt;">在版本发布管理的流程中，发布版本的安装应该由专门的角色负责，可以是配置管理员或者是集成员</span><span style="font-size: 10pt;">(integrator)</span><span style="font-size: 10pt;">；开发人员被禁止向各平台（测试平台、准生产环境、生产系统）上安装任何软件，并且各平台上所安装软件的版本号</span><span style="font-size: 10pt; display: none;">.0.0 Notes 11</span><span style="font-size: 10pt;">都应该有详细的记录。当软件缺陷被发现时，我们就可以明确知道问题究竟是出在哪一个版本。</span></p>  <p><span style="font-size: 10pt;">内部发布版本只会被安装到测试平台上，经过 &#8220;开发 </span><span style="font-size: 10pt; font-family: Wingdings;">&#224;</span> <span style="font-size: 10pt;">构建 </span><span style="font-size: 10pt; font-family: Wingdings;">&#224;</span><span style="font-size: 10pt;"> </span><span style="font-size: 10pt;">测试 </span><span style="font-size: 10pt; font-family: Wingdings;">&#224;</span> <span style="font-size: 10pt;">发现缺陷</span><span style="font-size: 10pt; font-family: Wingdings;">&#224;</span> <span style="font-size: 10pt;">修改代码&#8221; 的多次循环之后，内部发布版本的质量趋于稳定，开发团队才会决定做一个外部发布版本。</span></p>  <p><span style="font-size: 10pt;">外部发布版本被安装到准生产环境上，并且只有通过用户验收测试，它才可以被安装到生产系统上 去。如果该版本没有通过用户验收测试，那么开发团队需要提供相应的补丁来解决用户验收中发现的问题，直到通过用户验收后再将该发布版本及其所有的累积补丁 全部安装到生产系统上去。有些情况下，最终通过验收测试的也可能是下一个发布版本，所以生产系统上安装的发布版本前后之间不一定是连续的，中间可能跳过一 些质量不够成熟的版本。</span></p>  <p><span style="font-size: 10pt;">同样的，只有通过用户验收测试的补丁才会被最终安装到生产系统上去。紧急的补丁经过用户验收测试之后会马上安装到生产系统上，不紧急的补丁可以累积几个以后批量安装上去。</span></p>  <p>&nbsp;</p><img src ="http://www.blogjava.net/jasmine214--love/aggbug/358509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-09-13 09:52 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/09/13/358509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基线的概念-------权威</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/09/09/358359.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 09 Sep 2011 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/09/09/358359.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/358359.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/09/09/358359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/358359.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/358359.html</trackback:ping><description><![CDATA[<div><h5>主题</h5> <ul><li><a href="http://ir.hit.edu.cn/%7Ecar/programming/rup/process/workflow/conf_mgt/co_basel.htm#Definition">定义</a></li><li><a href="http://ir.hit.edu.cn/%7Ecar/programming/rup/process/workflow/conf_mgt/co_basel.htm#Explanation">解释</a></li><li><a href="http://ir.hit.edu.cn/%7Ecar/programming/rup/process/workflow/conf_mgt/co_basel.htm#Use">使用</a></li></ul> <h3><a name="XE_基线__定义"></a><a name="Definition">定义</a> <a href="http://ir.hit.edu.cn/%7Ecar/programming/rup/process/workflow/conf_mgt/co_basel.htm#Top"><img src="http://ir.hit.edu.cn/%7Ecar/programming/rup/images/top.gif" alt="返回页首" width="26" border="0" height="20" /></a></h3> <p>基线是项目储存库中每个工件版本在特定时期的一个&#8220;快照&#8221;。它提供一个正式标准，随后的工作基于此标准，并且只有经过授权后才能变更这个标准。建立一个初始基线后，以后每次对其进行的变更都将记录为一个差值，直到建成下一个基线。&nbsp;</p> <p>参与项目的开发人员将基线所代表的各版本的目录和文件填入他们的工作区。随着工作的进展，基线将合并自从上次建立基线以来开发人员已经交付的工作。变更一旦并入基线，开发人员就采用新的基线，以与项目中的变更保持同步。调整基线将把集成工作区中的文件并入开发工作区。</p> <h3><a name="Explanation">解释</a> <a href="http://ir.hit.edu.cn/%7Ecar/programming/rup/process/workflow/conf_mgt/co_basel.htm#Top"><img src="http://ir.hit.edu.cn/%7Ecar/programming/rup/images/top.gif" alt="返回页首" width="26" border="0" height="20" /></a></h3> <p>建立基线的三大原因是：重现性、可追踪性和报告。</p> <p>重现性是指及时返回并重新生成软件系统给定发布版的能力，或者是在项目中的早些时候重新生成开发环境的能力。可追踪性建立项目工件之间的前后继承关 系。其目的在于确保设计满足要求、代码实施设计以及用正确代码编译可执行文件。报告来源于一个基线内容同另一个基线内容的比较。基线比较有助于调试并生成 发布说明。</p> <p>建立基线后，需要标注所有组成构件和基线，以便能够对其进行识别和重新建立。</p> <p><a name="XE_基线__建立基线的优点"></a>建立基线有以下几个优点：</p> <ul><li>基线为开发工件提供了一个定点和快照。</li><li>新项目可以从基线提供的定点之中建立。作为一个单独分支，新项目将与随后对原始项目（在主要分支上）所进行的变更进行隔离。</li><li>各开发人员可以将建有基线的构件作为他在隔离的私有工作区中进行更新的基础。</li><li>当认为更新不稳定或不可信时，基线为团队提供一种取消变更的方法。</li><li>您可以利用基线重新建立基于某个特定发布版本的配置，这样也可以重现已报告的错误。</li></ul> <h3><a name="Use">使用</a> <a href="http://ir.hit.edu.cn/%7Ecar/programming/rup/process/workflow/conf_mgt/co_basel.htm#Top"><img src="http://ir.hit.edu.cn/%7Ecar/programming/rup/images/top.gif" alt="返回页首" width="26" border="0" height="20" /></a></h3> <p><a name="XE_基线__何时建立？"></a>定期建立基线以确保各开发人员的工作保持同步。但是，在项目过程中，应该在每次迭代结束点（次要里程碑），以及与生命周期各阶段结束点相关联的主要里程碑处定期建立基线：</p> <ul><li>生命周期目标里程碑（先启阶段）</li><li>生命周期构架里程碑（精化阶段）</li><li>初始操作性能里程碑（构建阶段）</li><li>产品发布里程碑（产品化阶段）</li></ul></div><br />原文：<div>http://ir.hit.edu.cn/~car/programming/rup/process/workflow/conf_mgt/co_basel.htm#Top</div><div>http://ir.hit.edu.cn/~car/programming/rup/process/workflow/conf_mgt/co_basel.htm#Top</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/358359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-09-09 11:51 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/09/09/358359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】持续集成工具</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/08/17/356730.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Wed, 17 Aug 2011 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/08/17/356730.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/356730.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/08/17/356730.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/356730.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/356730.html</trackback:ping><description><![CDATA[<div><p>引言</p> <p>Thomas  Carlyle说：&#8220;人类是使用工具的动物。没有工具，人什么都不是；有了工具，人无所不能。&#8221;金融家们创造了复杂的金融工具，并利用这些工具制造了财富 神话，制造了著名的跨国公司，也制造了世界范围的危机。软件精英们为了让自己的工作效率更高，有更多时间去做想做的事，也创造了各式各样的工具。持续集成 已经不是一个新概念，在这个概念发展的十多年间，出现了支持这一概念的众多工具。这些工具的组合使用，为软件开发提供了强大的支持。</p> <p>持续集成工具的分类和功能</p> <p>一般来说，持续集成工具可以分成两大类：自动化构建工具和构建计划安排工具。</p> <p>自动化构建工具有这样一些基本功能：代码编译、组件打包、程序执行和文件操作。编译源代码是构建的主要工作之一，为了提高效率，编译应该根据相应的 源代码是否发生改变而有条件地执行。组件打包是将编译的结果和其他需要包含的文件组织在一起，形成可以部署的组件。构建工具应该知道何时需要重新打包。程 序执行是指构建工具能够在它支持的平台上，调用所有提供命令行接口的程序。构建工具应该支持创建、拷贝、删除文件和目录等操作。</p> <p>某些自动化构建工具还有一些扩展功能：执行开发者测试、版本控制工具集成、文档集成、部署功能、代码品质分析、支持扩展、多平台构建、加速构建。虽 然构建工具可以通过命令行执行的方式来集成构建工具和测试工具，但如果它提供更直接的集成方式，开发者就更省力。同样，如果构建工具能够直接与版本控制工 具集成，开发者也会觉得更方便。文档集成是指构建工具能够自动从源代码中抽取并生成API文档。构建工具还可以将打包好的组件自动部署到目标测试环境中 去。构建工具一般通过一些第三方插件，支持对代码品质进行分析。而提供插件接口，是构建工具实现可扩展性的通用方式。如果您开发的软件需要在多个平台上构 建并测试，那么构建工具对多平台的支持就会带来极大的方便。对于较大的代码集，一次构建可能需要好几个小时，这为持续集成带来了一些挑战。有的构建工具支 持加速构建，即在多个构建服务器的多个处理器上进行分布式构建。</p> <p>常见的自动化构建工具包括Ant、NAnt、MSBuild、make、Maven、Rake等。</p> <p>构建计划安排工具有这样一些基本功能：构建执行、版本控制集成、构建工具集成、提供反馈、为构建打上标签。构建计划安排工具的核心功能就是在特定时 间执行自动化的构建，这可以通过轮询版本控制库、计划驱动或事件通知等方式来实现。大部分构建计划安排工具都支持大多数流行的版本控制系统，也支持大多数 流行的构建工具。构建计划安排工具至少支持通过电子邮件提供反馈信息，有一些工具可以通过即时消息、手机短信或其他设备来提供反馈。大多数构建计划安排工 具会提供某种类型的升序计数，作为构建版本的标签。</p> <p>某些构建计划安排工具还有一些扩展功能：支持项目间依赖关系、提供用户界面、制品发布、安全。如果项目间存在依赖关系，您可能希望在被依赖的项目重 新构建时，重新构建依赖于它的项目。设计良好的用户界面会在工作时为您节约时间。制品发布是指除了得到可部署的组件之外，一些成熟的某些构建计划安排工具 可以将文档、测试结果、品质分析结构和其他测量指标数据格式化，便于查看。有一些工具提供了身份认证和授权等安全方面的功能，允许您指定谁能查看结果和修 改配置。</p> <p>常见的构建计划安排工具包括AnthillPro、Continuum、CruiseControl、CruiseControl.NET、Draco.NET、Luntbuild、Hudson等。</p> <p>下面介绍两个颇具代表性的工具：Ant和Hudson。</p> <p>Ant</p> <p>Ant是Java构建工具的事实标准，一般建议，不论项目团队成员使用哪种集成开发环境，项目都要有一个可以脱离IDE执行的Ant脚本。Ant采用插件式的设计结构，通过不同的插件来实现各种任务，其任务分类如表1所示。</p> <p>Archive Tasks<br />&nbsp;打包解包任务，支持的格式包括：BZip2、Cab、Ear、GZip、Jar、Rpm、Tar、War、Zip。<br />&nbsp;<br />Audit/Coverage Tasks<br />&nbsp;JDepend任务，调用JDepend实现代码静态分析，针对每个Java包生成设计品质指标数据。<br />&nbsp;<br />Compile Tasks<br />&nbsp;编译任务，实现对Java、JSP、NetRexx等源文件的编译。<br />&nbsp;<br />Deployment Tasks<br />&nbsp;部署任务，实现在JavaEE服务器上热部署。<br />&nbsp;<br />Documentation Tasks<br />&nbsp;文档生成任务，生成javadoc文档、Apache Stylebook文档。<br />&nbsp;<br />EJB Tasks<br />&nbsp;EJB任务，提供对1.x和2.x的EJB的支持，并支持不同供应商的应用服务器。<br />&nbsp;<br />Execution Tasks<br />&nbsp;执行任务，包括对子项目调用Ant、调用同一脚本中的另一个target、执行系统提供的命令行程序、执行Java程序、暂停和并行同步执行等功能。<br />&nbsp;<br />File Tasks<br />&nbsp;文件任务，实现对文件和目录的操作。<br />&nbsp;<br />Java2 Extensions Tasks<br />&nbsp;Java2 扩展信息任务，对jar包中的版本、供应商等扩展信息进行检查和操作。<br />&nbsp;<br />Logging Tasks<br />&nbsp;日志任务，将构建过程事件记录到文件中。<br />&nbsp;<br />Mail Tasks<br />&nbsp;邮件任务，发送SMTP邮件。<br />&nbsp;<br />Miscellaneous Tasks<br />&nbsp;其他任务，各种或许会用到的小任务，例如播放wav文件。<br />&nbsp;<br />.NET Tasks<br />&nbsp;.NET任务，支持执行.NET程序、执行NUnit测试、调用NAnt、调用MSBuild、调用WiX工具。<br />&nbsp;<br />Pre-process Tasks<br />&nbsp;预处理任务，实现编译之前的一些预处理。例如调用ANTLR、JavaCC、Native2Ascii等程序。<br />&nbsp;<br />Property Tasks<br />&nbsp;属性任务，对脚本中的属性变量进行判断和操作。<br />&nbsp;<br />Remote Tasks<br />&nbsp;远程任务，支持FTP、Rexec、Scp、SSH和Telnet。<br />&nbsp;<br />SCM Tasks<br />&nbsp;SCM任务，支持各种配置管理（版本控制）软件，包括CVS、ClearCase、Continuus、Visual SourceSafe、Perforce、PVCS、SourceOffSite和StarTeam。<br />&nbsp;<br />Testing Tasks<br />&nbsp;测试任务，支持执行JUnit测试。<br />&nbsp;<br />表1. Ant任务分类</p> <p>以上介绍的只是Ant发行版所带的一些任务。由于Ant采用的是插件结构，所以开发者可以开发自己需要的Ant任务，支持各种工具，如FindBugs、TestNG等其他代码检查工具和测试工具。早期的Ant没有很好的依赖关系支持，后来则通过Ivy弥补了这一缺点。</p> <p>关键是Ant为我们提供了一个跨平台的Java构建工具，为持续集成提供了根本的支持。对于Java开发者来说，如果不想采用Ant，也可以考虑采用Maven。</p> <p>Hudson</p> <p>Hudson是一个开放源代码的CI服务器，受到世界各地各种规模和类型的开发团队的欢迎。关键是因为它非常易于安装和使用，提供了灵活的配置方式和复杂的功能，同时支持Java项目和非Java项目，由强大的Hudson社区提供技术支持。</p> <p>简而言之，Hudson不仅仅是一个CI服务器，它的可扩展架构使它不仅是一个构建管理系统，也成为一个通用的开发生命周期管理系统，让开发者能够完成提升基线、打标签、执行工作流、根据依赖关系追踪变更、监视并图示测试结果、查看代码覆盖率和违反编码标准的情况等任务。</p> <p>Hudson是最活跃，成长最快的开源社区之一，目前每周下载达4000次，有超过2万个在工作的安装实例。它的开发者超过160人，贡献的工作量超过137人年，目前已发布了超过300个发行版本。Hudson实际上是现在世界上最受欢迎的开源CI服务器。</p> <p>图1是Apache软件基金会运行Hudson的屏幕截图，您可以在<a href="http://wiki.hudson-ci.org/display/HUDSON/Meet+Hudson">http://wiki.hudson-ci.org/display/HUDSON/Meet+Hudson</a> 看到更多Hudson的使用案例。</p> <p>图1. Apache运行的Hudson</p> <p>Huddon的主要优点包括：</p> <p>易于安装。只要执行&#8220;java &#8211;jar hudson.war&#8221;，或者将hudson.war部署到应用服务器上就可以了，不需要其他的安装工作，也不需要建立数据库。 <br />易于配置。所有东西都通过Web GUI界面来配置，不需要手工修改XML文件。 <br />支持分布式构建。Hudson支持将构建和测试负载分布到多台机器上，图2是Apache采用Hudson的分布式构建功能。 <br />支持环境配置矩阵。Hudson支持在不同的环境配置下执行相同的任务，例如不同的JDK版本、不同的操作系统、不同的数据库。执行的结果可以汇总在一起。 <br />支持JUnit/TestNG测试报告。测试的结果可以分标签列出、汇总，并与历史信息一同显示。历史趋势可以显示在图中。 <br />追踪依赖关系。Hudson追踪记录哪次构建生成了哪些jar，某次构建使用了哪些版本的jar，即使这些jar包来自于外部也可以。 </p> <p>图2. Hudson支持的分布式构建</p> <p>Hudson通过大量的插件来实现其丰富的功能，这些插件大致可以分为以下几类：</p> <p>SCM。Hudson缺省支持CVS和Subversion，通过安装插件支持Accurev、Bitkeeper、ClearCase、Git、Mercurial、Perforce、StarTeam、Synergy等 <br />构建触发器。可以通过IRC、Ivy、Jabber、Join、Locks and Latches、Navigator来触发执行构建。 <br />构 建工具。缺省支持Ant、Maven、shell s和Windows 批处理命令，通过安装插件支持batch  tasks、Gant、Gradle、Grails、Groovy、Jython、Kundo、MSBuild、Phing、Powershell、 Python、Rake、Ruby、SCons、SCTMExecutor,Selenium等。 <br />构建包装。对构建的方式进行一些控制，如并发 同步、启停虚拟机等。包括Hudson Centralized Job Action、Hudson Distributed Workspace  Clean、Locks and Latches、M2 Extra Steps、M2  Release、Release、VMware、Xvnc、Zen Timestamp等。 <br />构建通知。缺省支持电子邮件通知，通过插件支持 Campfire、Google Calendar、HudsonTracker (RSS  feeds)、IRC、Jabber、Nabaztag、SameTime、Status Monitor、The new  Emailer、TuxDroid、Twitter等。 <br />Slave启动和控制。缺省支持JNLP和命令行，通过插件支持SSH。 <br />构建 报告。缺省支持JUnit、javadoc和FindBugs，通过插件支持CCCC、Checkstyle、Clover、DRY、Emma、 Gallio、Gnat、Grinder、Japaex、JavaNCS、JavaTest Report、MSTest、N  Cover、NUint、Plot、PMD、PureCoverage、Ruby metrics、Selenium AES、Selenium  hq、Serenitec、SLOCCount、Task Scanner、Testability  Explorer、Violations、Warnings、WebTest Presenter等。图3是Sonar生成的项目报告的样例。 <br />集群管理/分布式构建。支持DistFork、Hadoop、PXE、Selenium、Swarm等。 <br />制品上传。支持FTP-Publisher、java.net uploader、SCP,SFEE、SVN等。 <br />身份认证和用户管理。支持操作审计追踪、LDAP、MySQL认证等。 </p> <p>图3. Sonar Dashboard</p> <p>结束语</p> <p>工欲善其事，必先利其器。人是工具的主宰。A fool with a tool is still a fool（傻子拿着工具还是傻子）。人们总是在学习工具、使用工具、创造更好的工具，以期提高工作的效率和品质。人要有智慧，工具要先进。</p></div>原文：http://www.blogjava.net/justuszhang2009/archive/2011/06/24/352182.html<div></div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/356730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-08-17 17:40 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/08/17/356730.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hudson环境搭建详解-kiki</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/08/12/356416.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 12 Aug 2011 12:28:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/08/12/356416.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/356416.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/08/12/356416.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/356416.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/356416.html</trackback:ping><description><![CDATA[<div>  <p><span style="font-family: 宋体;">【</span><span>================= windows OS</span><span style="font-family: 宋体;">系统下的：</span> Hudson<span style="font-family: 宋体;">环境搭建过程记录</span>===========<span style="font-family: 宋体;">】</span></p>  <p>1. <span style="font-family: 宋体;">安装</span>jakarta-tomcat-5.0.30.exe, <span style="font-family: 宋体;">使用的</span>jdk<span style="font-family: 宋体;">（</span>C:\Program Files\Java\jdk1.6.0_14<span style="font-family: 宋体;">）。</span></p>  <p><span style="font-family: 宋体;">设置</span>HUDSON_HOME<span style="font-family: 宋体;">环境变量，按住</span>windows<span style="font-family: 宋体;">键</span>+Pause<span style="font-family: 宋体;">键快速出现环境变量设置界面。</span> </p>  <p>HUDSON_HOME=C:\hudson_ci\hudson</p>  <p><span><span>TOMCAT_HOME=C:\hudson_ci\Tomcat 5.0</span></span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JAVA_HOME=C:\Program Files\Java\jdk1.6.0_14</span></span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CALSSPATH=C:\ProgramFiles\Java\jdk1.6.0_14\lib\dt.jar;C:\ProgramFiles\Java\jdk1.6.0_14\lib\tools.jar</span></span></p>    <p>&nbsp;</p>  <p>2. hudson-2.0.0.war&nbsp;copy<span style="font-family: 宋体;">到</span>C:\hudson_ci\Tomcat 5.0\webapps<span style="font-family: 宋体;">目录。</span></p>  <p>&nbsp;</p>  <p>3. <span style="font-family: 宋体;">访问</span><a href="http://localhost:8080/hudson-2.0.0/">http://localhost:8080/hudson-2.0.0/</a><span style="font-family: 宋体;">出现</span>hudson web<span style="font-family: 宋体;">页面。</span></p>  <p>&nbsp;</p>  <p><span style="font-family: 宋体;">【</span>=================PC<span style="font-family: 宋体;">环境</span>=================<span style="font-family: 宋体;">】</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>1.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>OS:fedora 8</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>2.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">【备注信息】</span></p>  <p style="text-indent: 18pt;">1<span style="font-family: 宋体;">）</span>jobs<span style="font-family: 宋体;">里面：只有</span>job<span style="font-family: 宋体;">的各项设置参数值，数据没有保存下来比如</span>MD5<span style="font-family: 宋体;">值等。</span></p>  <p style="margin-left: 21pt;">2<span style="font-family: 宋体;">）</span></p>  <p style="margin-left: 21pt;">2.1.<span style="font-family: 宋体;">）</span> <span style="font-family: 宋体;">之前试过</span>2<span style="font-family: 宋体;">次</span>jdk<span style="font-family: 宋体;">和</span>tomcat6<span style="font-family: 宋体;">都安装好的情况，每次浏览</span>hudson<span style="font-family: 宋体;">就出现内存泄露的情况，是因为</span>hudson-2.0.1.war<span style="font-family: 宋体;">和</span>hudson-2.0.0.war<span style="font-family: 宋体;">虽然在</span>windows<span style="font-family: 宋体;">环境访问</span>OK<span style="font-family: 宋体;">，但是在</span>fedora<span style="font-family: 宋体;">中不兼容，于是从</span>hudson<span style="font-family: 宋体;">官网下了个</span>hudson.war<span style="font-family: 宋体;">，部署到</span>webapps<span style="font-family: 宋体;">最终搞定。</span></p>  <p style="margin-left: 21pt;">2.2.<span style="font-family: 宋体;">）</span></p>  <p style="margin-left: 21pt;">yum list | grep tomcat<span>&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">列出</span>tomcat<span style="font-family: 宋体;">可安装包</span></p>  <p style="margin-left: 21pt;">yum -y install tomcat5<span>&nbsp;&nbsp; //</span><span style="font-family: 宋体;">安装</span>tomcat5</p>  <p style="margin-left: 21pt;">yum remove tomcat5<span>&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">卸载</span>tomcat5</p>  <p style="margin-left: 21pt;">yum remove java <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">卸载所有</span>JAVA</p>  <p style="margin-left: 21pt;">rpm &#8211;qa | grep jdk<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">查找</span>jdk</p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">查看方法</span>:rpm &#8211;qa |grep &#8211;I java</p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">卸载方法</span>:rpm &#8211;e &#8211;nodeps java*<span style="font-family: 宋体;">包名</span></p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">将</span>jdk-6u21-linux-i586-rpm.bin<span style="font-family: 宋体;">给予可执行权限</span></p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">修改权限：</span><span>chmod u+x jdk-6u21-linux-i586-rpm.bin</span></p>  <p style="margin-left: 18pt;">&nbsp;</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>3.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">【</span>SVN<span style="font-family: 宋体;">版本信息】</span></p>  <p style="text-indent: 18pt;"><span style="font-family: 宋体;">【服务器端</span>SVN<span style="font-family: 宋体;">】：</span></p>  <p><span style="font-family: 宋体;">查看</span>SVN<span style="font-family: 宋体;">版本方法：</span></p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image002.jpg" width="477" border="0" height="85"  alt="" /></p>  <p style="text-indent: 18pt;">&nbsp;</p>  <p style="margin-left: 17.95pt;"><span style="font-family: 宋体;">【客户端</span>SVN<span style="font-family: 宋体;">】</span></p>  <p style="margin-left: 17.95pt;"><span style="background: none repeat scroll 0% 0% yellow;">TortoiseSVN 1.5.5,</span> Build 14361 - 32 Bit , 2008/10/24 18:06:34</p>  <p style="margin-left: 17.95pt;">Subversion 1.5.4,</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>4.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&nbsp;<span style="font-family: 宋体;">【几个重要的目录】</span></p>  <p style="margin-left: 18pt;">1<span style="font-family: 宋体;">）</span># cd /etc/init.d/&nbsp;<span style="font-family: 宋体;">目录下面在</span>hudson<span style="font-family: 宋体;">使用之后，会产生</span>hudson<span style="font-family: 宋体;">目录，用于存放</span>Hudson<span style="font-family: 宋体;">的一些数据信息，包括</span>Hudson_home<span style="font-family: 宋体;">变量，所以当</span>hudson<span style="font-family: 宋体;">想要重新配置的时候，一定要删除这里的</span>Hudson<span style="font-family: 宋体;">目录。</span></p>  <p style="margin-left: 10.5pt;">2<span style="font-family: 宋体;">）</span><span>/etc/sysconfig/Hudson </span><span style="font-family: 宋体;">与上面类似，可以使用命令启动</span>Hudson<span style="font-family: 宋体;">，目前最好不用。</span>/etc/init.d/hudson start </p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">。</span></p>  <p style="text-indent: 18pt;">3<span style="font-family: 宋体;">）查看</span>hudson<span style="font-family: 宋体;">的环境变量值是否设置好</span> <span style="font-family: 宋体;">：</span></p>  <p style="margin-left: 21pt;"><span style="font-family: 宋体;">使用</span></p>  <p style="margin-left: 21pt;">[root@localhost etc]# echo $HUDSON_HOME</p>  <p style="margin-left: 21pt;">/home/kiki/compile/hudson_ci/Hudson</p>  <p style="margin-left: 21pt;"><span style="font-family: 宋体;">如果环境变量值</span>OK,<span style="font-family: 宋体;">说明是上面所述的</span>2<span style="font-family: 宋体;">个目录需要清理干净才可以。</span></p>  <p style="margin-left: 18pt;">&nbsp;</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>5.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">【当前</span>HUDSON<span style="font-family: 宋体;">的一些数据信息】</span></p>  <p><span style="font-family: 宋体;">安全机制的用户：</span></p>  <p><span style="font-family: 宋体;">匿名只有</span>R<span style="font-family: 宋体;">权限</span></p>  <p><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#97;&#100;&#109;&#105;&#110;&#47;&#107;&#105;&#107;&#105;&#47;&#120;&#117;&#102;&#117;&#108;&#105;&#64;&#116;&#119;&#115;&#104;&#46;&#99;&#111;&#109;">admin/kiki/xufuli@twsh.com</a></p>  <p><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#116;&#101;&#115;&#116;&#101;&#114;&#47;&#116;&#101;&#115;&#116;&#101;&#114;&#47;&#120;&#117;&#102;&#117;&#108;&#105;&#64;&#116;&#119;&#115;&#104;&#46;&#99;&#111;&#109;">tester/tester/xufuli@twsh.com</a></p>  <p style="margin-left: 18pt;">&nbsp;</p>  <p><span style="font-family: 宋体;">【</span>=================fedora 8<span style="font-family: 宋体;">下面hudson</span><span style="font-family: 宋体;">搭建过程=================</span><span style="font-family: 宋体;">】</span></p>    <p>[<span style="font-family: 宋体;">备注</span>]hudson<span style="font-family: 宋体;">相应的设置都在系统设置时所规定的</span>Hudson_home<span style="font-family: 宋体;">目录下面，</span></p>  <p><span style="font-family: 宋体;">与</span>/usr/apache-tomcat-6.0.32/webapps<span style="font-family: 宋体;">下面的</span>hudson<span style="font-family: 宋体;">不相干，所以保存</span>Hudson_home<span style="font-family: 宋体;">目录下面的数据，就可以对</span>hudson<span style="font-family: 宋体;">进行迁移。</span></p>  <p>JDK6</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>1.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>JDK<span style="font-family: 宋体;">使用软件：</span><a href="http://zh.sourceforge.jp/frs/g_redir.php?m=jaist&amp;f=%2Fcrawlzilla%2Fother%2Fjdk-6u21-linux-i586-rpm.bin" target="_blank">jdk-6u21-linux-i586-rpm.bin</a>,<span style="font-family: 宋体;">下载路径</span></p>  <p><a href="http://zh.sourceforge.jp/projects/sfnet_crawlzilla/downloads/other/jdk-6u21-linux-i586-rpm.bin/">http://zh.sourceforge.jp/projects/sfnet_crawlzilla/downloads/other/jdk-6u21-linux-i586-rpm.bin/</a></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>2.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>JDK<span style="font-family: 宋体;">安装路径</span> <span style="font-family: 宋体;">：</span> /usr/java/jdk1.6.0_21</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>3.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">执行安装命令：</span>./ jdk-6u21-linux-i586-rpm.bin</p>  <p>APACHE</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>1.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>apache<span style="font-family: 宋体;">使用软件：</span>apache-tomcat-6.0.32.tar.gz</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>2.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>apache <span style="font-family: 宋体;">安装路径：</span>/usr/apache-tomcat-<span>6.0.32</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>3.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>apache<span style="font-family: 宋体;">安装方法：</span>tar xzvf&nbsp;apache-tomcat-6.0.32.tar.gz</p>  <p>HUDSON<span style="font-family: 宋体;">软件</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>1.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>hudson<span style="font-family: 宋体;">使用</span>Hudson.war</p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>2.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">直接</span>copy Hudson.war <span style="font-family: 宋体;">到</span>/usr/apache-tomcat-6.0.32/webapps<span style="font-family: 宋体;">目录下面</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>3.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">【</span>hudson<span style="font-family: 宋体;">相应环境变量设置】</span></p>  <p>&nbsp;<span style="font-family: 宋体;">修改文件</span>/etc/profile,<span style="font-family: 宋体;">在文件末尾添加如下，执行</span>source /etc/profile<span style="font-family: 宋体;">生效：</span></p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image004.jpg" width="481" border="0" height="147"  alt="" /></p>  <p>4. apache <span style="font-family: 宋体;">目录中</span>tomcat-users.xml<span style="font-family: 宋体;">配置</span>apache<span style="font-family: 宋体;">的访问用户。</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体;">修改文件</span>/usr/apache-tomcat-6.0.32/conf<span style="font-family: 宋体;">如下：</span></p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image006.jpg" width="577" border="0" height="216"  alt="" /></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>4.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">进入</span>apache<span style="font-family: 宋体;">目录</span>/usr/apache-tomcat-6.0.32/bin,<span style="font-family: 宋体;">启动</span>apache<span style="font-family: 宋体;">服务。</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>5.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">登录</span><a href="http://172.28.6.36:8080/hudson">http://172.28.6.36:8080/hudson</a><span style="font-family: 宋体;">看到</span>hudson<span style="font-family: 宋体;">首页即成为搭建</span>hudson.</p>  <p>&nbsp;</p>  <p><span style="font-family: 宋体;">【</span>=================hudson<span style="font-family: 宋体;">配置过程</span>=================<span style="font-family: 宋体;">】</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>1.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">安全机制配置：</span></p>  <p style="text-indent: 18pt;">Hudson&gt;<span style="font-family: 宋体;">系统管理</span>&gt;<span style="font-family: 宋体;">系统设置</span> <span style="font-family: 宋体;">配置如下</span>,<span style="font-family: 宋体;">然后点击页面右上角的【登录】，跳转到登录页面，单击【</span>Create an account<span style="font-family: 宋体;">】创建一个</span>hudson<span style="font-family: 宋体;">访问用户：</span></p>  <p style="text-indent: 18pt;"><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image008.jpg" width="680" border="0" height="413"  alt="" /></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>2.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">单个</span>SVN<span style="font-family: 宋体;">路径项目的配置如下；</span></p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image010.jpg" width="597" border="0" height="459"  alt="" /><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image012.jpg" width="631" border="0" height="520"  alt="" /></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>3.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">多个相同库或不同库的</span>SVN<span style="font-family: 宋体;">源码的项目配置方式：</span></p>  <p><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image014.jpg" width="735" border="0" height="577"  alt="" /><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image016.jpg" width="724" border="0" height="600"  alt="" />4. <span style="font-family: 宋体;">在</span>hudson<span style="font-family: 宋体;">首页有个：</span>&nbsp;<a href="http://172.28.6.36:8080/hudson/fingerprintCheck">Check File Fingerprint</a></p>  <p><span style="font-family: 宋体;">可以通过这个功能检查构件是否由</span>hudson<span style="font-family: 宋体;">所构建产生。</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>4.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">进入任务的某次构建页面：有</span><span><a href="http://172.28.6.36:8080/hudson/job/5358U_3G_CT----------DSL/58/tagBuild">Tag this build</a></span></p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">可以通过此将此次构建的路径及</span>SVN<span style="font-family: 宋体;">版本号在</span>SVN<span style="font-family: 宋体;">库中打上基线。</span></p>  <p style="margin-left: 18pt; text-indent: -18pt;"><span><span>5.<span style="font: 7pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体;">进入任务页面，</span></p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">状态会显示上次成功构建所产生的构件</span>list,</p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">变更集：显示每次构建源码库所产生的变化，如果是每次提交代码触发一次构建，那么这里显示的就是每次的提交变更记录。</span></p>  <p style="margin-left: 18pt;">&nbsp;</p>  <p style="margin-left: 18pt;">&nbsp;</p>  <p style="margin-left: 18pt;">&nbsp;</p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">【</span>================<span style="font-family: 宋体;">遇到的问题</span>======================<span style="font-family: 宋体;">】</span></p>  <p>1. hudson<span style="font-family: 宋体;">无法指定</span>SVN<span style="font-family: 宋体;">版本的实现（下载最新的</span>SVN<span style="font-family: 宋体;">插件即</span>OK<span style="font-family: 宋体;">，服务器端</span>SVN<span style="font-family: 宋体;">与客户端</span>SVN<span style="font-family: 宋体;">版本不一致导致，请求</span>IT<span style="font-family: 宋体;">开通下载权限再试）</span></p>  <p style="margin-left: 18pt;"><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image018.jpg" width="577" border="0" height="171"  alt="" /></p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">插件这里升级为：</span></p>  <p style="margin-left: 18pt;"><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image020.jpg" width="1010" border="0" height="241"  alt="" />*********<span style="font-family: 宋体;">尝试步骤：</span></p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">新建任务：</span>test812</p>  <p style="margin-left: 18pt;"><span style="font-family: 宋体;">可以了。</span></p>  </div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/356416.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-08-12 20:28 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/08/12/356416.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>译言-持续集成（第二版）</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/08/04/355801.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Thu, 04 Aug 2011 07:41:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/08/04/355801.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/355801.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/08/04/355801.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/355801.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/355801.html</trackback:ping><description><![CDATA[<div><p>目录</p> <p><br /> </p> <p>用持续集成构建特性</p> <p>持续集成实践</p> <p>　　只维护一个源码仓库</p> <p>　　自动化 build</p> <p>　　让你的build自行测试</p> <p>　　每人每天都要向mainline提交代码</p> <p>　　每次提交都应在集成计算机上重新构建 mainline</p> <p>　　保持快速 build</p> <p>　　在模拟生产环境中进行测试</p> <p>　　让每个人都能轻易获得最新的可执行文件</p> <p>　　每个人都能看到进度</p> <p>　　自动化部署</p> <p>持续集成的益处</p> <p>引入持续集成</p> <p>最后的思考</p> <p>延伸阅读</p> <p><br /> </p> <p>　　相关文章<br /> </p> <p>　　<a href="http://www.martinfowler.com/articles/originalContinuousIntegration.html" target="_blank">持续集成（第一版）</a><br /> </p> <p>　　<a href="http://www.martinfowler.com/articles/evodb.html" target="_blank">进化式数据库设计</a><br /> </p> <p><br /> </p> <p><br /> </p> <p>我还可以生动记起第一次看到大型软件工程的情景。我当时在一家大型英国电子公司的QA部 门实习。我的经理带我熟悉公司环境，我们进到一间巨大的，充满了压抑感和格子间的的仓库。我被告知这个项目已经开发了好几年，现在正在集成阶段，并已经集 成了好几个月。我的向导还告诉我没人知道集成要多久才能结束。从此我学到了软件开发的一个惯例：集成是一个很耗时并难以预测的过程。但是事实并非总是如 此，我的 ThoughWorks  同事所做的项目，以及很多其它遍布世界各地的软件项目，都不会把集成当回事。任何一个开发者本地的代码和项目共享基准代码的差别仅仅只有几小时的工作而 已，而且这只要几分钟的时间就可以被集成回去。任何集成错误都可以很快被发现，并被快速修复。这鲜明的差别并非源于昂贵和复杂的工具。其中的精华蕴含于一 个简单的实践：使用统一的代码仓库并频繁集成（通常每天一次）。</p> <p><br /> </p> <p>当我向别人介绍持续集成方法 时，人们通常会有两种反应：&#8220;这（在我们这儿）不管用&#8221;和&#8220;做了也不可能有什么不同&#8221;。但如果他们真的试过了，就会发现持续集成其实比听起来要简单，并且 能给开发过程带来巨大的改变。因此第三种常见的反应是：&#8220;我们就是这么做的，做开发怎可能不用它呢？&#8221;</p> <p><br /> </p> <p>&#8220;持续集成&#8221;一词来源于极限编程（Extreme Programming），作为它的12个实践之一出现。当我开始在 ThoughWorks 开始顾问职业生涯时，我鼓励我所参与的项目使用这种技巧。Matthew Foemmel 将我抽象的指导思想转化为具体的行动。我们看到了项目从少而繁杂的集成进步到我所描述的不当回事。Metthew和我将我们的经验写进了这篇论文的第一版里。这篇论文后来成了我网站里最受欢迎的文章之一。</p> <p><br /> </p> <blockquote style="margin: 0pt 0pt 0pt 40px; border: medium none; padding: 0px;"><p><strong>相关文章：<a href="http://www.martinfowler.com/articles/originalContinuousIntegration.html" target="_blank">持续集成（第一版）</a></strong></p> <p>这是我的个人网站上关于持续集成最早的文章。尽管我觉得新的更好，但大多数链接还是指向原先的这篇文章。文中我描述了 Matt 于2000年早期在 ThoughtWorks 项目中帮助实施持续集成的经验。</p> </blockquote> <p><br /> </p> <p>尽管持续集成不需要什么特别的工具，我们发现使用一个持续集成服务器软件还是很有效果的。最出名的持续集成服务器软件是 CruiseControl，这是一个开源工具，最早由 ThoughWorks 的几个人开发，现在由社区维护。之后还有许多其他持续集成服务器软件出现，有些是开源的，有些则是商业软件，比如 ThoughtWorks Studio 的 <a href="http://studios.thoughtworks.com/cruise-continuous-integration" target="_blank">Cruise</a>。</p> <p><br /> </p> <h2>用持续集成构建特性</h2> <p><br /> </p> <p>对我来说，解释持续集成最简单的方法就是用一个简单的例子来示范开发一个小 feature。现在假设我要完成一个软件的一部分功能，具体任务是什么并不重要，我们先假设这个 feature 很小，只用几个小时就可以完成。（我们稍后会研究更大的任务的情况。）</p> <p><br /> </p> <p>一开始，我将已集成的源代码复制一份到本地计算机。这可以通过从源码管理系统的 mainline 上 check out 一份源代码做到。</p> <p><br /> </p> <p>如果你用过任何源代码管理系统，理解上面的文字应该不成问题。但如果你没用过，可能会有读天书的感觉。所以我们先快速解释一个这些概念。源代码管理系统将项目的所有源代码都保存在一个&#8220;仓库（repository）&#8221;中。系统的当前状态通常被称为&#8220;mainline&#8221;。开发者随时都可以把mainline复制一份到他们自己的计算机，这个过程被称为&#8220;check out&#8221;。开发者计算机上的拷贝被称为&#8220;工作拷贝（working copy）&#8221;。（绝大部分情况下，你最终都会把工作拷贝的内容提交到mainline上去，所以两者实际上应该差不多。）</p> <p><br /> </p> <p>现在我拿到了工作拷贝，接下来需要做一些事情来完成任务。这包括修改产品代码和添加修改自动化测试。在持续集成中，软件应该包含完善的可自动运行的测试，我称之为自测试代码。这一般需要用到某一个流行的 XUnit 测试框架。</p> <p><br /> </p> <p>一旦完成了修改，我就会在自己的计算机上启动一个自动化 build。这会将我的工作拷贝中的源代码编译并链接成为一个可执行文件，并在之上运行自动化测试。只有当所有的 build 和测试都完成并没有任何错误时，这个 build 过程才可以认为是成功的。</p> <p><br /> </p> <p>当我 build 成功后，我就可以考虑将改动提交到源码仓库。但麻烦的情况在于别人可能已经在我之前修改过 mainline。这时我需要首先把别人的修改更新到我的工作拷贝中，再重新做 build。如果别人的代码和我的有冲突，就会在编译或测试的过程中引起错误。我有责任改正这些问题，并重复这一过程，直到我的工作拷贝能通过 build 并和 mainline 的代码同步。</p> <p><br /> </p> <p>一旦我本地的代码能通过 build，并和 mainline 同步，我就可以把我的修改提交到源码仓库。</p> <p><br /> </p> <p>然而，提交完代码不表示就完事大吉了。我们还要做一遍集成 build，这次在集成计算机上并要基于 mainline 的代码。只有这次 build 成功了，我的修改才算告一段落。因为总有可能我忘了什么东西在自己的机器上而没有更新到源码仓库。只有我提交的改动被成功的集成了，我的工作才能结束。这可以由我手工运行，也可以由 Cruise 自动运行。</p> <p><br /> </p> <p>如果两个开发者的修改存在冲突，这通常会被第二个人提交代码前本地做 build 时发现。即使这时侥幸过关，接下来的集成 build 也会失败掉。不管怎样，错误都会被很快检测出来。此时首要的任务就是改正错误并让 build 恢复正常。在持续集成环境里，你必须尽可能快地修复每一个集成 build。好的团队应该每天都有多个成功的 build。错误的 build 可以出现，但必须尽快得到修复。</p> <p><br /> </p> <p>这样做的结果是你总能得到一个稳定的软件，它可能有一些 bug，但可以正常工作。每个人都基于相同的稳定代码进行开发，而且不会离得太远，否则就会不得不花很长时间集成回去。Bug被发现得越快，花在改正上的时间就越短。</p> <p><br /> </p> <h2>持续集成实践</h2> <p><br /> </p> <p>从上面的故事我们大概了解了持续集成是如何在我们的日常工作中发挥作用的。但让一切正常运行起来还需要掌握更多的知识。我接下来会集中讲解一下高效持续集成的关键实践。</p> <p><br /> </p> <h3>只维护一个源码仓库</h3> <p><br /> </p> <p>在软件项目里需要很多文件协调一致才能 build   出产品。跟踪所有这些文件是一项困难的工作，尤其是当有很多人一起工作时。所以，一点也不奇怪，软件开发者们这些年一直在研发这方面的工具。这些工具称为 源代码管理工具，或配置管理，或版本管理系统，或源码仓库，或各种其它名字。大部分开发项目中它们是不可分割的一部分。但可惜的是，并非所有项目都是如 此。虽然很罕见，但我确实参加过一些项目，它们直接把代码存到本地驱动器和共享目录中，乱得一塌糊涂。</p> <p><br /> </p> <p>所以，作为一个最基本的要求，你必须有一个起码的源代码管理系统。成本不会是问题，因为有很多优秀的开源工具可用。当前较好的开源工具是 <a href="http://subversion.tigris.org/" target="_blank">Subversion</a>。（更老的同样开源的 <a href="http://www.nongnu.org/cvs/" target="_blank">CVS</a> 仍被广泛使用，即使是 CVS 也比什么都不用强得多，但 Subversion 更先进也更强大。）有趣的是，我从与开发者们的交谈中了解到，很多商业源代码管理工具其实不比 Subversion 更好。只有一个商业软件是大家一致同意值得花钱的，这就是 <a href="http://www.perforce.com/" target="_blank">Perforce</a>。</p> <p><br /> </p> <p>一旦你有了源代码管理系统，你要确保所有人都知道到哪里去取代码。不应出现这样的问题：&#8220;我应该到哪里去找xxx文件？&#8221; 所有东西都应该存在源码仓库里。</p> <p><br /> </p> <p>即便对于用了源码仓库的团队，我还是观察到一个很普遍的错误，就是他们没有把所有东西都放在源码仓库里。一般人们都会把代码放进去，但还有许多其它文件，包括测试脚本，配置文件，数据库Schema，安装脚本，还有第三方的库，所有这些build时需要的文件都应该放在源码仓库里。我知道一些项目甚至把编译器也放到源码仓库里（用来对付早年间那些莫名其妙的C++编译器很有效）。一个基本原则是：你必须能够在一台干净的计算机上重做所有过程，包括checkout和完全build。只有极少量的软件需要被预装在这台干净机器上，通常是那些又大又稳定，安装起来很复杂的软件，比如操作系统，Java开发环境，或数据库系统。</p> <p><br /> </p> <p>你必须把build需要的所有文件都放进源代码管理系统，此外还要把人们工作需要的其他东西也放进去。IDE配置文件就很适合放进去，因为大家共享同样的IDE配置可以让工作更简单。</p> <p><br /> </p> <p>版本控制系统的主要功能之一就是创建 branch 以管理开发流。这是个很有用的功能，甚至可以说是一个基础特性，但它却经常被滥用。你最好还是尽量少用&nbsp;branch。一般有一个mainline就够了，这是一条能反映项目当前开发状况的&nbsp;branch。大部分情况下，大家都应该从mainline出发开始自己的工作。（合理的创建&nbsp;branch&nbsp;的理由主要包括给已发布的产品做维护和临时性的实验。）</p> <p><br /> </p> <p>一般来说，你要把build依赖的所有文件放进代码管理系统中，但不要放build的结果。有些人习惯把最终产品也都放进代码管理系统中，我认为这是一种坏味道&#8212;&#8212;这意味着可能有一些深层次的问题，很可能是无法可靠地重新build一个产品。</p> <p><br /> </p> <h3>自动化build</h3> <p><br /> </p> <p>通常来说，由源代码转变成一个可运行的系统是一个复杂的过程，牵扯到编译，移动文件，将 schema 装载到数据库，诸如此类。但是，同软件开发中的其它类似任务一样，这也可以被自动化，也必须被自动化。要人工来键入各种奇怪的命令和点击各种对话框纯粹是浪费时间，也容易滋生错误。</p> <p><br /> </p> <p>在大部分开发平台上都能找到自动化 build 环境的影子。比如 make，这在 Unix 社区已经用了几十年了，Java 社区也开发出了 Ant，.NET 社区以前用 Nant，现在用 MSBuild。不管你在什么平台上，都要确保只用一条命令就可以运行这些脚本，从而 build 并运行系统。</p> <p><br /> </p> <p>一个常见的错误是没有把所有事都放进自动化 build。比如：Build 也应该包括从源码仓库中取出数据库 schema 并在执行环境中设置的过程。我要重申一下前面说过的原则：任何人都应该能从一个干净的计算机上 check out 源代码，然后敲入一条命令，就可以得到能在这台机器上运行的系统。</p> <p><br /> </p> <p>Build 脚本有很多不同的选择，依它们所属的平台和社区而定，但也没有什么定势。尽管大部分的 Java 项目都用 Ant，还是有一些项目用 Ruby（Ruby Rake 是一个不错的 build 脚本工具）。我们也曾经用 Ant 自动化早期的 Microsoft COM 项目，事实证明很有价值。</p> <p><br /> </p> <p>一个大型 build 通常会很耗时，如果只做了很小的修改，你不会想花时间去重复所有的步骤。所以一个好的 build 工具应该会分析哪些步骤可以跳过。一个通用的办法是比较源文件和目标文件的修改时间，并只编译那些较新的源文件。处理依赖关系要麻烦一些：如果一个目标文件修改了，所有依赖它的部分都要重新生成。编译器可能会帮你处理这些事情，也可能不会。</p> <p><br /> </p> <p>根据你的需要，你可能会想 build 出各种不同的东西。你可以同时 build 系统代码和测试代码，也可以只 build 系统代码。一些组件可以被单独 build。Build 脚本应该允许你在不同的情况中 build 不同的 target。</p> <p><br /> </p> <p>我们许多人都用 IDE，许多 IDE 都内置包含某种 build 管理功能。然而，相应的配置文件往往是这些 IDE 的专有格式，而且往往不够健壮，它们离了 IDE 就无法工作。如果只是 IDE 用户自己一个人开发的话，这还能够接受。但在团队里，一个工作于服务器上的主 build 环境和从其它脚本里运行的能力更重要。我们认为，在 Java 项目里，开发者可以用自己的 IDE 做 build，但主 build 必须用 Ant 来做，以保证它可以在开发服务器上运行。</p> <p><br /> </p> <h3>让你的build自行测试</h3> <p><br /> </p> <p>传统意义上的 build 指编译，链接，和一些其它能让程序运行起来的步骤。程序可以运行并不意味着它也工作正常。现代静态语言可以在编译时检测出许多 bug，但还是有更多的漏网之鱼。</p> <p><br /> </p> <p>一种又快又省的查 bug 的方法是在 build 过程中包含自动测试。当然，测试并非完美解决方案，但它确实能抓住很多 bug&#8212;&#8212;多到可以让软件真正可用。极限编程（XP）和测试驱动开发（TDD）的出现很好地普及了自测试代码的概念，现在已经有很多人意识到了这种技巧的价值。 </p> <p><br /> </p> <p>经常读我的著作的读者都知道我是 TDD 和 XP 的坚定追随者。但是我想要强调你不需要这两者中任何一个就能享受自测试代码的好处。两者都要求你先写测试，再写代码以通过测试，在这种工作模式里测试更多着重于探索设计而不是发现 bug。这绝对是一个好方法，但对于持续集成而言它并不必要，因为这里对自测试代码的要求没有那么高。（尽管我肯定会选择用 TDD 的方式。）</p> <p><br /> </p> <p>自测试代码需要包含一套自动化测试用例，这些测试用例可以检查大部分代码并找出 bug。测试要能够从一条简单的命令启动。测试结果必须能指出哪些测试失败了。对于包含测试的 build，测试失败必须导致 build 也失败。</p> <p><br /> </p> <p>在过去的几年里，TDD 的崛起普及了开源的&nbsp;<a href="http://www.martinfowler.com/bliki/Xunit.html" target="_blank">XUnit 系列工具</a>，这些工具用作以上用途非常理想。对于我们在 ThoughWorks 工作的人来说，XUnit 工具已经证明了它们的价值。我总是建议人们使用它们。这些最早由 Kent Beck 发明的工具使得设置一个完全自测试环境的工作变得非常简单。</p> <p><br /> </p> <p>毋庸置疑，对于自动测试的工作而言，XUnit 工具只是一个起点。你还必须自己寻找其他更适合端对端测试的工具。现在有很多此类工具，包括<a href="http://fit.c2.com/" target="_blank">FIT</a>，<a href="http://www.openqa.org/selenium/" target="_blank">Selenium</a>，<a href="http://sahi.sourceforge.net/" target="_blank">Sahi</a>，<a href="http://wtr.rubyforge.org/" target="_blank">Watir</a>，<a href="http://fitnesse.org/" target="_blank">FITnesse</a>，和许多其它我无法列在这里的工具。</p> <p><br /> </p> <p>当然你不能指望测试发现所有问题。就像人们经常说的：测试通过不能证明没有 bug。然而，完美并非是你要通过自测试 build 达到的唯一目标。经常运行不完美的测试要远远好过梦想着完美的测试，但实际什么也不做。</p> <p><br /> </p> <h3>每人每天都要向 mainline 提交代码</h3> <p><br /> </p> <p>集成的主要工作其实是沟通。集成可以让开发者告诉其他人他们都改了什么东西。频繁的沟通可以让人们更快地了解变化。</p> <p><br /> </p> <p>让开发者提交到 mainline 的一个先决条件是他们必须能够正确地 build 他们的代码。这当然也包括通过 build 包含的测试。在每个提交迭代里，开发者首先更新他们的工作拷贝以与 mainline 一致，解决任何可能的冲突，然后在自己的机器上做 build。在 build 通过后，他们就可以随便向 mainline 提交了。</p> <p><br /> </p> <p>通 过频繁重复上述过程，开发者可以发现两个人之间的代码冲突。解决问题的关键是尽早发现问题。如果开发者每过几个小时就会提交一次，那冲突也会在出现的几个 小时之内被发现，从这一点来说，因为还没有做太多事，解决起来也容易。如果让冲突待上几个星期，它就会变得非常难解决。</p> <p><br /> </p> <p>因为你在更新工作拷贝时也会做 build，这意味着你除了解决源代码冲突外也会检查编译冲突。因为 build 是自测试的，你也可以查出代码运行时的冲突。后者如果在一段较长的时间还没被查出的话会变得尤其麻烦。因为两次提交之间只有几个小时的修改，产生这些问题只可能在很有限的几个地方。此外，因为没改太多东西，你还可以用&nbsp;<a href="http://www.martinfowler.com/bliki/DiffDebugging.html" target="_blank">diff-debugging</a>&nbsp;的技巧来找 bug。</p> <p><br /> </p> <p>总的来说，我的原则是每个开发者每天都必须提交代码。实践中，如果开发者提交的更为频繁效果也会更好。你提交的越多，你需要查找冲突错误的地方就越少，改起来也越快。</p> <p><br /> </p> <p>频繁提交客观上会鼓励开发者将工作分解成以小时计的小块。这可以帮助跟踪进度和让大家感受到进展。经常会有人一开始根本无法找到可以在几小时内完成的像样的工作，但我们发现辅导和练习可以帮助他们学习其中的技巧。</p> <p><br /> </p> <h3>每次提交都应在集成计算机上重新构建 mainline</h3> <p><br /> </p> <p>使用每日提交的策略后，团队就能得到很多经过测试的 build。这应该意味着 mainline 应该总是处于一种健康的状态。但在实践中，事情并非总是如此。一个原因跟纪律有关，人们没有严格遵守在提交之前在本地更新并做 build 的要求。另一个原因是开发者的计算机之间环境配置的不同。</p> <p><br /> </p> <p>结论是你必须保证日常的 build 发生在专用的集成计算机上，只有集成 build 成功了，提交的过程才算结束。本着&#8220;谁提交，谁负责&#8221;的原则，开发者必须监视 mainline 上的 build 以便失败时及时修复。一个推论是如果你在下班前提交了代码，那你在 mainline build 成功之前就不能回家。</p> <p><br /> </p> <p>我知道主要有两种方法可以使用：手动 build，或持续集成服务器软件。</p> <p><br /> </p> <p>手动 build 描述起来比较简单。基本上它跟提交代码之前在本地所做的那次 build 差不多。开发者登录到集成计算机，check out 出 mainline 上最新的源码（已包含最新的提交），并启动一个集成 build。他要留意 build 的进程，只有 build 成功了他的提交才算成功。（请查看 Jim Shore 的<a href="http://www.jamesshore.com/Blog/Continuous-Integration-on-a-Dollar-a-Day.html" target="_blank">描述</a>。）</p> <p><br /> </p> <p>持续集成服务器软件就像一个监视着源码仓库的监视器。每次源码仓库中有新的提交，服务器就会自动 check out 出源代码并启动一次 build，并且把 build 的结果通知提交者。这种情况下，提交者的工作直到收到通知（通常是 email）才算结束。</p> <p><br /> </p> <p>在 ThoughtWorks，我们都是持续集成服务器软件的坚定支持者，实际上我们引领了&nbsp;<a href="http://cruisecontrol.sourceforge.net/" target="_blank">CruiseControl</a>&nbsp;和&nbsp;<a href="http://ccnet.thoughtworks.com/" target="_blank">CruiseControl.NET</a>&nbsp;最早期的开发，两者都是被广泛使用的开源软件。此后，我们还做了商业版的&nbsp;<a href="http://studios.thoughtworks.com/cruise-continuous-integration" target="_blank">Cruise</a>&nbsp;持续集成服务器。我们几乎在每一个项目里都会用持续集成服务器，并且对结果非常满意。 </p> <p><br /> </p> <p>不是每个人都会用持续集成服务器。Jim Shore 就<a href="http://www.jamesshore.com/Blog/Continuous-Integration-is-an-Attitude.html" target="_blank">清楚地表达</a>了为什么他更偏好手动的办法。我同意他的看法中的持续集成并不仅仅是安装几个软件而已，所有的实践都必须为了能让持续集成更有效率。但同样的，许多持续集成执行得很好的团队也会发现持续集成服务器是个很有用的工具。</p> <p><br /> </p> <p>许多组织根据安排好的日程表做例行 build，如每天晚上。这其实跟持续集成是两码事，而且做得远远不够。持续集成的最终目标就是要尽可能快地发现问题。Nightly build 意味着 bug 被发现之前可能会待上整整一天。一旦 bug 能在系统里呆这么久，找到并修复它们也会花较长的时间。</p> <p><br /> </p> <p>做好持续集成的一个关键因素是一旦 mainline 上的 build 失败了，它必须被马上修复。而在持续集成环境中工作最大的好处是，你总能在一个稳定的基础上做开发。mainline 上 build 失败并不总是坏事，但如果它经常出错，就意味着人们没有认真地在提交代码前先在本地更新代码和做 build。当 mainline 上 build 真的失败时，第一时间修复就成了头等大事。为了防止在 mainline 上的问题，你也可以考虑用&nbsp;<a href="http://martinfowler.com/bliki/PendingHead.html" target="_blank">pending head</a>&nbsp;的方法。</p> <p><br /> </p> <p>当团队引入持续集成时，这通常是最难搞定的事情之一。在初期，团队会非常难以接受频繁在 mainline 上做 build 的习惯，特别当他们工作在一个已存在的代码基础上时更是如此。但最后耐心和坚定不移的实践常常会起作用，所以不要气馁。</p> <p><br /> </p> <h3>保持快速 build</h3> <p><br /> </p> <p>持续集成的重点就是快速反馈。没有什么比缓慢的 build 更能危害持续集成活动。这里我必须承认一个奇思怪想的老家伙关于 build 快慢标准的的玩笑（译者注：原文如此，不知作者所指）。我的大部分同事认为超过1小时的 build 是不能忍受的。团队们都梦想着把 build 搞得飞快，但有时我们也确实会发现很难让它达到理想的速度。</p> <p><br /> </p> <p>对大多数项目来说，XP 的10分钟 build 的指导方针非常合理。我们现在做的大多数项目都能达到这个要求。这值得花些力气去做，因为你在这里省下的每一分钟都能体现在每个开发者每次提交的时候。持续集成要求频繁提交，所以这积累下来能节省很多时间。如果你一开始就要花1小时的时间做 build，想加快这个过程会相当有挑战。即使在一个从头开始的新项目里，想让 build 始终保持快速也是很有挑战的。至少在企业应用里，我们发现常见的瓶颈出现在测试时，尤其当测试涉及到外部服务如数据库。</p> <p><br /> </p> <p>也许最关键的一步是开始使用分阶段build（staged build）。<strong>分阶段 build</strong>（也被称作&nbsp;<strong>build 生产线</strong>）的基本想法是多个 build 按一定顺序执行。向 mainline 提交代码会引发第一个 build，我称之为提交 build（commit build）。<strong>提交 build&nbsp;</strong>是当有人向 mainline 提交时引发的 build。提交 build 要足够快，因此它会跳过一些步骤，检测 bug 的能力也较弱。提交 build 是为了平衡质量检测和速度，因此一个好的提交 build 至少也要足够稳定以供他人基于此工作。 </p> <p><br /> </p> <p>一旦提交 build 成功，其他人就可以放心地基于这些代码工作了。但别忘了你还有更多更慢的测试要做，可以另找一台计算机来运行运行这些测试。 </p> <p><br /> </p> <p>一个简单的例子是两阶段 build。第一阶段会编译和运行一些本地测试，与数据库相关的单元测试会被完全隔离掉（stub out）。这些测试可以运行得非常快，符合我们的10分钟指导方针。但是所有跟大规模交互，尤其是真正的数据库交互的 bug 都无法被发现。第二阶段的 build 运行一组不同的测试，这些测试会调用真正的数据库并涉及更多的端到端的行为。这些测试会跑上好几小时。</p> <p><br /> </p> <p>这种情况下，人们用第一阶段作为提交 build，并把这作为主要的持续集成工作。第二阶段 build 是<strong>次级build</strong>，只有在需要的时候才运行，从最后一次成功的提交 build 中取出可执行文件作进一步测试。如果次级 build 失败了，大家不会立刻停下手中所有工作去修复，但团队也要在保证提交 build 正常运行的同时尽快修正 bug。实际上次级 build 并非一定要正常运行，只要 bug 都能够被检查出来并且能尽快得到解决就好。在两阶段 build 的例子里，次级 build 经常只是纯粹的测试，因为通常只是测试拖慢了速度。</p> <p><br /> </p> <p>如果次级 build 检查到了 bug，这是一个信号，意味着提交 build 需要添加一个新测试了。你应该尽可能把次级 build 失败过的测试用例都添加到提交 build 中，使得提交 build 有能力验证这些 bug。每当有 bug 绕过提交测试，提交测试总能通过这种方法被加强。有时候确实无法找到测试速度和 bug 验证兼顾的方法，你不得不决定把这个测试放回到次级 build 里。但大部分情况下都应该可以找到合适加入提交 build 的测试。</p> <p><br /> </p> <p>上面这个例子是关于两阶段 build，但基本原则可以被推广到任意数量的后阶段 build。提交 build 之后的其它 build 都可以同时进行，所以如果你的次级测试要两小时才能完成，你可以通过用两台机器各运行一半测试来快一点拿到结果。通过这个并行次级 build 技巧，你可以向日常 build 流程中引入包括性能测试在内的各种自动化测试。（当我过去几年内参加 Thoughtworks 的各种项目时，我碰到了很多有趣的技巧，我希望能够说服一些开发者把这些经验写出来。）</p> <p><br /> </p> <h3>在模拟生产环境中进行测试</h3> <p><br /> </p> <p>测试的关键在于在受控条件下找出系统内可能在实际生产中出现的任何问题。这里一个明显的因素是生产系统的运行环境。如果你不在生产环境做测试，所有环境差异都是风险，可能最终造成测试环境中运行正常的软件在生产环境中无法正常运行。</p> <p><br /> </p> <p>自然你会想到建立一个与生产环境尽可能完全相同的测试环境。用相同的数据库软件，还要同一个版本；用相同版本的操作系统；把所有生产环境用到的库文件都放进测试环境中，即使你的系统没有真正用到它们；使用相同的IP地址和端口；以及相同的硬件；</p> <p><br /> </p> <p>好 吧，现实中还是有很多限制的。如果你在写一个桌面应用软件，想要模拟所有型号的装有不同第三方软件的台式机来测试显然是不现实的。类似的，有些生产环境可 能因为过于昂贵而无法复制（尽管我常碰到出于经济考虑拒绝复制不算太贵的环境，结果得不偿失的例子）。即使有这些限制，你的目标仍然是尽可能地复制生产环 境，并且要理解并接受因测试环境和生产环境不同带来的风险。</p> <p><br /> </p> <p>如果你的安装步骤足够简单，无需太多交互，你也许能在一个模拟生产环境里运行提交 build。但事实上系统经常反应缓慢或不够稳定，这可以用&nbsp;<a href="http://www.martinfowler.com/bliki/TestDouble.html" target="_blank">test double</a>&nbsp;来解决。结果常常是提交测试为了速度原因在一个假环境内运行，而次级测试运行在模拟真实的生产环境中。</p> <p><br /> </p> <p>我注意到越来越多人用虚拟化来搭建测试环境。虚拟机的状态可以被保存，因此安装并测试最新版本的build相对简单。此外，这可以让你在一台机器上运行多个测试，或在一台机器上模拟网络里的多台主机。随着虚拟化性能的提升，这种选择看起来越来越可行。</p> <p><br /> </p> <h3>让每个人都能轻易获得最新的可执行文件</h3> <p><br /> </p> <p>软件开发中最困难的部分是确定你的软件行为符合预期。我们发现事先清楚并正确描述需求非常困难。对人们而言，在一个有缺陷的东西上指出需要修改的地方要容易得多。敏捷开发过程认可这种行为，并从中受益。</p> <p><br /> </p> <p>为了以这种方式工作，项目中的每个人都应该能拿到最新的可执行文件并运行。目的可以为了 demo，也可以为了探索性测试，或者只是为了看看这周有什么进展。</p> <p><br /> </p> <p>这做起来其实相当简单：只要找到一个大家都知道的地方来放置可执行文件即可。可以同时保存多份可执行文件以备使用。每次放进去的可执行文件应该要通过提交测试，提交测试越健壮，可执行文件就会越稳定。</p> <p><br /> </p> <p>如果你采用的过程是一个足够好的迭代过程，把每次迭代中最后一个 build 放进去通常是明智的决定。Demo 是一个特例，被 demo 的软件特性都应该是演示者熟悉的特性。为了 demo 的效果值得牺牲掉最新的 build，转而找一个早一点但演示者更熟悉的版本。</p> <p><br /> </p> <h3>每个人都能看到进度</h3> <p><br /> </p> <p>持续集成中最重要的是沟通。你需要保证每个人都能轻易看到系统的状态和最新的修改。</p> <p><br /> </p> <p>沟通的最重要的途径之一是 mainline build。如果你用 Cruise，一个内建的网站会告诉你是否正有 build 在进行，和最近一次 mainline build 的状态。许多团队喜欢把一个持续工作的状态显示设备连接到 build 系统来让这个过程更加引人注目，最受欢迎的显示设备是灯光，绿灯闪亮表示 build 成功，红灯表示失败。一种常见的选择是红色和绿色的<a href="http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Devices/BubbleBubbleBuildsInTrouble.rdoc" target="_blank">熔岩灯</a>，这不仅仅指示 build 的状态，还能指示它停留在这个状态的时间长短，红灯里出现气泡表示 build 出问题已经太长时间了。每一个团队都会选择他们自己的 build 传感器。如果你的选择带点幽默性和娱乐性效果会更好（最近我看到有人在实验跳舞兔）。</p> <p><br /> </p> <p>即使你在使用手动持续集成，可见程度依然很重要。Build 计算机的显示器可以用来显示 mainline build 的状态。你很可能需要一个 build 令牌放在正在做 build 那人的桌子上（橡皮鸡这种看上去傻傻的东西最好，原因同上）。有时人们会想在 build 成功时弄出一点噪音来，比如摇铃的声音。</p> <p><br /> </p> <p>持续集成服务器软件的网页可以承载更多信息。Cruise 不仅显示谁在做 build，还能指出他们都改了什么。Cruise 还提供了一个历史修改记录，以便团队成员能够对最近项目里的情况有所了解。我知道 team leader喜欢用这个功能了解大家手头的工作和追踪系统的更改。</p> <p><br /> </p> <p>使用网站的另一大优点是便于那些远程工作的人了解项目的状态。一般来说，我倾向于让项目中发挥作用的成员都坐在一起工作，但通常也会有一些外围人员想要了解项目的动态。如果组织想要把多个项目的 build情况聚合起来以提供自动更新的简单状态时，这也会很有用。</p> <p><br /> </p> <p>好的信息展示方式不仅仅依赖于电脑显示器。我最喜欢的方式出现于一个中途转入持续集成的项目。很长时间它都无法拿出一个稳定的 build。我们在墙上贴了一整年的日历，每一天都是一个小方块。每一天如果 QA 团队收到了一个能通过提交测试的稳定 build，他们都会贴一张绿色的贴纸，否则就是红色的贴纸。日积月累，从日历上能看出 build 过程在稳定地进步。直到绿色的小方块已经占据了大部分的空间时，日历被撤掉了，因为它的使命已经完成了。</p> <p><br /> </p> <h3>自动化部署</h3> <p><br /> </p> <p>自 动化集成需要多个环境，一个运行提交测试，一个或多个运行次级测试。每天在这些环境之间频繁拷贝可执行文件可不轻松，自动化是一个更好的方案。为实现自动 化，你必须有几个帮你将应用轻松部署到各个环境中的脚本。有了脚本之后，自然而然的结果是你也要用类似的方式部署到生产环境中。你可能不需要每天都部署到 生产环境（尽管我见过这么做的项目），但自动化能够加快速度并减少错误。它的代价也很低，因为它基本上和你部署到测试环境是一回事。</p> <p><br /> </p> <p>如果你部署到生产环境，你需要多考虑一件事情：自动化回滚。坏事情随时可能发生，如果情况不妙，最好的办法是尽快回到上一个已知的正常状态。能够自动回滚也会减轻部署的压力，从而鼓励人们更频繁地部署，使得新功能更快发布给用户。（Ruby on Rails 社区开发了一个名为&nbsp;<a href="http://capify.org/" target="_blank">Capistrano</a>&nbsp;的工具，是这类工具很好的代表。）</p> <p><br /> </p> <p>我还在服务器集群环境中见过滚动部署的方法，新软件每次被部署到一个节点上，在几小时时间内逐步替换掉原有的软件。</p> <p><br /> </p> <blockquote style="margin: 0pt 0pt 0pt 40px; border: medium none; padding: 0px;"><p><strong>参见相关文章：</strong><a href="http://www.martinfowler.com/articles/evodb.html" target="_blank">进化式数据库设计</a></p> <p><em>许多人在频繁发布时都遇到的一个障碍是数据库的迁移。数据库的改动很麻烦，因为你不能仅仅修改 schema，你还要保证数据本身也被顺利迁移。这篇文章描述了我的同事 Pramod Sadalage 自动化重构和迁移数据库的技巧。这篇文章只是一个简单的记录，其中的信息在 Pramod 和 Scott Amblers 关于数据库重构的书中有更详细的阐述[ambler-sadalage]。</em></p> </blockquote> <p><br /> </p> <p>在 web 应用开发中，我碰到的一个有趣的想法是把一个试验性的 build 部署到用户的一个子集。团队可以观察这个试验 build 被使用的情况，以决定是否将它部署到全体用户。你可以在做出最终决定之前试验新的功能和新的 UI。自动化部署加上良好的持续集成的纪律是这项工作的基础。 </p> <p><br /> </p> <h2>持续集成的益处 </h2> <p><br /> </p> <p>我认为持续集成最显著也最广泛的益处是降低风险。说到这里，我的脑海中还是会浮现出第一段描述的早期软件项目。他们已经到了一个漫长项目的末期（至少他们期望如此），但还是不知道距离真正的结束有多远。</p> <p><br /> </p> <p>延迟集成的问题在于时间难以估计，你甚至无法得知你的进展。结果是你在项目最紧张的阶段之一把自己置入了一个盲区，此时即使没有拖延（这很罕见）也轻松不了多少。</p> <p><br /> </p> <p>持续集成巧妙的解决了这个问题。长时间的集成不再存在，盲区被彻底消除了。在任何时间你都知道你自己的进展，什么能运转，什么不能运转，你系统里有什么明显的 bug，这些都一目了然。</p> <p><br /> </p> <p>Bug 让人恶心，它摧毁人的自信，搞乱时间表，还破坏团队形象。已部署软件里的 bug 招致用户的怒气。未完成软件里的 bug 让你接下来的开发工作受阻。</p> <p><br /> </p> <p>持续集成不能防止 bug 的产生，但它能明显让寻找和修改 bug 的工作变简单。从这个方面看，它更像自测试代码。如果你引入 bug 后能很快发现，改正也会简单得多。因为你只改了系统中很小的一部分，你无需看很多代码就能找到问题所在。因为这一小部分你刚刚改过，你的记忆还很新鲜，也会让找 bug 的工作简单不少。你还可以用<a href="http://www.martinfowler.com/bliki/DiffDebugging.html" target="_blank">差异调试</a>&#8212;&#8212;比较当前版本和之前没有 bug 的版本。</p> <p><br /> </p> <p>Bug 也会积累。你的 bug 越多，解决掉任何一个都会越困难。这部分原因是 bug 之间的互相作用，你看到的失败实际上是多个问题叠加的结果，这使得检查其中任何一个问题都更加困难。还有部分原因是心理层面的因素，当人们面对大量 bug 时，他们寻找和解决 bug 的动力就会减弱。《Pragmatic Programmer》一书中称之为&#8220;<a href="http://www.amazon.com/exec/obidos/ASIN/020161622X" target="_blank">破窗综合症</a>&#8220;。</p> <p><br /> </p> <p>使用持续集成的项目的通常结果是 bug 数目明显更少，不管在产品里还是开发过程中都是如此。然而，我必须强调，你受益的程度跟你测试的完善程度直接相关。其实建立测试系统并非想象中那么困难，但带来的区别却显而易见。一般来说，团队需要花一定时间才能把 bug 数量减少到理想的地步。做到这一点意味着不断添加和改进测试代码。</p> <p><br /> </p> <p>如果你用了持续集成，你就解决了频繁部署的最大障碍之一。频繁部署很有价值，因为它可以让你的用户尽快用到新功能，从而快速提供反馈，这样他们在开发过程中可以有更多的互动。这可以帮助打破我心目中成功的软件开发最大的障碍&#8212;&#8212;客户与开发团队之间的障碍。</p> <p><br /> </p> <h2>引入持续集成</h2> <p><br /> </p> <p>看 到这里，你一定想要尝试一下持续集成了。但是从哪里开始呢？我在上面描述了一整套的实践，这些可以让你体验到所有的好处。但你也不必一开始就照单全收，你 有自己的选择余地，基本上取决于你的环境和团队的特性。我们也从过去的实践中吸取了一些经验和教训，做好下面这些事会对于你的持续集成运作有重要的意义。</p> <p><br /> </p> <p>最早的几步之一是实现 build 自动化。把所有需要的东西都放进版本控制系统里，这样你就可以用一条命令 build 整个系统。这对许多项目而言不是什么小任务，这对于其他东西正常工作非常重要。刚开始你可能只是偶尔需要的时候做一个 build，或者只是做一个自动的 nightly build。当你还没有开始持续集成时，自动 nightly build 也是一个不错的开始。</p> <p><br /> </p> <p>其次是引入一些自动化测试到你的 build 中。试着指出主要出错的地方，并要让自动化测试暴露这些错误。建立又快又好的测试集合会比较困难，特别在已存在的项目中，建立测试需要时间。你必须找个地方开始动手，就像俗话说的，罗马不是一天建成的。</p> <p><br /> </p> <p>还要试着加快提交 build 的速度。虽然需要几个小时 build 的持续集成也比什么都没有好，但能做到传说中的10分钟会更好。这通常要对你的代码动一些大手术，以剥离对运行缓慢那部分的依赖。</p> <p><br /> </p> <p>如果你刚刚开始一个新项目，从一开始就用持续集成。对build时间保持关注，当慢于10分钟时就立即采取行动。通过快速行动，你可以在代码变得太大之前做一些必要的架构调整。</p> <p><br /> </p> <p>比所有事情都重要的是寻找帮助。找一个以前做过持续集成的人来帮你。像所有新技巧一样，当你不知道最终结果怎样的时候会非常难以实施。请一个导师（mentor）可能会花些钱，但如果你不做，你会付出时间和生产效率损失的代价。（免责声明/广告：是的，我们 ThoughtWorks 在这个领域提供咨询服务。不管怎样，我们曾经犯过你可能会犯的大多数错误。）</p> <p><br /> </p> <h2>最后的思考</h2> <p><br /> </p> <p>在我和 Matt 写完最初那篇论文后的几年，持续集成已经成为了软件开发的一个主流方法。ThoughtWorks 的项目很少有不用到它的。我们也能看到世界各地的人们在用持续集成。与极限编程中一些充满争议的实践不同，我很少听到关于持续集成的负面消息。 </p> <p><br /> </p> <p>如果你还没用持续集成，我强烈建议你试一下。如果你已经在做了，可能这篇文章中的某些方法可以帮你得到更好的效果。过去几年中，我们已经了解了很多关于持续集成的知识，我希望还有更多的知识可以让我们学习和提高。</p> <p><div>出自：http://article.yeeyan.org/view/2251/94882</div><br /> </p></div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/355801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-08-04 15:41 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/08/04/355801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hudson-英文介绍</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/08/03/355691.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Wed, 03 Aug 2011 08:57:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/08/03/355691.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/355691.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/08/03/355691.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/355691.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/355691.html</trackback:ping><description><![CDATA[<div>
<h1>What is Hudson?</h1>
<p><span style="float: right;"><a 873x676="" href="http://wiki.hudson-ci.org//download/attachments/753667/1.png"><img src="http://wiki.hudson-ci.org/download/thumbnails/753667/1.png" title="Screenshot 1" alt="" border="0" /></a></span> Hudson monitors executions of repeated jobs, such as building a software project or jobs run by cron. Among those things, current Hudson focuses on the following two jobs:</p>
<ol>
     <li><strong>Building/testing software projects continuously</strong>, just like CruiseControl or DamageControl. In a nutshell, Hudson provides an easy-to-use so-called continuous integration system, making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build. The automated, continuous build increases the productivity.</li>
     <li><strong>Monitoring executions of externally-run jobs</strong>, such as cron jobs and procmail jobs, even those that are run on a remote machine. For example, with cron, all you receive is regular e-mails that capture the output, and it is up to you to look at them diligently and notice when it broke. Hudson keeps those outputs and makes it easy for you to notice when something is wrong.</li>
</ol>
<h1><a name="MeetHudson-Features"></a>Features</h1>
<p>Hudson offers the following features:</p>
<ol>
     <li><strong>Easy installation</strong>: Just <tt>java -jar hudson.war</tt>, or deploy it in a servlet container. No additional install, no database.</li>
     <li><strong>Easy configuration</strong>: Hudson can be configured entirely from its friendly web GUI with extensive on-the-fly error checks and inline help. There's no need to tweak XML manually anymore, although if you'd like to do so, you can do that, too.</li>
     <li><strong>Change set support</strong>: Hudson can generate a list of changes made into the build from CVS/Subversion. This is also done in a fairly efficient fashion, to reduce the load on the repository.</li>
     <li><strong>Permanent links</strong>: Hudson gives you clean readable URLs for most of its pages, including some permalinks like "latest build"/"latest successful build", so that they can be easily linked from elsewhere.</li>
     <li><strong>RSS/E-mail/IM Integration</strong>: Monitor build results by RSS or e-mail to get real-time notifications on failures.</li>
     <li><strong>After-the-fact tagging</strong>: Builds can be tagged long after builds are completed</li>
     <li><strong>JUnit/TestNG test reporting</strong>: JUnit test reports can be tabulated, summarized, and displayed with history information, such as when it started breaking, etc. History trend is plotted into a graph.</li>
     <li><strong>Distributed builds</strong>: Hudson can distribute build/test loads to multiple computers. This lets you get the most out of those idle workstations sitting beneath developers' desks.</li>
     <li><strong>File fingerprinting</strong>: Hudson can keep track of which build produced which jars, and which build is using which version of jars, and so on. This works even for jars that are produced outside Hudson, and is ideal for projects to track dependency.</li>
     <li><strong>Plugin Support</strong>: Hudson can be extended via <a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FPlugins" title="Plugins">3rd party plugins</a>. You can write plugins to make Hudson support tools/processes that your team uses.</li>
</ol>
<h1><a name="MeetHudson-HudsonBestPractices"></a>Hudson Best Practices</h1>
<p>Continuous Integration with automated test execution has seen broad adoption in recent years. The ideas behind Continuous Integration have changed how companies look at Build Management, Release Management, Deployment Automation, and Test Orchestration. This section provides a set of best practices for Hudson - A Continuous Integration Solution to provide executives, business managers, software developers and architects a better sense of the development progress and code quality of projects throughout the development lifecycle. (<a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FHudson%2BBest%2BPractices" title="Hudson Best Practices">View Hudson Best Practices</a>)</p>
<h1><a name="MeetHudson-IntroductoryArticles"></a>Introductory Articles</h1>
<ul>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://linsolas.developpez.com%2Farticles%2Fhudson%2F" rel="nofollow">http://linsolas.developpez.com/articles/hudson/</a> (French)</li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://www.slideshare.net%2Fcarlo.bonamico%2Fcontinuous-integration-with-hudson%2F" rel="nofollow">http://www.slideshare.net/carlo.bonamico/continuous-integration-with-hudson/</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://video.fosdem.org%2F2008%2Fmaintracks%2FFOSDEM2008-hudson.ogg" rel="nofollow">Kohsuke presenting Hudson in FOSDEM 2008</a> (video)</li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://sysadmin.asyd.net%2Fhome%2Ffr%2Fdevel%2Fintegration%2Bhudson" rel="nofollow">Introduction to Hudson</a> (French)</li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://gihyo.jp%2Fdev%2Ffeature%2F01%2Fhudson" rel="nofollow">Introduction and best practice by Kohsuke</a> (Japanese)</li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://xnoccio.com%2F362-hudson-parte-1-introduccion%2F" title="Introducci&#243;n, primeros pasos e instalaci&#243;n de Hudson" rel="nofollow">Introduci&#243;n a Hudson</a> (Spanish)</li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://tcs.java.no%2Ftcs%2Fdownload%2FBD3E404A-2CA7-4170-A3A3-E82892977B04" rel="nofollow">Kohsuke presenting Hudson in JavaZone 2009</a> (video)</li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://docs.hawebs.net%2Fxhtml%2Fhudson%2Ftutorials%2Fmainp.html" rel="nofollow">Hawebs.net docs for Hudson</a> (简体中文 Simplified Chinese)</li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://wiki.hawebs.net%2Findex.php%3Ftitle%3DHudson" rel="nofollow">Hudson Wiki - Hudson 中文维基 </a> (简体中文 Simplified Chinese)</li>
</ul>
<h1><a name="MeetHudson-TestDrive"></a>Test Drive</h1>
<p><a href="https://hudson.dev.java.net/hudson.jnlp" rel="nofollow"><span style="float: left;"><img src="https://hudson.dev.java.net/images/webstart.gif" alt="" border="0" /></span></a> Launch Hudson through Java Web Start for a test drive. Once it launches, visit <a href="http://blog.chinaunix.net/link.php?url=http://localhost%3A8080%2F" rel="nofollow">http://localhost:8080/</a> to get to the dashboard. Any configuration that you do with this Hudson will be stored in ~/.hudson, so your data will survive through Hudson process restart.</p>
<h1><a name="MeetHudson-Installation"></a>Installation</h1>
<p>To run Hudson, minimally you need to have JRE 1.5 or later. After you <a href="http://blog.chinaunix.net/link.php?url=http://hudson-ci.org%2Flatest%2Fhudson.war" rel="nofollow">download hudson.war</a>, you can launch it by <a href="http://blog.chinaunix.net/link.php?url=http://weblogs.java.net%2Fblog%2Fkohsuke%2Farchive%2F2007%2F02%2Fhudson_became_s.html" rel="nofollow">executing <tt>java -jar hudson.war</tt></a>. This is basically the same set up as the test drive, except that the output will go to console, not to a window.</p>
<p>Alternatively, if you have a servlet container that supports Servlet 2.4/JSP 2.0 or later, such as Glassfish, Tomcat 5, JBoss, Jetty 6, etc., then you can deploy <tt>hudson.war</tt> as you would any WAR file. See <a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FContainers" title="Containers">this document</a> for more about container-specific installation instruction.</p>
<p>Once the war file is exploded, run <tt>chmod 755 hudson</tt> in the exploded <tt>hudson/WEB-INF</tt> directory so that you can execute this shell script.</p>
<p>If you're running on Windows you might want to run Hudson as a service so it starts up automatically without requiring a user to log in. One way is to first install Tomcat as a service and then deploy Hudson to it in the usual way.&nbsp; Another way is to use the <a href="http://blog.chinaunix.net/link.php?url=http://wrapper.tanukisoftware.org%2Fdoc%2Fenglish%2Fintroduction.html" rel="nofollow">Java Service Wrapper</a>. However, there may be problems using the service wrapper, because the Main class in Hudson in the default namespace conflicts with the service wrapper main class. Deploying inside a service container (Tomcat, Jetty, etc.) is probably more straightforward, even for developers without experience with such containers.</p>
<p>Also, see how other people are deploying Hudson to get some idea of how to make it fit your environment.</p>
<ul>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FCase%2Bstudy%2Bof%2BSven%2BReimers" title="Case study of Sven Reimers">Case study of Sven Reimers</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FCase%2Bstudy%2Bof%2BKohsuke%2BKawaguchi" title="Case study of Kohsuke Kawaguchi">Case study of Kohsuke Kawaguchi</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FCase%2Bstudy%2Bof%2BRhett%2BSutphin" title="Case study of Rhett Sutphin">Case study of Rhett Sutphin</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FCase%2Bstudy%2Bof%2BNed%2BCollyer" title="Case study of Ned Collyer">Case study of Ned Collyer</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://wiki.hudson-ci.org%2Fdisplay%2FHUDSON%2FCase%2BStudy%2Bof%2BArnaud%2BLacour" title="Case Study of Arnaud Lacour">Case Study of Arnaud Lacour</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://jboss-qa.blogspot.com%2F2007%2F10%2Ftaking-continuous-integration-to.html" rel="nofollow">Case Study of JBoss</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://www.factsandpeople.com%2Ffacts-mainmenu-5%2F22-tibco%2F62-deploying-businessworks-processes-on-tibco-administrator-using-hudson" title="Hudson +Tibco" rel="nofollow">Using Hudson with Tibco BusinessWorks</a></li>
     <li><a href="http://blog.chinaunix.net/link.php?url=http://blog.xuggle.com%2F2009%2F06%2F14%2Feveryone-needs-a-butler%2F" title="Xuggler Hudson Case Study" rel="nofollow">Case Study of Xuggler and Red5</a></li>
     <li>we'd love to list yours here. Please talk to us. </li>
</ul>
</div>
原文：
<div>http://blog.chinaunix.net/space.php?uid=20545494&amp;do=blog&amp;cuid=2322998</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/355691.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-08-03 16:57 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/08/03/355691.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>window/fedora搭建hudson的过程记录（kiki整理）</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/07/23/354889.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Sat, 23 Jul 2011 02:57:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/07/23/354889.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/354889.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/07/23/354889.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/354889.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/354889.html</trackback:ping><description><![CDATA[<div>  <p><span style="font-family: 宋体;">【</span>windows OS<span style="font-family: 宋体;">系统下的：</span> Hudson<span style="font-family: 宋体;">环境搭建过程记录】</span></p>  <p>1. <span style="font-family: 宋体;">安装</span>jakarta-tomcat-5.0.30.exe, <span style="font-family: 宋体;">使用的</span>jdk<span style="font-family: 宋体;">（</span>C:\Program Files\Java\jdk1.6.0_14<span style="font-family: 宋体;">）。</span></p>  <p><span style="font-family: 宋体;">设置</span>HUDSON_HOME<span style="font-family: 宋体;">环境变量，按住</span>windows<span style="font-family: 宋体;">键</span>+Pause<span style="font-family: 宋体;">键快速出现环境变量设置界面。</span> </p>  <p>HUDSON_HOME=C:\hudson_ci\hudson</p>  <p>TOMCAT_HOME=C:\hudson_ci\Tomcat 5.0</p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JAVA_HOME=C:\Program Files\Java\jdk1.6.0_14</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CALSSPATH=C:\ProgramFiles\Java\jdk1.6.0_14\lib\dt.jar;C:\ProgramFiles\Java\jdk1.6.0_14\lib\tools.jar</span></p>  <p>&nbsp;</p>  <p>2. hudson-2.0.0.war&nbsp;copy<span style="font-family: 宋体;">到</span>C:\hudson_ci\Tomcat 5.0\webapps<span style="font-family: 宋体;">目录。</span></p>  <p>&nbsp;</p>  <p>3. <span style="font-family: 宋体;">访问</span><a href="http://localhost:8080/hudson-2.0.0/">http://localhost:8080/hudson-2.0.0/</a><span style="font-family: 宋体;">出现</span>hudson web<span style="font-family: 宋体;">页面。</span></p>  <p>=============================================================</p>  <p><span style="font-family: 宋体;">【</span><span>linux (fedora)</span><span style="font-family: 宋体;">系统下</span>hudson<span style="font-family: 宋体;">搭建过程】</span></p>  <p>&nbsp;</p>  <p>1. fedora<span style="font-family: 宋体;">机器的一些信息</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IP</span><span style="font-family: 宋体;">：</span>172.28.6.36<span style="font-family: 宋体;">（</span>7<span style="font-family: 宋体;">楼时）</span></p>  <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PC</span><span style="font-family: 宋体;">账户：</span>root/123456</p>  <p>&nbsp;</p>  <p>2. <span style="font-family: 宋体;">安装</span>JDK <a href="http://zh.sourceforge.jp/frs/g_redir.php?m=jaist&amp;f=%2Fcrawlzilla%2Fother%2Fjdk-6u21-linux-i586-rpm.bin" target="_blank">jdk-6u21-linux-i586-rpm.bin</a> (JDK6)</p>  <p style="margin-left: 10.5pt;">(<span style="font-family: 宋体;">下载页面</span></p>  <p style="margin-left: 10.5pt;"><a href="http://zh.sourceforge.jp/projects/sfnet_crawlzilla/downloads/other/jdk-6u21-linux-i586-rpm.bin/">http://zh.sourceforge.jp/projects/sfnet_crawlzilla/downloads/other/jdk-6u21-linux-i586-rpm.bin/</a>)</p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">执行：</span>./ jdk-6u21-linux-i586-rpm.bin</p>  <p style="margin-left: 10.5pt;">[root@localhost ~]# vim /etc/profile</p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">在最下面加入如下内容</span></p>  <p style="margin-left: 10.5pt;"><span>JAVA_HOME=/usr/java/jdk1.6.0_21 #</span><span style="font-family: 宋体;">你的</span>jdk<span style="font-family: 宋体;">所在目录</span></p>  <p style="margin-left: 10.5pt;">PATH=$PATH:$JAVA_HOME/bin</p>  <p style="margin-left: 10.5pt;">CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar</p>  <p style="margin-left: 10.5pt;">export JAVA_HOME</p>  <p style="margin-left: 10.5pt;">export PATH</p>  <p style="margin-left: 10.5pt;">export CLASSPATH</p>  <p style="margin-left: 10.5pt;">&nbsp;</p>  <p style="margin-left: 10.5pt;">1) <span style="font-family: 宋体;">马上生效：</span></p>  <p style="margin-left: 10.5pt;">[root@localhost ~]# source /etc/profile</p>  <p style="margin-left: 10.5pt;">3<span style="font-family: 宋体;">）查看是否已生效</span></p>  <p style="margin-left: 31.5pt;">[root@localhost kikitest]# java -version</p>  <p style="margin-left: 31.5pt;">java version "1.6.0_21"</p>  <p style="margin-left: 31.5pt;">Java(TM) SE Runtime Environment (build 1.6.0_21-b06)</p>  <p style="margin-left: 31.5pt;">Java HotSpot(TM) Server VM (build 17.0-b16, mixed mode)</p>  <p>3. <span style="font-family: 宋体;">安装</span>Tomcat6</p>  <p style="margin-left: 21pt;">tar xzvf &nbsp;apache-tomcat-6.0.32.tar.gz</p>  <p>4. </p>  <p style="margin-left: 21pt;">PS:</p>  <p style="margin-left: 21pt;">1.<span style="font-family: 宋体;">）</span> <span style="font-family: 宋体;">之前试过</span>2<span style="font-family: 宋体;">次</span>jdk<span style="font-family: 宋体;">和</span>tomcat6<span style="font-family: 宋体;">都安装好的情况，每次浏览</span>hudson<span style="font-family: 宋体;">就出现内存泄露的情况，是因为</span>hudson-2.0.1.war<span style="font-family: 宋体;">和</span>hudson-2.0.0.war<span style="font-family: 宋体;">虽然在</span>windows<span style="font-family: 宋体;">环境访问</span>OK<span style="font-family: 宋体;">，但是在</span>fedora<span style="font-family: 宋体;">中不兼容，于是从</span>hudson<span style="font-family: 宋体;">官网下了个</span>hudson.war<span style="font-family: 宋体;">，部署到</span>webapps<span style="font-family: 宋体;">最终搞定。</span></p>  <p style="margin-left: 21pt;">2.<span style="font-family: 宋体;">）</span></p>  <p style="margin-left: 21pt;">yum list | grep tomcat<span>&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">列出</span>tomcat<span style="font-family: 宋体;">可安装包</span></p>  <p style="margin-left: 21pt;">yum -y install tomcat5<span>&nbsp;&nbsp; //</span><span style="font-family: 宋体;">安装</span>tomcat5</p>  <p style="margin-left: 21pt;">yum remove tomcat5<span>&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">卸载</span>tomcat5</p>  <p style="margin-left: 21pt;">yum remove java <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">卸载所有</span>JAVA</p>  <p style="margin-left: 21pt;">rpm &#8211;qa | grep jdk<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体;">查找</span>jdk</p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">查看方法</span>:rpm &#8211;qa |grep &#8211;I java</p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">卸载方法</span>:rpm &#8211;e &#8211;nodeps java*<span style="font-family: 宋体;">包名</span></p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">将</span>jdk-6u21-linux-i586-rpm.bin<span style="font-family: 宋体;">给予可执行权限</span></p>  <p style="margin-left: 10.5pt;"><span style="font-family: 宋体;">修改权限：</span><span>chmod u+x jdk-6u21-linux-i586-rpm.bin</span></p>  <p style="margin-left: 21pt;">&nbsp;</p>  <p>&nbsp;</p>  <p>&nbsp;</p>  <p>&nbsp;</p>  </div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/354889.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-07-23 10:57 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/07/23/354889.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SVN钩子集合-kiki整理</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354874.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 22 Jul 2011 11:09:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354874.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/354874.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/354874.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/354874.html</trackback:ping><description><![CDATA[<div>  <p>SVN<span style="font-family: 宋体;">里的钩子脚本（</span>T&amp;W<span style="font-family: 宋体;">）</span></p>  <p><span style="font-family: 宋体;">【</span>post-commit<span style="font-family: 宋体;">】</span>S204<span style="font-family: 宋体;">提交之后邮件通知</span></p>  <p>#!/bin/sh</p>  <p>REPOS="$1"</p>  <p>REV="$2"</p>  <p>DOMAIN=twsh.com</p>  <p>PROJECTNAME=`basename $REPOS`</p>  <p>&nbsp;</p>  <p>/urr/local/ActivePerl/site/bin/svnnotify </p>  <p style="margin-left: 10.5pt;">--repos-path "$1" </p>  <p style="margin-left: 10.5pt;">--revision "$2" </p>  <p style="margin-left: 10.5pt;">--to $PROJECTNAME@$DOMAIN </p>  <p style="margin-left: 10.5pt;">--user-domain $DOMAIN </p>  <p style="margin-left: 10.5pt;">--smtp 10.58.100.8 </p>  <p style="margin-left: 10.5pt;">--smtp-user svn@twsh.com &#8211;</p>  <p style="margin-left: 10.5pt;">-smtp-pass 15021151553 </p>  <p style="margin-left: 10.5pt;">--subject-prefix [SVN:$PROJECTNAME] -g en_US </p>  <p style="margin-left: 10.5pt;">--handler "HTML::ColorDiff" </p>  <p style="margin-left: 10.5pt;">--with-diff </p>  <p style="margin-left: 10.5pt;">--diff-encoding GBK</p>  <p>&nbsp;</p>  <p><span style="font-family: 宋体;">【</span>post-commit<span style="font-family: 宋体;">】</span>DSL<span style="font-family: 宋体;">库提交之后的邮件通知（</span>DSL<span style="font-family: 宋体;">是一个大库，里面包含很多小项目库）</span></p>  <p>.</p>  <p>#!/bin/sh</p>  <p>REPOS="$1"</p>  <p>REV="$2"</p>  <p>DOMAIN=twsh.com</p>  <p>PROJECTNAME=`basename $REPOS`</p>  <p>&nbsp;</p>  <p>PATHFILTER='4.02L.03_CT_BCM963293+TK3715_E8C_EPON\|Gewv2.3L19A-B2-V03'</p>  <p>SVNLOOK=/usr/bin/svnlook</p>  <p>&nbsp;</p>  <p><span>if ( $SVNLOOK dirs-changed -r $REV "$REPOS" | grep "$PATHFILTER" &gt; /dev/null ); then</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp; </span>/urr/local/ActivePerl/site/bin/svnnotify \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--repos-path "$REPOS" \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--revision "$REV" \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--to ponsw@twsh.com \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--user-domain $DOMAIN \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--smtp 10.58.100.8 \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--smtp-user svn@twsh.com \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--smtp-pass 15021151553 \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--subject-prefix [SVN:$PROJECTNAME] \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>-g en_US \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--handler "HTML::ColorDiff" \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--with-diff \</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--diff-encoding GBK</span></p>  <p>fi</p>  <p>&nbsp;</p>  <p><span style="font-family: 宋体;">【</span>pre-commit<span style="font-family: 宋体;">】提交之前</span>LOG<span style="font-family: 宋体;">限制</span></p>  <p>#!/bin/sh</p>  <p>REPOS="$1"</p>  <p>TXN="$2"</p>  <p>&nbsp;</p>  <p>SVNLOOK=/usr/bin/svnlook</p>  <p>&nbsp;</p>  <p><span>if ( $SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" &gt; /dev/null ); then</span></p>  <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit 0;</span></p>  <p>fi</p>  <p>&nbsp;</p>  <p><span>echo "Empty log message not allowed. Commit aborted!" &gt;&amp;2</span></p>  <p>exit 1;</p>  <p>&nbsp;</p>  <p><span style="font-family: 宋体;">【</span>pre-revprop-chang<span style="font-family: 宋体;">】实例验证过，可修改</span>:author and log message.</p>  <p>#!/bin/sh</p>  <p>REPOS="$1"</p>  <p>REV="$2"</p>  <p>USER="$3"</p>  <p>PROPNAME="$4"</p>  <p>ACTION="$5"</p>  </div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/354874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-07-22 19:09 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hudson的一些文章收集</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354868.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 22 Jul 2011 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354868.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/354868.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354868.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/354868.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/354868.html</trackback:ping><description><![CDATA[1. http://zhaohaihua.blog.163.com/blog/static/271629820116142913431/<br />2. <div>http://zhaohaihua.blog.163.com/blog/static/271629820116142913431/</div>3. <div>http://doc.open-open.com/view/3892a4e792f04a3880da588f6369b52e</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/354868.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-07-22 17:29 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/07/22/354868.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>持续集成工具hudson</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/07/18/354527.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Mon, 18 Jul 2011 05:16:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/07/18/354527.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/354527.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/07/18/354527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/354527.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/354527.html</trackback:ping><description><![CDATA[<div><h4><div>原文:http://www.blogjava.net/xiaodu/archive/2008/07/08/213298.html</div></h4><h4>一.什么是持续集成</h4> <h4><span style="font-family: 宋体;">持续集成的核心概念</span></h4> <h4><span style="font-family: 宋体;"><span><span style="font-size: 8pt;"><span style="font-size: 10pt;">CI  过程会经常构建软件组件；在许多情况下，每当源代码存储库（比如 Subversion 或  ClearCase）中的代码发生变化时，都要构建软件组件。CI  的好处是：经常构建软件可以确保尽早遇到问题（比如代码缺陷），避免问题在软件开发周期晚期变复杂时才被发现。</span></span></span></span></h4> <h4><a name="N10122"><span style="font-family: 宋体;"><span><span style="font-size: 8pt;"><span style="font-size: 10pt;">工具与过程</span></span></span></span></a></h4> <h4><span style="font-family: 宋体;"><span><span style="font-size: 8pt;"><span style="font-size: 10pt;">尽管 CI 实际上是一个过程，但是<em>持续集成</em>  这个词常常与一个或多个工具相关联。在本教程中，讲解如何安装、配置和使用 Hudson 作为 CI 服务器，但是要记住，CI  远不只是个工具。实际上，使用的工具可能是 CI 比较次要的方面，因为 CI  工具所做的仅仅是在代码存储库中探测到修改时运行构建。构建过程本身比用来运行它的工具重要得多。</span></span></span></span></h4> <h4><a name="N1012F"><span style="font-family: 宋体;"><span><span style="font-size: 8pt;"><span style="font-size: 10pt;">开始使用 CI</span></span></span></span></a></h4> <h4><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">开始使用 CI 需要三个组件： </span></span></span></h4> <ul><li><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;"><strong>用 Ant 或 Maven 等工具建立的自动构建过程 </strong></span></span></span>     </li><li><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;"><strong>一个代码存储库，比如 CVS 或 Subversion </strong></span></span></span>     </li><li><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;"><strong>一个 CI 服务器，比如 Hudson，但是 cron 作业也可以满足需要</strong> </span></span></span></li></ul> <h4><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">我们来详细讨论这些组件。</span></span></span></h4> <h4><a name="N10147"><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">自动的构建</span></span></span></a></h4> <h4><span style="font-family: 宋体;"><span><span style="font-size: 8pt;"><span style="font-size: 10pt;">CI  过程会经常集成软件，这需要通过构建来完成。在 Java 环境中，Ant 是常用的构建平台。可以使用 Ant  可靠地自动执行编译、测试等任务，甚至可以执行软件检查和部署。在掌握了 CI 的所有组件之后，您会发现构建策略是成功的 CI  过程最重要的方面。如果缺少适当的构建过程，CI 就难以发挥作用。</span></span></span></span></h4> <h4><a name="N10150"><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">源代码管理</span></span></span></a></h4> <h4><span style="font-family: 宋体;"><span><span style="font-size: 8pt;"><span style="font-size: 10pt;">为 了让 CI 正确地发挥作用，需要一个源代码管理（SCM）系统或存储库，比如 Subversion 或 CVS。CI 服务器向 SCM  存储库查询代码修改。在找到修改时，CI 服务器执行签出（即更新本地沙箱）并执行构建。除了执行得更频繁之外，构建过程与在本地环境中执行的构建相同。  </span></span></span></span></h4> <h4><a name="N10159"><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">CI 服务器</span></span></span></a></h4> <h4><span style="font-family: 宋体;"><span><span style="font-size: 8pt;"><span style="font-size: 10pt;">对 于成功的 CI 过程，需要用一个自动的过程监视 SCM 存储库并在探测到修改时运行构建，这也非常重要。对于 Java 平台，有许多可用的 CI  服务器，包括开放源码软件和商业产品。它们的基本配置都很相似，适合监视特定的 SCM 并在探测到修改时运行构建。所有 CI  服务器都有自己的优缺点。Hudson 尤其让人感兴趣，因为它容易配置而且具有强大的插件，这些插件可以显示测试结果趋势等信息。<br /> <p>二.Hudson 简介</p> <p><span style="font-size: 10pt;">Hudson 是一种革命性的开放源码 CI 服务器，它从以前的 CI  服务器吸取了许多经验教训。Hudson 最吸引人的特性之一是它很容易配置：很难找到更容易设置的 CI 服务器，也很难找到开箱即用特性如此丰富的  CI 服务器。Hudson 容易使用的第二个原因是它具有强大的插件框架，所以很容易添加特性。例如，一个 Hudson 插件可以随时间的推移跟踪  FindBugs 和代码覆盖。它还可以报告测试结果的趋势（来自 JUnit 或 TestNG）以及构建结果和对应的执行时间。 </span></p> <p><span style="font-size: 10pt;">Hudson 需要运行 Java 5。如果需要使用 Hudson 附带的嵌入式容器（Winstone）之外的其他容器，那么只需使用一种 Servlet 2.4 容器。对于大多数情况，Winstone 就足够了。<br /> </span></p> <p>三.Hudson使用</p> <p><span style="font-size: 10pt;">CI 过程的最后一个方面是 CI 服务器本身。CI  服务器在整个开发过程中的主要作用是控制者：当服务器在代码存储库中探测到修改时，它将运行构建的任务委托给构建过程本身。如果构建失败了，那么 CI  服务器将通知相关方面，然后继续监视存储库。它的角色看起来是被动的；但是，它是快速反映问题的关键。</span></p> <p><a name="N10326"><span style="font-size: 10pt;">安装 Hudson</span></a></p> <p><span style="font-size: 10pt;">使用 Hudson 的主要好处之一是它的设置很简单。在最简单的情况下，Hudson 只需要两个步骤：</span></p> <ol><li><span style="font-size: 10pt;">下载最新的版本（它打包为一个 WAR 文件）。 hudson官方网址:https://hudson.dev.java.net/</span>     </li><li><span style="font-size: 10pt;">运行 <code>java -jar hudson.war</code>。 </span></li></ol> <p><span style="font-size: 10pt;">这样就可以了。因为下载的是一个 WAR 文件，所以如果愿意，可以将它部署在 Tomcat 或 JBoss 等容器中。这完全由您自己决定。当然，Hudson 假设在安装它的机器上运行着 Java 5，而且如果定义了 <code>JAVA_HOME</code> 环境变量，Hudson 就会使用它。（正如前面提到的，Hudson 需要 Java 5。）</span></p> <p><span style="font-size: 10pt;">在安装并运行 Hudson 之后（将 WAR 文件部署到 servlet 容器或从命令行执行 <code>java -jar hudson.war</code>），启动浏览器并访问默认安装位置。如果通过命令行运行 Hudson 而且您在本地机器上，那么可以访问 <code>http://localhost:8080/</code>。</span></p></span></span></span></span> </h4> <img alt="" src="../../images/blogjava_net/xiaodu/b.jpg" width="1000" border="0" height="591" /><br /> <strong><span style="font-size: 10pt;">如果一切正常（实际上不太可能出问题），应该会看到图 2 所示的 Hudson 启动页面。</span><br /> </strong> <p><a name="N10360"><span style="font-size: 10pt;"><strong>配置 Hudson</strong></span></a></p> <p><span style="font-size: 10pt;"><strong>如果访问 Hudson 主页的本地实例并单击左上角的 Manage Hudson 链接，应该会看到图 3 所示的可配置选项列表。</strong></span></p> <a name="figure3"><strong><span style="font-size: 10pt;">图 3. 配置 Hudson 非常容易</span></strong></a><br /> <img alt="" src="../../images/blogjava_net/xiaodu/aa.jpg" width="1000" border="0" height="591" /><br /> <p><span style="font-size: 10pt;"><strong>参数说明:<br /> system.message 填写一些说明信息<br /> Quiet period:hudson定时构建工程的时间(秒)<br /> &nbsp;<label>Enable security</label>:设置hudson登陆的规则(默认为匿名登陆)<br /> TCP port for JNLP slave agents:不了解JNLP不敢胡写总之就是三种方式:固定(fixed) 随机(Radom) 不使用(disabled),使用固定时可以填入JNLP信息</strong></span></p> <span style="font-size: 10pt;"><strong>security realm:可以使用中间件容器,数据库,LDAP来验证安全,具体怎样用法没用过,以后会有更新,研究中.<br /> authorized:可以设置身份的验证方法:系统用户,匿名用户,自定义用户,还有继承用户(此处也在研究中,建议使用匿名用户)<br /> JDK installations:设置JDK的安装路径<br /> Shell executable:设置window shell命令<br /> Ant installation:设置ant 的安装路径<br /> mave installation设置mave的安装路径<br /> cvs executable:设置cvsnt执行进程的路径(cvs.exe)<br /> .cvspass file:设置cvsnt管理员文件的路径(passwd文件)<br /> e-mail notification:设置当发生错误时发送的邮箱地址<br /> hudson url:就是hudson的默认地址<br /> </strong></span> <p><span style="font-size: 10pt;"><strong>还可以配置服务器的其他几个方面，比如向 Hudson  提供一个电子邮件服务器的位置，以便在构建失败时接收电子邮件。根据您的组织设置电子邮件的方式，可能需要让系统管理员帮助设置这个特性。设置电子邮件并 不是必需的；Hudson 还支持以 RSS  作为通知机制，对于某些人来说，这种方式比电子邮件更好。究竟选择哪些通知机制完全取决于您。（注意，这里说的是  &#8220;哪些&#8221;，也就是说，可以同时使用多种通知机制！）</strong></span></p> <span style="font-size: 10pt;"> <p><a name="N103A5"><span style="font-size: 10pt;"><strong>在 Hudson 中配置项目</strong></span></a></p> <span style="font-size: 10pt;"> <p><span style="font-size: 10pt;"><strong>既然 Hudson 已经能够与 SCM 存储库通信了，就该配置项目了。这个示例所用的项目称为 <code>solar-ci</code>。在 Hudson 主页上单击左上角的 New Job 链接。这时会看到图 5 所示的屏幕：</strong> </span></p> <img alt="" src="../../images/blogjava_net/xiaodu/3.jpg" width="1000" border="0" height="591" /><br /> <br /> <p><strong><span style="font-family: 宋体;">该页面可以使我们通过</span>hudson<span style="font-family: 宋体;">来管理</span>cvs<span style="font-family: 宋体;">里的一个对应的工程</span></strong></p> <p><strong>Project name:<span style="font-family: 宋体;">工程名称</span></strong></p> <p><strong>Description:<span style="font-family: 宋体;">描述信息</span></strong></p> <p><strong>Discard build:<span style="font-family: 宋体;">如果选择此项可以设置</span>build<span style="font-family: 宋体;">记录保存的天数</span>,<span style="font-family: 宋体;">或者</span>build<span style="font-family: 宋体;">记录保存的数理</span>,<span style="font-family: 宋体;">或者只保存最新的</span>build<span style="font-family: 宋体;">记录</span>,<span style="font-family: 宋体;">一般不需填写</span></strong></p> <p><strong>Advance project options:<span style="font-family: 宋体;">可以设置</span>hudson<span style="font-family: 宋体;">定时检查</span>cvs<span style="font-family: 宋体;">工程的时间间隔</span>,<span style="font-family: 宋体;">还可以指定</span>cvs<span style="font-family: 宋体;">工程</span>check out<span style="font-family: 宋体;">到本地的工程路径</span>,<span style="font-family: 宋体;">一般不需要填写</span></strong></p> <p><strong>Source code management:<span style="font-family: 宋体;">我们选择</span>cvs<span style="font-family: 宋体;">将出现以下参数</span>:</strong></p> <strong><span style="font-size: 10.5pt; font-family: 'Times New Roman';">Cvsroot:</span><span style="font-size: 10.5pt; font-family: 宋体;">将写</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">cvs</span><span style="font-size: 10.5pt; font-family: 宋体;">登陆字符串</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">,</span><span style="font-size: 10.5pt; font-family: 宋体;">格式</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">(</span><tt><span style="font-size: 12pt;">:protocol:user:password@host:path),</span><span style="font-size: 12pt;">例如:</span></tt> <tt><span style="font-size: 12pt;">:pserver:cvsadmin:1@127.0.0.1:2401:/CVSNT/Repository,</span><span style="font-size: 12pt;">使用cvs必填</span></tt><br /> &nbsp; </strong> <p><tt><span style="font-size: 12pt;"><strong>Modules:</strong></span></tt><strong><tt><span style="font-size: 12pt;">填写<span>cvs仓库下的具体工程名, 使用cvs必填</span></span></tt></strong></p></span><strong></strong> <strong><tt><span style="font-size: 12pt;">Branch:</span><span style="font-size: 12pt;">填写分支名称,也可以勾选this is a tag,no a branch指定标记名称</span></tt><br /> &nbsp; </strong> <p><tt><span style="font-size: 12pt;"><strong>选择subversion可以进行相应的subversion设置</strong></span></tt></p> <p><strong><tt><span style="font-size: 12pt;">Build trigger</span></tt><tt><span style="font-size: 12pt;">可以设置hudson自动执行的一些动作,build after others projects are built指定hudson构建完成后需要继续构建的工程名</span></tt></strong></p> <p><strong><tt><span style="font-size: 12pt;">Build periodically </span></tt><tt><span style="font-size: 12pt;">根据hudson定义的语法规则来设定自动构建工程的时间间隔</span></tt></strong></p> <p><tt><span style="font-size: 12pt;"><strong>Post-build actions</strong></span></tt><tt><span style="font-size: 12pt;"><strong> </strong></span></tt></p> <p><tt><span style="font-size: 12pt;"><strong>设置一些构建完成后的动作,如放邮件,打包,产生测试报告,产生java doc 等.</strong></span></tt></p> <p><tt><span style="font-size: 12pt;"><strong>点击ok保存设置</strong></span></tt></p> <strong>使用hudson<br /> <tt><span style="font-size: 12pt;">进入刚配置的项目,可以在左侧build history看到历史的build记录,点击build now 可以手动执行构建动作,完成后可以通过记录标记的颜色来看是否出错,红色有错,蓝色成功.点击记录查看详细信息,如果有变化hudson将列出类信息</span></tt></strong></span> <br /> <br /> <strong>elipse插件应用<br /> eclipse updatesite:http://code.google.com/p/hudson-eclipse/<br /> 重新打开eclipse在windows-&gt;preferences下将出现hudson选项,设置默认的hudson url保存.<br /> 然后选择windows-&gt;open view打开hudson view<br /> 如果你己经配置hudson项目将列出hudson的项目名称,右键菜单可以看到所有的执行菜单,使用还是很方便的,希望大家来完善这篇文章.<br />原文：<div>http://www.blogjava.net/xiaodu/archive/2008/07/08/213298.html</div><div></div><br /></strong></div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/354527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-07-18 13:16 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/07/18/354527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>项目中的软件质量管理</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353661.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Mon, 04 Jul 2011 09:51:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353661.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/353661.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353661.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/353661.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/353661.html</trackback:ping><description><![CDATA[<div>  <p>提起<a href="http://software.it168.com/" target="_blank" title="软件"><span style="color: black;">软件</span></a>质 量管理，人们更多地会想起<span>ISO9001、CMM、CMMI这些&#8220;质量管理圣经&#8221;。但国内企业做了这么多年的质量认证，却没有使软件质量有大幅度地提高。 实际上，很多企业通过ISO9001、CMM、CMMI等质量认证的目的就不是为了提高质量：有的企业是为了跟风，有的企业则是为了向客户展示证书。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 在很多软件企业里，软件质量管理在内部开发产品时做的相对较好：因为产品开发通常在各个软件企业的研发中心进行，涉及的人员以内部为主，进度压力相对较 小，可以投入时间和精力来开展软件质量管理。对于有客户进行参与的软件实施项目，多数企业为了节省成本和赶进度，往往会忽略质量管理，最后导致软件质量很 差&#8212;&#8212;投产后的软件经常会被用户发现很多Bug。实际上，在项目实施中开展质量管理工作更加重要，因为产品上线后的质量问题往往意味着更大的投入。本文将 和读者一起探讨软件项目实施中如何开展质量管理工作。 </span></p>  <p><span>&nbsp;&nbsp;&nbsp;<strong><span style="font-family: 宋体;"> 1. </span></strong></span><strong><span style="font-family: 宋体;">质量管理主要内容</span></strong></p>  <p><span>&nbsp;&nbsp;&nbsp; 在探讨项目实施中开展软件质量管理工作前，我们先回顾一下质量管理的基础知识。质量管理主要包括三个过程：质量计划制定、质量保证和质量控制。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 质量计划：是质量管理的第一过程域，它主要指依据公司的质量方针、产品描述以及质量标准和规则等制定出来实施方略，其内容全面反应用户的要求，为质量小组 成员有效工作提供了指南，为项目小组成员以及项目相关人员了解在项目进行中如何实施质量保证和控制提供依据，为确保项目质量得到保障提供坚实的基础。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 质量保证：是贯穿整个项目全生命周期的有计划和有系统的活动，经常性地针对整个项目质量计划的执行情况进行评估、检查与改进等工作，向管理者、顾客或其他方提供信任，确保项目质量与计划保持一致。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 质量控制：是对阶段性的成果进行测试、验证，为质量保证提供参考依据。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 在软件实施项目中，质量保证对应于技术评审与过程检查，质量控制对应于软件测试等工作，如图1所示。</span></p>  <p align="center"><span><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image001.jpg" width="337" border="0" height="260"  alt="" /></span></p>  <p align="center"><span><span><br /> </span>图1 全面软件质量管理模型 </span></p>  <p><strong><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 2. </span></strong><strong><span style="font-family: 宋体;">项目中质量管理的原则</span></strong></p>  <p><span>&nbsp;&nbsp;&nbsp; 在软件项目实施中，由于进度和成本两大因素的影响，它的质量管理与产品开发有着很大的差别。因此，在项目实施中做好质量管理工作应该坚持自己的原则。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 我们先看一下国内企业实施软件项目的一些特征：</span></p>  <p><span>&nbsp;&nbsp;&nbsp; &#8220;进度高于一切&#8221;可以说是国内企业实施项目的最大特点，而&#8220;为了短期利益不惜愚弄客户&#8221;、不重视质量、喜欢追究责任则成了这道&#8220;靓丽&#8221;风景上的点缀。回顾 国内很多IT热门领域，可以发现多是大家看好某个领域后就会&#8220;一哄而上&#8221;，然后进行低价为主的恶性竞争，结果是搞得自己没有能力来重视质量，而为了生存， 还要拼命的加班赶进度，最后形成一个怪圈。可以说在很多IT领域，国内软件企业为自己精心打造了无数个这样的&#8220;怪圈&#8221;。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 国内的企业要想挑出&#8220;怪圈&#8221;，最根本的办法是从源头做起：即从项目一开始就开始重视产品质量，因为质量是根本，好的质量加上好的服务才能拥有更强的市场竞 争能力。同时也应该认识到质量、进度、成本是相辅相成的，决不可以忽略任何一个方面。过分重视质量，必然会耽误进度和加大成本投入，甚至会失去市场机会； 过分节约成本、抢进度又会降低质量，质量不好的产品肯定不会在市场上走多远。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 根据作者多年的经验，IT企业要想在软件项目实施中做好质量工作，应该坚持下面几个重要的原则：</span></p>  <p><span>&nbsp;<strong><span style="font-family: 宋体;">&nbsp;&nbsp; &#183;</span></strong></span><strong><span style="font-family: 宋体;">不但要主观认识到质量的重要性，同时还要落实到行动中。</span></strong></p>  <p><span>&nbsp;&nbsp;&nbsp; 软件质量管理的重要性已经逐渐被国内的IT企业认可，但是要落实到具体的项目实施工作中，并通过它提高软件质量，还有一段很长的路要走。因为几乎所有的软件公司都灌输着&#8220;进度高于一切&#8221;的思想，只要是为了赶进度和发布产品，所有影响进度的工作都可以忽略。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 因此，把想法落实到实际工作中是做好软件质量管理的第一原则。</span></p>  <p><span>&nbsp;&nbsp;&nbsp;<strong><span style="font-family: 宋体;"> &#183;</span></strong></span><strong><span style="font-family: 宋体;">树立提高质量就是尊重客户的思想。</span></strong></p>  <p><span>&nbsp;&nbsp;&nbsp; 可以说，目前很多公司都有&#8220;愚弄客户&#8221;的嫌疑，不管是有心的还是无意的。很多公司实施项目时只要能拿到&#8220;钱&#8221;就达到目的了，因此也就不在乎是否掩盖缺陷和敷衍客户。至于后果，那是以后的事情了。</span></p>  <p><span>&nbsp;&nbsp;&nbsp; 在软件产业发达的今天，已经是客户的买方市场，客户永远会选择质量和服务都表现良好的产品来满足自己的需求。因此，我们应该尊重客户，把客户放在&#8220;上帝&#8221;的位置上，认证做好质量。</span></p>  <p><span>&nbsp;&nbsp;<strong><span style="font-family: 宋体;">&nbsp; &#183;</span></strong></span><strong><span style="font-family: 宋体;">建立规范的质量保证体系，逐步使软件开发进入良性循环状态。</span></strong></p>  <p><span>&nbsp;&nbsp;&nbsp; 在没有开发规范的前提下，软件团队是不能开发出高质量软件的。因此软件团队一定要建立规范的质量保证体系，同时把规范体系逐步落实到工作中。如果急功近利，不但会做很多浪费人力和物力的无效工作，还会给客户留下不好的印象。</span></p>  <p align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">3. </span></strong><strong><span style="font-size: 12pt; font-family: 宋体;">项目中质量管理开展方法</span></strong></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">要想在项目中开展质量管理，就不能脱离中国</span><a href="http://software.it168.com/" target="_blank" title="软件"><span style="font-size: 12pt; font-family: 宋体; color: black;">软件</span></a><span style="font-size: 12pt; font-family: 宋体;">企业实施项目的现状：工期短、任务重、利润低。在这种背景下，开展全面质量管理是不太现实的，只能根据每个项目的进度和成本实际情况来进行合理的投入，否则质量投入过大不但耽误进度，还会影响到企业利润，这是本末倒置的。在项目实施中，通常是最大限度地去提高质量。</span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">在图<span>1的全面软件质量管理模型中，我们可以看出质量管理有三大类：技术评审、过程检查、软件测试，项目实施中的软件质量管理仍然围绕着这三类工作来开展。 由于很多项目实施中没有专门的质量人员，这个时候项目经理应该更多地去组织技术评审和安排人员进行过程检查，可以考虑让软件测试人员承担一些质量保证工 作，因为测试人员通常是必不可少的。</span></span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">下面探讨一下每类工作如何开展。</span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp;<strong> &#183;</strong></span><strong><span style="font-size: 12pt; font-family: 宋体;">项目实施中的技术评审</span></strong><span><span style="font-size: 12pt; font-family: 宋体;"><br /> &nbsp;&nbsp;&nbsp; <br /> &nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; font-family: 宋体;">技术评审可以把一些软件缺陷消灭在代码开发之前，尤其是一些架构方面的缺陷。在项目实施中，为了节省时间应该优先对一些重要环节进行技术评审，这些环节主 要有：项目计划、软件架构设计、数据库逻辑设计、系统概要设计等。如果时间和资源允许，可以考虑适当增加评审内容。</span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">项目实施中技术评审如表<span>1所示：</span></span></p>  <p align="center"><span style="font-size: 12pt; font-family: 宋体;">表<span>1 项目实施中技术评审</span></span></p>  <p align="center"><span style="font-size: 12pt; font-family: 宋体;"><img src="file:///C:/DOCUME%7E1/xufuli/LOCALS%7E1/Temp/msohtml1/01/clip_image002.jpg" width="561" border="0" height="311"  alt="" /></span></p>  <p align="left"><span><span style="font-size: 12pt; font-family: 宋体;">&nbsp;<br /> &nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; font-family: 宋体;">很多软件项目由于性能等诸多原因最后导致失败，实际上都是由于设计阶段技术评审做的不够。一味地节省时间、关键工作仅由某几个人执行、整个项目的成败依赖于某些<span>&#8220;个人英雄&#8221;等做法是十分错误的，重要的技术评审工作是不可以忽略的。</span></span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp;<strong> &#183;</strong></span><strong><span style="font-size: 12pt; font-family: 宋体;">项目实施中的过程检查</span></strong></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">项目经常延期是中国软件企业实施很多项目时候的特点，因此项目实施中的过程检查重点是<span>&#8220;进度检查&#8221;。在实际工作中，很多项目都是启动一段时间后就开始不停 地加班，使整个团队处于疲惫状态，导致工作效率低下，最后把项目计划丢在一边。对于这种情况，比较好的做法是不断地检查项目计划与实际进度是否存在偏差， 如果存在偏差则找出问题的根源，然后消除引起问题的因素，例如可以调整进度安排或者增加人力投入，这样就避免了问题不断放大。</span></span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">版本检查在项目实施中也需要特别注意，因为版本混乱会带来很大麻烦，尤其进行测试的时候。此外，项目实施时候也应该注意文档检查，尤其是一些关键文档的质量，例如接口文档、用户手册等。</span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;<strong>&nbsp;&nbsp; &#183;</strong></span><strong><span style="font-size: 12pt; font-family: 宋体;">项目实施中的软件测试</span></strong></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">项目实施相关的全部质量管理工作中，软件测试的工作量最大。由于很多项目在实施中非常不规范，因此软件测试一定要把好关。软件测试应该重点做好测试用例设计、功能测试、性能测试、缺陷管理等工作。</span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span><span style="font-size: 12pt; font-family: 宋体;">测试用例设计：虽然项目实施中没有太多时间来设计测试用例，但是这个环节是必不可少的。项目实施中设计测试用例应该根据进度安排，优先设计核心应用模块或 核心业务相关的测试用例。设计测试用例的时候可以不设计的特别完善，基本目标是列出测试重点，对测试执行起良好地指导作用，这个时候的测试用例更像是&#8220;测 试大纲&#8221;。</span></span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">能测试：软件首先应该从功能上满足用户需求，因此功能测试是质量管理工作中的重中之重。功能测试在产品试运行前一定要开展好，否则将会发生<span>&#8220;让用户来执行测试&#8221;的情况，后果非常严重。</span></span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span><span style="font-size: 12pt; font-family: 宋体;">性能测试：性能测试是经常容易被忽略的测试。在实施项目过程中，应该充分考虑软件地性能，运行较慢的软件仍然不会为用户所接受。性能测试可以根据用户对软 件的性能需求来开展，通常系统软件和银行、电信等特殊行业应用软件对性能要求较高，应该尽早进行，这样更易于早解决问题。</span></span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">缺陷管理：缺陷跟踪与管理工作也经常被忽略，很多问题会被遗忘，直到客户再次发现。建议测试人员在项目实施中仍然采用一些工具进行缺陷管理与跟踪，保证任何缺陷都得到妥善的处理。</span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">此外，对于一些项目，如果实在没有测试人员，可以考虑让开发人员互相进行测试，这样也可以发现很多缺陷。</span></p>  <p align="left"><span style="font-size: 12pt; font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt; font-family: 宋体;">项目实施中的质量管理工作是非常复杂的，存在很多不可以控制的因素，例如没有质量人员、测试环境不具备等。因此，项目实施中的质量管理原则应该是<span>&#8220;最大限度地去提高质量&#8221;。只有这样，才能更好地利用现有资源尽可能地提高质量。</span></span></p>      <p>&nbsp;</p>  </div>原文：http://tech.it168.com/d/2008-06-29/200806291358627_1.shtml<div>http://tech.it168.com/d/2008-06-29/200806291358627_1.shtml</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/353661.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-07-04 17:51 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353661.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有效的软件质量管理</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353660.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Mon, 04 Jul 2011 09:46:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353660.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/353660.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353660.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/353660.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/353660.html</trackback:ping><description><![CDATA[<div><strong><span style="font-size: medium;">一、引言</span></strong><br />随着社会信息化水平的不断提高，信息 行业急速膨胀，信息企业快速成长，随之带来的信息市场竞争激烈，企业为了求生存，满足客户要求则成为各行各业的首要责任。依赖于质量、成本和进度的客户满 意度，质量则是重点支撑之一，这样要求我们对质量管理需要加强认识。我们都知道pmbok把项目管理划分为9个知识领域，即范围管理、时间管理、成本管 理、质量管理、人力资源管理、沟通管理、采购管理、风险管理和综合管理。质量管理作为9大知识领域之一，可见其重要性。<br /><br />   质量管理包括：质量计划编制、质量保证和质量控制三个过程域。质量计划是质量管理的第一过程域，它主要结合各个公司的质量方针，产品描述以及质量标准和规 则通过收益、成本分析和流程设计等工具制定出来实施方略，其内容全面反应用户的要求，为质量小组成员有效工作提供了指南，为项目小组成员以及项目相关人员 了解在项目进行中如何实施质量保证和控制提供依据，为确保项目质量得到保障提供坚实的基础。质量保证则是贯穿整个项目全生命周期的有计划和有系统的活动， 经常性地针对整个项目质量计划的执行情况进行评估、检查与改进等工作，向管理者、顾客或其他方提供信任，确保项目质量与计划保持一致。质量控制是对阶段性 的成果进行检测、验证，为质量保证提供参考依据，它是一个PDCA循环过程。<br /><br /><strong><span style="font-size: medium;">二 质量管理责任分配</span></strong><br /><br />我们公司在开发项目上按照规范化软件的生产方式进行生产，在生产流程上采用ISO9000的标准进行。每个项目除配备了项目开发所需角色外，还专门配备了配置管理小组、测试小组和质量保证小组确保质量管理的实施，下面针对这三种角色进行说明：<br /><br /><strong>1、配置管理小组职责</strong><br />配 置管理小组是保证项目开发完毕的同时，内部文档和外部文档都同时完成。内部文档的及时产生和规范，是保证项目开发各小组能够更好的接口和沟通的重要前提， 从另一个方面讲，也是保证工程不被某个关键路径所阻塞而延滞的前提。如上所述，配置管理小组还是保证质量保证小组得以发挥作用的基础。配置管理小组的主要 职责包括： 完善各个部门发送需要存档和进行版本控制的代码、文档（包括外来文件）和阶段性成果； 对代码、文档等进行单向出入的控制；  对所有存档的文档进行版本控制； 提供文档规范，并传达到开发组中。<br /><br /><strong>2、测试小组职责</strong><br />测试小组作为质量控制的主要 手段，负责软件的测试设计和执行工作。如同软件开发一样，测试在执行之前，同样需要进行测试计划和测试策略的设计，通常情况下测试可以分为如下几种类型， 如：正确性测试、功能性测试、性能测试、安全测试和系统测试等。而这些测试均需要在测试计划和测试策略中进行描述用以指导测试小组成员进行测试用例编写和 测试执行。程序员在交给测试人员之前是进行过一定的单元测试，确保程序编译、运行正确。<br /><br />  测试人员根据详细设计的文档对软件要实现的功能进行一一测试，保证软件的执行正确的实现设计要求，在此也只证明了软件正确的反映了设计思想，但是否真正反映了用户的需求仍需要进一步的功能性测试。<br /><br />    测试人员只有根据软件需求规格说明书所提及的功能进行检测，才能确保项目组开发的软件产品满足用户需求。在正确性测试完成之后，需要测试的是软件的性能， 软件的性能在本项目中占有重要的地位，性能要求有可能改变软件的设计，为避免造成软件的后期返工，测试在性能上需要较大的侧重。如果有必要的话，测试小组 还需要做安全测试，以确保系统使用安全可靠。<br /><br /><strong>3、质量保证小组职责</strong><br />质量保证小组作为质量保证的实施小组，主要职责是保证软件透明开发的主要环节。在项目开发的过程中几乎所有的部门都与质量保证小组有关。质量保证小组对项目经理提供项目进度与项目真正开发时的差异报告，提出差异原因和改进方法。<br /><br />    在项目进度被延滞或质量保证小组认为某阶段开发质量有问题时，提请项目经理、项目负责人等必要的相关人员举行质量会议。解决当前存在的和潜在的问题。质量 保证是建立在文档的复审基础之上，因而文档版本的控制，特别是软件配置管理，直接影响软件质量保证的影响力和力度。质量保证小组的检测范围包括：系统分析 人员是否正确的反映了用户的需求； 软件执行体是否正确的实现了分析人员的设计思想； 测试人员是否进行了较为彻底的和全面的测试；  配置管理员是否对文档的规范化进行的比较彻底，版本控制是否有效。 <br /><br /><strong><span style="font-size: medium;">三 质量管理实施言</span></strong><br />有了良好的资源配备，又如何在项目全生命周期内实施质量保证，让我们从以下几个方面来看质量保证的实施过程： <br /><br /><strong>1、项目进度的质量保证</strong><br />项 目进度是项目进行是否顺利的最直观表现。显然在项目开始之前，项目开发计划是必须的。如果项目开发计划的制定的是完全合理的，那项目进度也就真正表达了项 目与最终的交付使用之间的距离，然而要制定完全合理的项目开发计划几乎不太可能。可见要保证项目进度，首先要保证项目开发计划尽可能合理。 <br /><br />项目计划的合理程度与项目计划制定者从事类似规模和类似业务的项目的经验有直接关系，通过经验往往能够预见潜在的阻碍，这样要求项目计划制定者需要集众人之力来完善计划。<br /><br />    当项目计划制定初期，由质量保证小组组织召开的项目计划评审会，邀请公司技术专家、用户以及项目组小组成员一起讨论项目计划的可行性，会议通常采用头脑风 暴法，各抒己见，会后由指定的记录员形成质量记录，发送给相关人员，对其计划中不合理的地方进行修改完善，并由质量保证人员对其结果跟踪，以确保项目计划 完整性、可行性，完善后的计划交由配置管理人员进行版本控制。<br /><br />   然而在计划实施过程中，计划不是&#8220;固定化&#8221;。常有人道，&#8220;计划赶不上变化&#8221;，但&#8220;要跟上变化&#8221;。项目计划以里程碑为界限，将整个开发周期划分为若干阶段。 根据里程碑的完成情况，适当的调整每一个较小的阶段的任务量和完成的任务时间，这种方式非常有利于整个项目计划的动态调整。也利于项目质量保证的实施。<br /><br />    实际运作中，当质保小组发现计划实施的差异后，报告项目经理，由项目经理组织负责对计划进行周期性维护，对于已经变动的计划由质保小组协助配置管理小组完 成版本控制。本公司已经开发湖南移动的集中客服系统，开发中的子项目多达六个，历时十个月，目前多数项目已经开发完毕，系统正在试运行阶段，项目金额数千 万元。在这样的项目中，从管理者到开发人员到测试人员都积累了较为丰富的经验，特别是项目开发计划的制定，和项目进度的控制。</div>原文：http://www.iteer.net/modules/doc/article.php?storyid=382<div>http://www.iteer.net/modules/doc/article.php?storyid=382</div><div>http://www.iteer.net/modules/doc/article.php?storyid=382</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/353660.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-07-04 17:46 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/07/04/353660.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>计算机软件配置管理计划规范</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352934.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 24 Jun 2011 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352934.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/352934.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/352934.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/352934.html</trackback:ping><description><![CDATA[<table width="760" align="center" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle" align="center" height="56"><strong>计算机软件配置管理计划规范</strong></td>   </tr>   <tr>      <td align="center" height="40">来自        赵文锋</td>   </tr> </tbody></table> <table width="760" align="center" border="0" cellpadding="0" cellspacing="0" height="65">   <tbody><tr>      <td height="65">       <table width="85%" align="center" border="0">         <tbody><tr>           <td>1． 主题内容与适用范围             <p>本规范规定了在制订软件配置管理计划时应该遵循的统一的基本要求。<br />               本规范适用于软件特别是重要软件的配置管理计划的制订工作。对于非重要软件或已开发好的软件，可以采用本规范规定的要求的子集。</p>             <p>2． 引用标准</p>             <p>GB/T 11457 软件工程术语<br />               GB 8566 计算机软件开发规范<br />               GB 8567 计算机软件产品开发文件编制指南<br />               GB/T 12504 计算机软件质量保证计划规范</p>             <p>3． 术语</p>             <p>下面给出在本规范中用到的一些术语的定义，其它术语的定义按GB/T 11457。在引用时，特别要注意线（baseline）、配置控制(configuration)、配置控制组(configuration                control board)、配置检查(configuration audit)、配置标识(configurationidentification)和配置状态记录(configuration                status accounting)等术语的定义。<br />               3．1项目委托单位 project entrust organization<br />               项目委托单位是指为产品开发提供资金并通常也是（但有时也未必）确定产品需求的单位或个人。<br />               3．2 项目承办单位 project undertaking organization<br />               项目承办单位是指为项目委托单位开发、购置或选用软件产品的单位或个人。<br />               3．3 软件开发单位 software development organization<br />               软件开发单位是指直接或间接受项目委托单位委托而直接负责开发软件的单位或个人。 <br />               3．4 用户 user<br />               用户是指实际全胜软件来完成某项计算、控制或数据处理等任务的单位或个人。<br />               3．5 软件 software<br />               软件是指计算机程序及其有关的数据和文档，也包括固化了的程序。<br />               3．6 重要软件 critical software<br />               重要软件是指其故障会影响到人身安全、会导致重大经济损失或社会损失的软件。<br />               3．7 软件生存周期 software life cycle<br />                软件生存周期是指从软件系统设计对软件系统提出应用需求开始，经过开发，产生出一个满足需求的计算机软件系统，然后投入运行，直至该软件系统退役为止。其 间经历系统分析与软件定义、软件开发以及系统的运行与维护等三个阶段。其中软件开发阶段一般又分成需求分析、概要设计、详细设计、编码与单元测试、组装与 系统测试以及安装与验收等六个阶段。<br />               3．8 软件开发库 software development library<br />               软件开发库是指在软件生存周期的某一个阶段期间，存放与该阶段软件开发工作有关的计算机可读信息和人工可读信息的库。<br />               3．9 软件受控库 software sontrolled library<br />               软件受控库是指在软件生存周期的某一个阶段结束时，存放作为阶段产品而释放的、与软件开发工作有关的计算机可读信息一人工可读信息的库。软件配置管理就是对软件受控库中的各软件项进行管理，因此软件受控库也叫做软件配置管理库。                <br />               3．10 软件产品库 software product libary<br />               软件产品库是指在软件生存周期的组装与系统测试阶段结束后，存放最终产品而后交付给用户运行或在现场安装的软件的库。<br />               3．11 接口控制 interface control<br />               接口控制是指描述有关由一个或多个部门提供的两个或两个以上的配置项接口的所有功能特性和物理特性的过程。在实现之前，要确保对这些功能特性和物理特性所建议的修改已经过评审和批准。<br />               3．12 功能基线 functional baseline<br />                功能基线是指在系统分析与软件定义阶段结束时，经过正式评审和批准的系统设计规格说明书中对待开发系统的规格说明；或是指经过项目委托单位和项目承办单位 双方签字同意的协议书或合同中所规定的对待开发软件系统的规格说明；或是由下级申请经上级同意或直接由上级下达的项目任务书中所规定的对待开发软件系统的 规格说明。功能基线是最初批准的功能配置标识。                <br />               3．13 指派基线 allocated baseline<br />               指派基线是指在软件需求分析阶段结束时，经过正式评审和批准的软件需求的规格说明。指派基线是最初批准的指派配置标识。<br />               3．14 产品基线 product baseline<br />               产品基线是指在软件组装与系统测试阶段结束时，经过正式评审的批准的有关所开发的软件产品的全部配置项的规格说明。产品基线是最初批准的产品配置标识。                <br />               3．15 软件配置 software configuration<br />               软件配置是指一个软件产品在软件生存周期各个阶段所产生的各种形式（机器可读或人工可读）和各种版本的文档、程序及其数据的集合。该集合中的每一个元素称为该软件产品软件配置中的一个配置项(configuration                item)。<br />               3．16 释放 release<br />               释放是指在软件生存周期的各个阶段结束时，由该阶段向下阶段提交该阶段产品的过程。它也指将集成与系统测试阶段结束时所获得的最终产品向用户提交的过程。后面这个过程也中做交付(delivery)。</p>             <p>4． 软件配置管理计划编制大纲</p>             <p>项目承办单位（或软件开发单位）中负责软件配置管理的机构或个人，必须制订一个包括下面各章内容的的软件配置管理计划（以 下简称计划）。各章必须按所描述的顺序排列。如果某章中没有相应的内容，则在该章标题之后必须说明"本章无内容"的字样，并附上相应的理由。如果需要，可 以在后面增加章条。如果某些材料已经出现在其它文件中，则在该计划中应引用那些文件。计划的封面必须标明计划名和该计划所属的项目名，并必须经项目委托单 位和项目承办单位（或软件开发单位）的代表共同签字、批准。计划的目次是：                引言<br />               管理<br />               软件配置管理活动<br />               工具、技术和方法<br />               对供货单位的控制<br />               记录的收集、维护和保存<br />               下面给出软件配置管理计划的各个章条必须具有的内容。<br />               4．1 引言<br />               4．1．1 目的<br />               本条必须指明特定的软件配置管理计划的具体目的，还必须描述该计划所针对的软件项目及其所属的各个子项目的名称和用途。<br />               4．1．2 定义和缩写词<br />               本条应该列出计划正文中需要解释的、而在GB/T 11457中尚未包含的术语的定义，必要时，还要给出这些定义的英文单词及其缩写词。<br />               4．1．3 参考资料<br />               本条必须列出计划正文中所引用资料的名称、代号、编号、出版机构和出版年月。<br />               4．2 管理<br />               本章必须描述负责软件配置管理的机构、任务、职责及其有关的接口控制。<br />               4．2．1 机构<br />               本条必须描述在各阶段中负责软件配置管理的机构。描述的内容如下：<br />               A． 描述在软件生存周期各阶段中软件配置管理的功能和负责软件配置管理的机构；<br />               B． 说明项目和子项目与其他有关项目之间的关系；<br />               C． 指出在软件生存周期各阶段中的软件开发或维护机构与配置控制组的相互关系。<br />               4．2．2 任务<br />               本条必须描述在软件生存周期各个阶段中的配置管理任务以及要进行评审的检查工作，并指出各个阶段的阶段产品应存放在哪一类软件库中（软件开发库、软件受控库或软件产品库）。                <br />               4．2．3 职责<br />               本条必须描述与软件配置管理有关的各类机构或成员的职责，并指出这些机构或成员相互之间的关系。<br />               A． 指出负责各项软件配置管理任务（如配置标识、配置控制、配置状态记录以及配置的评审与检查）的机构的职责；<br />               B． 指出上述机构与软件质量保证机构、软件开发单位、项目承办单位、项目委托单位以及用户等机构的关系；<br />               C． 说明由本计划第4.2.2条指明的生存周期各个阶段的评审、检查和审批过程中的用户职责以及相关的开发与维护活动；<br />               D． 指出与项目开发有关的各个机构的代表的软件配置管理职责；<br />               E． 指出其他特殊职责，例如为满足软件配置管理要求所必要的批准要求。<br />               4．2．4 接口控制<br />               本条应该描述：<br />               A． 接口规格说明标识和文档控制的方法；<br />               B． 对已交付的接口规格说明和文档进行修改的方法；<br />               C． 对要完成的软件配置管理活动进行跟踪的方法；<br />               D． 记录和报告接口规格说明和文档控制状态的方法；<br />               E． 控制软件和劫持它运行的硬件之间的接口的方法。<br />               4．2．5 实现<br />               本条应该规定实现软件配置管理计划的主要里程碑，例如：<br />               A． 建立配置控制组；<br />               B． 确定各个配置基线；<br />               C． 建立接口控制协议；<br />               D． 制订评审与检查软件配置管理计划和规程；<br />               E． 制订相关的软件开发、测试和劫持工具的配置管理计划和规程。<br />               4．2．6 适用的标准、条例和约定<br />               4．2．6．1 本条必须指明所适用的软件配置管理标准、条例和约定，并把它们作为本计划要实现的一部分；还必须说明这些标准、条例和约定要实现的程度。<br />               4．2．6．2 本条必须描述要在本项目中编写和实现的软件配置管理标准、条例和约定。<br />               这些标准、条例和约定可以包括如下内容：<br />               A． 软件结构层次树中软件位置的标识方法；<br />               B． 程序和模块的命名约定；<br />               C． 版本级别的命名约定；<br />               D． 软件产品的标识约定；<br />               E． 规格说明、测试计划与测试规程、程序设计手册及其他文档的标识方法；<br />               F． 媒体和文档管理的标识方法；<br />               G． 文档交付过程；<br />               H． 软件产品库中软件产品入库、移交或交付的过程；<br />               I． 问题报告、修改请求和修改次序的处理过程；<br />               J． 配置控制组的结构和作用；<br />               K． 软件产品交付给用户的验收规程；<br />               L． 软件库的操作，包括准备、存储和更新模块的方法；<br />               M． 软件配置管理活动的检查；<br />               N． 问题报告、修改请求或修改次序的文档要求，指出配置修改的目的和影响；<br />               O． 软件进入配置管理之前的测试级别；<br />               P． 质量保证级别，例如，在进入配置管理之前，验证软件满足有关基线的程序。<br />               4．3 软件配置管理活动<br />               本章必须描述配置标识、配置控制、配置状态记录与报告以及配置检查与评审等到四方面的软件配置管理活动的需求。<br />               4．3．1 配置标识<br />               4．3．1．1  本条必须详细说明软件项目的基线（即最初批准的配置标识），并把它们与本计划第4.2.2条描述的生存周期的特定阶段相联系。在软件生存周期中，主要有三 种基线，它们是功能基线、指派基线和产品基线。对于每个基线，必须描述下列内容：                A． 每个基线的项（包括应交付的文档和程序）；<br />               B． 与每个基线有关的评审与批准事项以及验收标准；<br />               C． 在建立基线的过程中用户和开发者可的参与情况。<br />               例如，在产品基线中，要定义的元素可以包括：<br />               A． 产品的名字和命名规则；<br />               B． 产品标识编号；<br />               C． 对每一个新交付的版本，要给出版本交付号、新修改的描述、修改交付的方法、对支持软件的修改要求以及有关文档的修改要求；<br />               D． 安装说明；<br />               E． 已知的缺陷和故障； F． 软件媒体和媒体标识。<br />               4．3．1．2 本条必须描述本项目所有软件代码和文档的标题、代号、编号以及分类规程。例如，对代码来说：<br />               A． 编译日期可以作为每个交付模块标识的一部分；<br />               B． 在构造模块源代码的顺序行号时，应使它适合于对模块作进一步子修改。<br />               4．3．2 配置控制<br />               4．3．2．1 本条必须描述在本计划第4.2.2条描述的软件生存周期中各个阶段使用的修改批准权限的级别。<br />               4．3．2．2 本条必须定义对已有配置的修改建议进行处理的方法，其中包括：<br />               A． 详细说明书在本计划第4.2.2条描述的软件生存周期各个阶段中提出建议的程序（可以用注上自然语言的流程图来表达）；<br />               B． 描述实现已批准的修改建议（包括源代码、目标代码和文档的修改）的方法；<br />               C． 描述软件库控制的规程，其中包括存取控制、对于适用基线的读写保护、成员保护、成员标识、档案维护、修改历史以及故障恢复等七项规程；<br />               D． 如果有必要修补目标代码，则要描述其标识和控制的方法。<br />               4．3．2．3 对于各个不同层次的配置控制组和其他修改管理机构，本条必须：<br />               A． 定义其作用，并规定其权限和职责；<br />               B． 如果已组成机构，则指明该机构的领导人员及其成员；<br />               C． 如果还没有组成机构，则说明怎样任命该机构的领导人、成员及代理人； D． 说明开发者和用户与配置控制组的关系。<br />               4．3．2．4  当要与不属于本软件配置管理计划适用范围的程序和项目进行接口时，本条必须说明对其进行配置控制的方法。如果这些软件的修改需要其他机构在配置控制组评审 之前或之后进行评审，则本条必须描述这些机构的组成、它们与配置控制组的关系以及它们之间的相互关系。                <br />               4．3．2．5 本条必须说明与特殊产品（如非交付的软件、现存软件、用户提供的软件和内部支持软件）有关的配置控制规程。<br />               4．3．3 配置状态的记录和报告<br />               本条必须： A． 指明怎样收集、验证、存储、处理和报告配置项的状态信息；<br />               B． 详细说明要定期提供的报告及其分发办法；<br />               C． 如果有动态查询，要指出所动态查询的能力；<br />               D． 如果要求记录用户说明的特殊状态时，要描述其实现手段。<br />               例如，在配置状态记录和报告中，通常要描述的信息有：<br />               A． 规格说明的状态； <br />               B． 修改建议的状态；<br />               C． 修改批准的报告；<br />               D． 产品版本或其修改版的状态；<br />               E． 安装、更新或交付的实现报告；<br />               F． 用户提供的产品（如操作系统）的状态；<br />               G． 有关开发项目历史的报告。<br />               4．3．4 配置的检查和评审 本条必须：<br />               A． 定义在软件配置计划的第4.2.2条所定义的软件生存周期的特定点上执行的检查和评审中软件配置管理计划的作用；<br />               B． 规定每次检查和评审所包含的配置项；<br />               C． 指出用于标识和解决在检查和评审期间所发现的问题的工作规程。<br />               4．4 工具、技术和方法<br />               本章必须指明为支持特定项目的软件配置管理所使用的软件工具、技术和方法，指明它们的目的，并在开发者所有权的范围内描述其用法。例如，可以包括用于下列任务的工具、技术和方法：<br />               A． 软件媒体和媒体的标识。<br />               B．  把文档和媒体置于软件配置管理的控制之下，并把它正式地交付给用户。例如，要给出对软件库内的源代码和目标代码进行控制的工具、技术和方法的描述；如果用 到数据库管理系统，则还要对该系统进行描述。又如，要指明怎样使用软件库工具、技术和方法来处理软件产品的交付。                C．  编制关于程序及其有关文档的修改状态的文档。因此必须进一步定义用于准备多种级别（如项目负责人、配置控制小组、软件配置管理人员和用户）的管理报告的工 具、技术和方法。                <br />               4．5 对供货单位的控制<br />                供货单位是指软件销售单位、软件开发单位或软件子开发单位。必须规定对这些供货单位进行控制的管理规程，从而使从软件销售单位购买的、其他开发单位开发的 或从开发单位现存软件库中选用的软件能满足规定的软件配置管理需求。管理规程应该规定在本软件配置管理计划的执行范围内控制供货单位的方法；还应解释用于 确定供货单位的软件配置管理能力的方法以及监督他们遵循本软件配置管理计划需求的方法。<br />               4．6 记录的收集、维护和保存<br />               本章必须指明要保存的软件配置管理文档，指明用于汇总、保护和维护这些文档的方法和设施（其中包括要使用的后备设施），并指明要保存的期限。              </p>             <p><br />               附录A：<a href="http://www.uml.org.cn/pzgl/fulua.htm" target="_blank">软件配置管理计划示例</a></p>             <p>附录B：配置管理报表及其格式</p>原文：http://www.uml.org.cn/pzgl/jsjpzgf.htm</td></tr></tbody></table></td></tr></tbody></table><img src ="http://www.blogjava.net/jasmine214--love/aggbug/352934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-06-24 10:49 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于CMM和CMMI的配置管理（转）</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352932.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 24 Jun 2011 02:46:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352932.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/352932.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352932.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/352932.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/352932.html</trackback:ping><description><![CDATA[<div><p>本文主要从CMM和CMMI的要求出发，介绍了标准主要涉及的配置管理内容，并对相应内容进行初步地说明，最后提供了一个配置管理在项目实施的指南和一个在组织中部署配置管理的模型。</p> <p><strong>1 配置管理内容的逻辑关系</strong></p> <p>在CMM和CMMI中，将配置管理的目的定义为&#8220;建立和维护产品的完整性&#8221;，这个目标没有提到对项目管理的支持，也就是说，它定义的配置管理的目标 比当前业界对配置管理的认识有些缩小。但是，仔细分析可以发现&#8220;建立和维护产品的完整性&#8221;是其他配置管理目标的基础。下面就从这个目标出发进行分析。逻辑 关系见下图：<br /> <img src="http://www.uml.org.cn/images/upfile/2004511521.jpg" alt="" width="527" height="357" /></p> <p>配置完整性（对标准的理解）</p> <p>1. 产品完整性：就是项目提交的工作成果是&#8220;产品集合完整、子产品的正确&#8221;的 </p> <p>2. 产品集合完整：产品包含的子产品（配置项）是完整的</p> <p>3. 子产品的正确：子产品（配置项）达到了需求要求，满足标准、规程的要求 </p> <p>逻辑关系分析</p> <p>1. &#8220;基线管理&#8221;支持&#8220;产品集合完整&#8221;，明确产品的&#8220;子产品&#8221;（配置项）集合，并进行管理和控制<br /> &nbsp;&nbsp;&nbsp; 2. &#8220;配置项管理&#8221;，提供了了对子产品（配置项）的控制管理，支持&#8220;子产品的正确&#8221;<br /> &nbsp;&nbsp;&nbsp; 3. &#8220;变更管理&#8221;，同时支持&#8220;产品集合完整、子产品的正确&#8221;，用于控制子产品（配置项）和产品（基线）的变更<br /> &nbsp;&nbsp;&nbsp; 4. &#8220;配置标示&#8221;，建立对配置项（子产品）的识别、命名，支持&#8220;配置项管理&#8221;<br /> &nbsp;&nbsp;&nbsp; 5. &#8220;版本控制&#8221;，控制配置项（子产品）生命历程，保留配置项（子产品）演进历史<br /> &nbsp;&nbsp;&nbsp; 6. &#8220;过程管理&#8221;，就是对配置项、基线的建立、变更的状态标示、过程控制，保证产品（或子产品）按照规定的流程进行了操作；例如&#8220;配置项&#8221;进入&#8220;基线&#8221;的过程包括：配置项标示、产品验证、进入配置、配置审计等<br /> &nbsp;&nbsp;&nbsp; 7. &#8220;配置计划&#8221;、&#8220;配置库管理&#8221;、&#8220;配置审计&#8221;、&#8220;配置报告&#8221;等是整个配置管理得支持系统。提供了配置管理&#8220;可视性&#8221;和监督管理 </p> <p><strong>2 配置和配置项</strong></p> <p>在配置管理中，&#8220;配置&#8221;和&#8220;配置项&#8221;是重要的概念，&#8220;配置&#8221;是在技术文档中明确说明并最终组成软件产品的功能或物理属性。因此&#8220;配置&#8221;包括了即将受 控的所有产品特性，其内容及相关文档，软件版本，变更文档，软件运行的支持数据，以及其他一切保证软件一致性的组成要素，相对与硬件类配置，软件产品的 &#8220;配置&#8221;包括更多的内容并具有易变性。<br /> &nbsp;&nbsp;&nbsp; 受控软件经常被划分为各类配置项（Configuraion items,  CIs），这类划分是进行软件配置管理的基础和前提，CIs是逻辑上组成软件系统的各组成部分。比如一个软件产品包括几个程序模块，每个程序模块及其相关 文档和支撑数据可能被命名为一个CI。一个系统包括的CIs的数目是一个与设计密切相关的问题。一个纯软件的CI通常也称之为软件配置项（CSCI）。<br /> &nbsp;&nbsp;&nbsp; 现在所有的配置管理工具均提供对配置项的管理工具，包括(Check in和Check out机制的 )版本管理和版本标号功能。由于版本和标号管理比较繁琐，一般推荐使用配置管理工具，减少事务性工作。 </p> <p><strong>3 基线</strong></p> <p>在配置管理系统中，基线就是一个CI或一组CIs在其生命周期的不同时间点上通过正式评审而进入正式受控的一种状态，而这个过程被称为&#8220;基线化&#8221;。 每一个基线都是其下一步开发的出发点和参考点。基线确定了元素（配置项）的一个版本，且只确定一个版本。一般情况下，基线一般在指定的里程碑处创建，并与 项目中的里程碑保持同步。</p> <p>一般地，第一个基线包含了通过评审的软件需求，因此称之为&#8220;需求基线&#8221;，通过建立这样一个基线，受控的系统需求成为进一步软件开发的出发点，对需求的变更被正式初始化、评估。受控的需求还是对软件进行功能评审的基础。<br /> &nbsp;&nbsp;&nbsp; 每个基线都将接受配置管理的严格控制，对其的修改将严格按照变更控制要求的过程进行，在一个软件开发阶段结束时，上一个基线加上增加和修改的基线内容形成下一个基线，这就是&#8220;基线管理&#8221;的过程。</p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td><strong>基线具有以下属性：</strong><br />             通过正式的评审过程建立<br />             基线存在于基线库中，对基线的变更接受更高权限的控制<br />             基线是进一步开发和修改的基准和出发点<br />             进入基线前，不对变化进行管理或者较少管理<br />             进入基线后，对变化进行有效管理，而且这个基线作为后继续工作的基础<br />             不会变化的东西不要纳入基线<br />             变化对其他没有影响的可以不纳入基线</td>         </tr>     </tbody> </table> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td><strong>建立基线的好处：</strong><br />             重现性：及时返回并重新生成软件系统给定发布版的能力，或者是在项目中的早些时候重新生成开发环境的能力。当认为更新不稳定或不可信时，基线为团队提供一种取消变更的方法。<br />             可追踪性：建立项目工件之间的前后继承关系。目的是确保设计满足要求、代码实施设计以及用正确代码编译可执行文件。<br />             版本隔离：基线为开发工件提供了一个定点和快照，新项目可以从基线提供的定点之中建立。作为一个单独分支，新项目将与随后对原始项目（在主要分支上）所进行的变更进行隔离。</td>         </tr>     </tbody> </table> <p><strong>4 基线、配置、配置项的关系</strong></p> <p>基线的组成，以及配置项和配置的关系如下图：</p> <p><img src="http://www.uml.org.cn/images/upfile/2004511522.jpg" alt="" width="528" height="280" /><br /> </p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td><strong>基线管理的步骤：</strong><br />             1、在开发前确定基线的&#8220;配置&#8221;<br />             2、基线批准前，根据&#8220;配置&#8221;检查配置项是否齐备<br />             3、对各个配置项，确认其版本的正确性<br />             4、对每个配置项建立基线标志，<br />             例如上图为：测试基线=（配置项A=1，配置项B=1，配置项C=1）<br />             alpha版=（配置项A=2，配置项B=1，配置项C=1）<br />             beta版=（配置项A=3，配置项B=3，配置项C=2）<br />             产品基线=（配置项A=4，配置项B=4，配置项C=4）<br />             5、基线变更管理<br />             6、基线的各类报告和审计信息</td>         </tr>     </tbody> </table> <p>针对某个具体得项目，可以根据基线的内容，建立一个基线信息的跟踪表，例如如下：</p> <p><img src="http://www.uml.org.cn/images/upfile/2004511523.jpg" alt="" width="575" height="277" /><br /> <br /> [注]：被色块覆盖的表示，此配置项属于对应列的基线<br /> [注]：在色块的栏目填写对应配置项的版本号</p> <p><strong>5 变更管理</strong></p> <p>在有效标示了配置并进行了管理之后，如何保证它们在复杂多变得开发过程中真正的处于受控的状态，并在任何情况下都能迅速的恢复到任一历史状态就要依赖有下的变更管理。</p>  <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>缺乏有效的变更请求管理会导致的问题： <br />             软件产品质量低下，对一些缺陷的修正被遗漏<br />             项目经理不了解开发人员的工作进展，缺乏对项目现状进行客观评估的能力<br />             开发人员不了解手头工作的优先级别，可能出现将紧急的事情放在一边、而工作在一般优先级任务上的情况<br />             可能错误使用和引用已经变更的产品，引起开发工作混乱</td>         </tr>     </tbody> </table> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>变更管理的流程： <br />             （获得）提出变更请求； <br />             由CCB审核并决定是否批准； <br />             为（被接受）修改请求分配人员，提取SCI，进行修改； <br />             提交修改后的SCI，并测试（或者评审）； <br />             重建软件的适当版本； <br />             复审（审计）所有SCI的变化； <br />             发布新版本。 </td>         </tr>     </tbody> </table> <p>为了更好的指导变更范围的影响分析，可以通过两种表格来帮助发现受到变更影响的内容，一种是《需求跟踪表》，一种是《配置项依赖关系表》，分别如下：</p> <p><img src="http://www.uml.org.cn/images/upfile/2004511524.jpg" alt="" width="600" height="481" /></p> <p><strong>6 配置库管理</strong></p> <p>在实际的开发活动中系统中，为了让每个开发人员和各个开发团队能更好的分工合作，同时又互不干扰，必须规划好工作空间的管理。主要的手段是设置配置库（即文件夹设置），和设置版本的分支，来实现对配置项权限管理。</p> <p>设置版本分支</p> <p>基本上要为每个配置项从建立开始就划分成3个不同的分支：私有分支、集成分支、公共（主干）分支。让它们分别对应3类工作空间。<br /> </p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>私有分支：<br />              私有分支对应的是开发人员的私有开发空间。开发人员根据任务分工获得对相应配置项的操作许可之后，他即在自己的私有开发分支上工作，他的所有工作成果体现 为在该配置项的私有分支上的版本的推进，除该开发人员外，其他人员均无权操作该私有空间中的元素。</td>         </tr>     </tbody> </table> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>集成分支：<br />              集成分支对应的是开发团队的公共空间。凡是要为同组人员共享的配置项都从该分支获得。即各开发人员必须将私有工作空间中的开发成果归并（Merge）到该 分支后才能进入下一个开发活动。所有涉及多人协调的开发工作（如集成测试等）都必须工作在这一空间中。该开发团队拥有对该集成分支的读写权限，而其他成员 只有只读权限。该分支的管理工作由系统集成员及相关指定人员负责。 </td>         </tr>     </tbody> </table> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>公共（主干）分支：<br />              公共分支对应的是整个软件开发组织的公共空间。各个开发小组在现阶段的任务完成后，将可以发布的版本归并到该分支上，将来需要查阅相关资料时，以该分支上 的版本为准。该分支对组织内的全体软件人员开放只读权限。该分支的管理工作由系统集成员负责。 </td>         </tr>     </tbody> </table> <p>上面定义的3类工作空间（分支）由配置管理员统一管理，根据各开发阶段的实际情况定制相应的版本选取规则，来保证开发活动的正常运作。在变更发生时，应及时做好基线的推进。 </p> <p>配置库的设置 </p> <p>决定配置库的结构是配置管理活动的重要基础。一般常用的是两种组织形式：按配置项类型分类建库和按任务建库。 </p> <p>按配置项的类型分类建库的方式经常为一些咨询服务公司所推荐，它适用于通用的应用软件开发组织。这样的组织一般产品的继承性较强，工具比较统一，对 并行开发有一定的需求。使用这样的库结构有利于对配置项的统一管理和控制，同时也能提高编译和发布的效率。但由于这样的库结构并不是面向和各个开发团队的 开发任务的，所以可能会造成开发人员的工作目录结构过于复杂，带来一些不必要的麻烦。 </p> <p>而按任务建立相应的配置库则适用于专业软件的研发组织。在这样的组织内，使用的开发工具种类繁多，开发模式以线性发展为主，所以就没有必要把配置项严格的分类存储，人为增加目录的复杂性。因此，笔者认为特别是对于研发性的软件组织来说，还是采用这种设置策略比较灵活。 </p> <p>配置库的日常工作</p> <p>配置库的日常工作是一些事务性的工作，主要保证配置库的安全性，包括：</p> <p>对配置库的定期备份</p> <p>清除无用的文件和版本</p> <p>检测并改进配置库的性能等 </p> <p><strong>7 配置报告</strong></p> <p>配置状态报告就是根据配置项操作的记录来向管理者报告软件开发活动的进展情况。这样的报告应该是定期进行，并尽量通过CASE工具自动生成，用数据库中的客观数据来真实的反映各配置项的情况。 </p> <p>配置状态报告应着重反映当前基线配置项的状态，以作为对开发进度报告的参照。为了说明项目状态对变更的情况也应当进行报告。有时，对配置库的情况也 进行说明，例如备份次数，磁盘占用空间等等。只要是关心的信息，均可作为状态报告的内容。这些信息进行有效记录，往往可以作为项目度量的重要数据来源。 </p> <p><strong>8 配置审计</strong></p> <p>配置审计的主要作用是作为变更控制的补充手段，来确保某一变更需求已被切实实现。在某些情况下，它被作为正式的技术复审的一部分，但当软件配置管理 是一个正式的活动时，该活动由SQA人员单独执行。  审计机制保证修改的动作被完整地记录，也就是说，记录了谁修改了这个工件，什么时候做的修改，为什么原因做出这个改动，以及修改了哪些地方。  在版本控制过程中，如果利用一些配置管理工具（或者版本控制工具）的支持，则可以自动地记录审计工作所需的四个&#8220;W&#8221;（Who、When、Why、 What）。 同时配置审计工作应当可以说明如下信息。 </p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>配置审计应当说明的信息：<br />             1. 变更要求被完成，并且对附加的修改已经执行了<br />             2. 采用了正确的正式验证手段<br />             3. 遵循了标准的要求<br />             4. 变更的4W信息被完整记录，并和相关配置项关联 </td>         </tr>     </tbody> </table> <p><strong>9 项目实施指南</strong></p> <p>一个软件研发项目一般可以划分为三个阶段：计划阶段、开发阶段和维护阶段。然而从软件配置管理的角度来看，后两个阶段所涉及的活动是一致，所以就把它们合二为一，成为&#8220;项目开发和维护&#8221;阶段。 </p> <p>一个项目设立之初项目经理首先需要制定整个项目的计划，它是项目研发工作的基础。在有了总体研发计划之后，软件配置管理的活动就可以展开了，因为如 果不在项目开始之初制定软件配置管理计划，那么软件配置管理的许多关键活动就无法及时有效的进行，而它的直接后果就是造成了项目开发状况的混乱并注定软件 配置管理活动成为一种&#8220;救火&#8221;的行为。所以及时制定一份软件配置管理计划在一定程度上是项目成功的重要保证。 </p> <p>在&#8220;开发阶段和维护阶段&#8221;，软件配置管理活动主要分为三个层面，这三个层面是彼此之间既独立又互相联系的有机的整体。</p> <p>（1） 主要由配置人员完成的管理和维护工作；</p> <p>（2） 由系统集成员和开发人员具体执行软件配置管理策略；</p> <p>（3） 变更流程。</p> <table width="90%" border="1" cellpadding="1">     <tbody>         <tr>             <td width="18%">             <div align="center"><strong>软件阶段</strong></div>             </td>             <td width="19%">             <div align="center"><strong>活 动 </strong></div>             </td>             <td width="63%">             <div align="center"><strong>活动说明</strong></div>             </td>         </tr>         <tr>             <td rowspan="4">             <div align="center">计划阶段</div>             </td>             <td>制定软件计划<br />             </td>             <td>一个项目设立之初，项目经理首先需要制定整个项目的计划</td>         </tr>         <tr>             <td>确定配置策略</td>             <td>配置管理委员会（CCB）根据项目的开发计划确定各个里程碑和开发策略</td>         </tr>         <tr>             <td>制定配置计划</td>             <td>配置人员根据CCB的规划，制定详细的配置管理计划，交CCB审核</td>         </tr>         <tr>             <td>批准配置计划</td>             <td>CCB通过配置管理计划后交项目经理批准，发布实施</td>         </tr>         <tr>             <td rowspan="6">                                                                              <div align="center">开发阶段和维护阶段</div>             </td>             <td>确定初始基线</td>             <td>CCB设定研发活动的初始基线</td>         </tr>         <tr>             <td>配置库管理</td>             <td>配置人员根据软件配置管理规划设立配置库和工作空间，为执行软件配置管理做好准备；并定期进行备份和清理工作</td>         </tr>         <tr>             <td>授权开发</td>             <td>开发人员按照统一的软件配置管理策略，根据获得的授权的资源进行项目的研发工作</td>         </tr>         <tr>             <td>集成</td>             <td>系统集成员按照项目的进度集成组内开发人员的工作成果，并构建系统，推进版本的演进</td>         </tr>         <tr>             <td>管理基线</td>             <td>CCB根据项目的进展情况，并适时的建立基线，批准基线变更，保证开发和维护工作有序的进行。</td>         </tr>         <tr>             <td>产品发布</td>             <td>系统集成员进行产品集成，由CCB批准，进行发布</td>         </tr>         <tr>             <td rowspan="3">                                       <div align="center">其 他</div>             </td>             <td>配置会议<br />             </td>             <td>CCB定期举行例会，根据成员所掌握的情况、配置人员的报告和开发人员的请求，对配置管理计划作出修改，并向项目经理负责。</td>         </tr>         <tr>             <td>配置报告和审计</td>             <td>配置人员定期向项目经理和CCB提交审计报告，并在配置管理例会中报告项目在软件过程中可能存在的问题和改进方案</td>         </tr>         <tr>             <td>变更管理</td>             <td>事件触发执行，由CCB批准、项目组执行，并执行审计</td>         </tr>     </tbody> </table> <p><strong>10 配置管理部署模型</strong></p> <p>基本过程</p> <table width="90%" border="1" cellpadding="1">     <tbody>         <tr>             <td width="15%">             <div align="center"><strong>序号 </strong></div>             </td>             <td width="23%">             <div align="center"><strong>阶段</strong></div>             </td>             <td width="40%">             <div align="center"><strong>活动</strong></div>             </td>             <td width="22%">             <div align="center"><strong>备注</strong></div>             </td>         </tr>         <tr>             <td>1<br />             </td>             <td>获得相应管理权</td>             <td><br /></td>             <td><br /></td>         </tr>         <tr>             <td>1.1</td>             <td><br /></td>             <td>建立相应负责团队<br />             </td>             <td><br /></td>         </tr>         <tr>             <td>1.2</td>             <td><br /></td>             <td>获得授权和资源</td>             <td>可召开启动会</td>         </tr>         <tr>             <td>2<br />             </td>             <td>评估配置管理现状</td>             <td><br />             </td>             <td><br /></td>         </tr>         <tr>             <td>2.1</td>             <td><br /></td>             <td>绘制和评估当前过程的控制图</td>             <td>可采用CMM标准</td>         </tr>         <tr>             <td>2.2</td>             <td><br /></td>             <td>了解员工对配置管理的态度</td>             <td><br /></td>         </tr>         <tr>             <td>2.3</td>             <td><br /></td>             <td>了解组织的配置管理技术水平</td>             <td><br /></td>         </tr>         <tr>             <td>2.4</td>             <td><br /></td>             <td>了解领导期望</td>             <td><br /></td>         </tr>         <tr>             <td>2.5</td>             <td><br /></td>             <td>编制并评审评估报告</td>             <td>获得&#8220;现状信息&#8221;</td>         </tr>         <tr>             <td>3<br />             </td>             <td>配置工具选择</td>             <td><br /></td>             <td><br /></td>         </tr>         <tr>             <td>3.1</td>             <td><br /></td>             <td>编制、评审《评估评分表》<br />             </td>             <td><br /></td>         </tr>         <tr>             <td>3.2</td>             <td><br /></td>             <td>评估配置工具和供货商</td>             <td><br /></td>         </tr>         <tr>             <td>3.3</td>             <td><br /></td>             <td>收集其他用户的使用经验</td>             <td><br /></td>         </tr>         <tr>             <td>4<br />             </td>             <td>配置过程定义</td>             <td><br /></td>             <td>制定配置管理过程草案</td>         </tr>         <tr>             <td>4.1</td>             <td><br /></td>             <td>利用&#8220;现状信息&#8221;和收集的经验<br />             </td>             <td><br /></td>         </tr>         <tr>             <td>4.2</td>             <td><br /></td>             <td>制定新的过程</td>             <td><br /></td>         </tr>         <tr>             <td>4.3</td>             <td><br /></td>             <td>评审新过程，并建立新的过程基线</td>             <td><br /></td>         </tr>         <tr>             <td>5<br />             </td>             <td>试点</td>             <td><br /></td>             <td><br /></td>         </tr>         <tr>             <td>5.1</td>             <td><br /></td>             <td>选定试点项目</td>             <td><br /></td>         </tr>         <tr>             <td>5.2</td>             <td><br /></td>             <td>确定试点负责小组</td>             <td><br /></td>         </tr>         <tr>             <td>5.3</td>             <td><br /></td>             <td>定义试点成功标准和进度</td>             <td><br /></td>         </tr>         <tr>             <td>5.4</td>             <td><br /></td>             <td>试点项目人员培训</td>             <td><br /></td>         </tr>         <tr>             <td>5.5</td>             <td><br /></td>             <td>试点改进</td>             <td>同时对草案进行改进</td>         </tr>         <tr>             <td>5.6</td>             <td><br /></td>             <td>试点总结/推广</td>             <td>完成正式过程的发布</td>         </tr>         <tr>             <td>6<br />             </td>             <td>全面实施</td>             <td><br /></td>             <td><br /></td>         </tr>         <tr>             <td>6.1</td>             <td><br /></td>             <td>组建相应部门和团队<br />             </td>             <td><br /></td>         </tr>         <tr>             <td>6.2</td>             <td><br /></td>             <td>制定各个项目的实施计划</td>             <td><br /></td>         </tr>         <tr>             <td>6.3</td>             <td><br /></td>             <td>配置管理知识、过程、工具的培训</td>             <td><br /></td>         </tr>         <tr>             <td>6.4</td>             <td><br /></td>             <td>帮助各个项目向新过程迁移</td>             <td><br /></td>         </tr>         <tr>             <td>6.5</td>             <td><br /></td>             <td>日常监督、抽查、沟通</td>             <td><br /></td>         </tr>         <tr>             <td>7 </td>             <td>结束</td>             <td><br /></td>             <td>总结、奖励</td>         </tr>     </tbody> </table> <p>相应操作文件 </p> <p>对应过程：2.2了解员工对配置管理的态度建立一个CHECKLIST，来进行调研，如下</p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>             <div align="center"><strong>序号 </strong></div>             </td>             <td>             <div align="center"><strong>调查内容</strong></div>             </td>             <td>             <div align="center"><strong>调查结果</strong></div>             </td>         </tr>         <tr>             <td>1</td>             <td>原来是否有过类似尝试，成功或者失败了</td>             <td><br /></td>         </tr>         <tr>             <td>2</td>             <td>是否有由于配置管理不好造成的痛苦经历</td>             <td><br /></td>         </tr>         <tr>             <td>3</td>             <td>对建立配置管理过程是否支持</td>             <td><br /></td>         </tr>         <tr>             <td>4</td>             <td>是否觉得配置管理过程会压抑创造性</td>             <td><br /></td>         </tr>         <tr>             <td>5</td>             <td>是否觉得配置管理过程太繁琐</td>             <td><br /></td>         </tr>         <tr>             <td>6</td>             <td>对配置管理是否有不合理的期望</td>             <td><br /></td>         </tr>         <tr>             <td>7</td>             <td>是否有些急功近利</td>             <td><br /></td>         </tr>         <tr>             <td>8</td>             <td>是否对实施配置管理工具感兴趣</td>             <td><br /></td>         </tr>         <tr>             <td>9</td>             <td>个人英雄主义和分工协作那个是主流</td>             <td><br /></td>         </tr>     </tbody> </table> <p>对应过程：2.3了解组织的配置管理技术水平建立一个CHECKLIST，来进行调研，如下</p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td width="11%">             <div align="center">序号 </div>             </td>             <td width="72%">             <div align="center">调查内容</div>             </td>             <td width="17%">             <div align="center">调查结果</div>             </td>         </tr>         <tr>             <td>1</td>             <td>是否已经有了配置管理过程，运作时间<br />             </td>             <td><br /></td>         </tr>         <tr>             <td>2</td>             <td>是否使用了配置管理工具，使用时间</td>             <td><br /></td>         </tr>         <tr>             <td>3</td>             <td>是否接受了配置管理的专门培训，培训时间</td>             <td><br /></td>         </tr>         <tr>             <td>4</td>             <td>对配置管理过程的认识程度</td>             <td><br /></td>         </tr>         <tr>             <td>5</td>             <td>对配置管理工具的使用程度</td>             <td><br /></td>         </tr>         <tr>             <td>6</td>             <td>企业员工的基本素质和学习能力</td>             <td><br /></td>         </tr>     </tbody> </table> <p>对应过程：3.2评估配置工具供应商建立一个CHECKLIST，来进行调研，如下</p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>             <div align="center">序号 </div>             </td>             <td>             <div align="center">调查内容</div>             </td>             <td>             <div align="center">调查结果</div>             </td>         </tr>         <tr>             <td>1</td>             <td>工具可以解决当前问题，满足当前需求吗？<br />             <br />             </td>             <td><br /></td>         </tr>         <tr>             <td>2</td>             <td>产品的市场地位</td>             <td><br /></td>         </tr>         <tr>             <td>3</td>             <td>产品价格</td>             <td><br /></td>         </tr>         <tr>             <td>4</td>             <td>与现有环境的兼容程度</td>             <td><br /></td>         </tr>         <tr>             <td>5</td>             <td>运行能力（峰值情况、成熟性、稳定性）</td>             <td><br /></td>         </tr>         <tr>             <td>6</td>             <td>是否支持未来需求</td>             <td><br /></td>         </tr>         <tr>             <td>7</td>             <td>是否具备：工作空间管理</td>             <td><br /></td>         </tr>         <tr>             <td>8</td>             <td>是否具备：版本控制</td>             <td><br /></td>         </tr>         <tr>             <td>9</td>             <td>是否具备：配置报告</td>             <td><br /></td>         </tr>         <tr>             <td>10</td>             <td>是否具备：过程支持</td>             <td><br /></td>         </tr>         <tr>             <td>11</td>             <td>是否具备：安全和保护</td>             <td><br /></td>         </tr>         <tr>             <td>12</td>             <td>是否具备：工具集成</td>             <td><br /></td>         </tr>         <tr>             <td>13</td>             <td>是否具备：构造支持</td>             <td><br /></td>         </tr>         <tr>             <td>14</td>             <td>是否具备：图形界面</td>             <td><br /></td>         </tr>         <tr>             <td>15</td>             <td>是否具备：自定义支持</td>             <td><br /></td>         </tr>         <tr>             <td>16</td>             <td>是否具备：发行管理</td>             <td><br /></td>         </tr>         <tr>             <td>17</td>             <td>是否具备： WEB支持</td>             <td><br /></td>         </tr>     </tbody> </table> <p>对应过程：3.2评估配置工具供应商建立一个CHECKLIST，来进行调研，如下</p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>             <div align="center"><strong>序号 </strong></div>             </td>             <td>             <div align="center"><strong>调查内容</strong></div>             </td>             <td>             <div align="center"><strong>调查结果</strong></div>             </td>         </tr>         <tr>             <td>1</td>             <td>配置管理服务从业时间<br />             </td>             <td><br /></td>         </tr>         <tr>             <td>2</td>             <td>成功案例数量和质量</td>             <td><br /></td>         </tr>         <tr>             <td>3</td>             <td>培训、技术支持队伍</td>             <td><br /></td>         </tr>         <tr>             <td>4</td>             <td>提供的培训和指导，以及其他服务</td>             <td><br /></td>         </tr>         <tr>             <td>5</td>             <td>近期关于配置服务的商誉、资产、销售额</td>             <td><br /></td>         </tr>         <tr>             <td>6</td>             <td>地理位置、服务及时性</td>             <td><br /></td>         </tr>     </tbody> </table> <p>对应过程：4.2制定新的过程1. 配置管理过程至少应当包括的内容：配置标示、配置控制、报告、审计2. 在考虑工具纳入配置过程中应当考虑下表内容</p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>             <div align="center"><strong>序号 </strong></div>             </td>             <td>             <div align="center"><strong>考虑内容</strong></div>             </td>         </tr>         <tr>             <td>1</td>             <td>从配置过程中分解出那些是事务性、那些是创造性的工作</td>         </tr>         <tr>             <td>2</td>             <td>考虑事务性工作的繁重程度和精度要求程度，理出一个&#8220;自动化优先级&#8221;</td>         </tr>         <tr>             <td>3</td>             <td>根据过程，确定工具可以运用的地方</td>         </tr>         <tr>             <td>4</td>             <td>根据&#8220;自动化优先级&#8221;选择那些工具功能进行自动化</td>         </tr>         <tr>             <td>5</td>             <td>考虑使用工具功能自动化的前提和结果 </td>         </tr>         <tr>             <td>6</td>             <td>划分出&#8220;自动化&#8221;和&#8220;人工&#8221;的接口，并清晰描述</td>         </tr>         <tr>             <td>7</td>             <td>调整过程要素，适应工具，从而形成一个纳入了工具的配置管理过程</td>         </tr>         <tr>             <td>8</td>             <td>考虑这个过程的适用性和效益</td>         </tr>     </tbody> </table> <p>对应过程：6.1组建相应部门和团队负责配置管理部署和实施的团队必须包括</p> <table width="80%" border="1" cellpadding="1">     <tbody>         <tr>             <td>             <div align="center"><strong>序号 </strong></div>             </td>             <td>             <div align="center"><strong>团队成员</strong></div>             </td>             <td>             <div align="center"><strong>职责和要求</strong></div>             </td>         </tr>         <tr>             <td>1</td>             <td>组长<br />             </td>             <td>负责管理小组，并负责配置管理的部署和实施</td>         </tr>         <tr>             <td>2</td>             <td>技术人员</td>             <td>负责考虑将要和配置工具集成的各类工具之间的接口</td>         </tr>         <tr>             <td>3</td>             <td>配置专家</td>             <td>配置工具精通、配置管理理论知识熟悉</td>         </tr>         <tr>             <td>4</td>             <td>过程专家</td>             <td>负责过程建模和主要的过程分析工作</td>         </tr>         <tr>             <td>5</td>             <td>配置管理人员</td>             <td>负责评审新过程，并提供原来配置管理的经验</td>         </tr>         <tr>             <td>6</td>             <td>项目经理</td>             <td>负责评审新过程，并提供配置管理适应于项目的参考</td>         </tr>     </tbody> </table> <p>对应过程：6.2制定各个项目的实施计划计划应当包括的内容：</p>               <table width="80%" border="1" cellpadding="1"><tbody><tr>             <td>             <div align="center"><strong>序号 </strong></div>             </td>             <td>             <div align="center"><strong>计划内容</strong></div>             </td>         </tr>         <tr>             <td>1</td>             <td>目标和完成标准</td>         </tr>         <tr>             <td>2</td>             <td>投资和收益分析</td>         </tr>         <tr>             <td>3</td>             <td>阶段划分和进度安排</td>         </tr>         <tr>             <td>4</td>             <td>资源投入安排</td>         </tr>         <tr>             <td>5</td>             <td>人员分工和组织</td>         </tr>         <tr>             <td>6</td>             <td>风险管理</td></tr></tbody></table></div>原文：http://www.cnblogs.com/lingxzg/archive/2007/10/17/927543.html<div>http://www.cnblogs.com/lingxzg/archive/2007/10/17/927543.html</div><div>http://www.cnblogs.com/lingxzg/archive/2007/10/17/927543.html</div><img src ="http://www.blogjava.net/jasmine214--love/aggbug/352932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-06-24 10:46 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/06/24/352932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Continuous integration with Hudson</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/05/16/350316.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Mon, 16 May 2011 05:54:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/05/16/350316.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/350316.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/05/16/350316.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/350316.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/350316.html</trackback:ping><description><![CDATA[http://www.javaworld.com/javaworld/jw-12-2008/jw-12-hudson-ci.html?page=1<br />
<br />
<br />
<img src ="http://www.blogjava.net/jasmine214--love/aggbug/350316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-05-16 13:54 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/05/16/350316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>做配置管理你需要那些知识？我的几年工作总结。 [转]</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350199.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 13 May 2011 12:52:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350199.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/350199.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350199.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/350199.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/350199.html</trackback:ping><description><![CDATA[做配置管理你需要那些知识？<font style="font-size: 10px; color: #ffffff;">: k/ o3 Y6 g) j" ^0 z2 E) o( v9 L5 O</font><br />
我在做配置管理以前做过两年的测试，期间做过两家公司的iso 9000的内审员，然后老板觉得我比较有耐心，所以赶鸭子上架，和前任学习拉一周，我就是配置管理拉，然后不知不觉，已经6年拉，总结一下，看看会需要些什么呢？<br />
1、软件公司的开发流程，对软件工程一定要熟悉，尤其是开发模型，你不能保证公司的所有项目使用一个模型。比如：瀑布、迭代或者极限编程。只有熟悉这些开发模型，你才能参与到公司的流程制定中去。<br />
2、
熟悉一些标准，比如：iso
9000和cmmi。一个公司想要发展大，想要稳定，就一定会有一套稳定的流程。而熟悉标准，会更有利于你理解和说服你的同事。记得以前一个同事说过这样
一句话，一个公司想要长大，那一定必须是一头小象而不能是一只大蚂蚁。而一个做有流程，愿意将公司的事情流程化的公司才能保证不因人成事，才能长大。<font style="font-size: 10px; color: #ffffff;">. @5 "9 E: Q( L0 j1 ~</font><br />
3、沟通能力。配置管理员的工作就是沟通协助需求、开发及测试人员工作。而一个新的项目的建立意味这大家都是新人，来自不同的行业不同的公司，公司文化不
同，做事的方法也不同，你只有有好的沟通能力，才能说服项目经理支持你的工作，才只能说服开发测试人员按你要求的流程工作。<br />
4、编程能力。想做好配置管理，你就不得不编写一些配置脚本，以方便开发测试人员，同时减少自己的工作量。<br />
5、数据库知识。一般来说配置管理员，同时要管理BUG跟踪或需求管理的系统，那免不了老板会让你提供一些统计数据，所以数据库知识也是必不可少的。<br />
6、系统知识。多说公司的配置管理员还要负责开发测试环境的维护，那么有系统知识，无疑可以减少你求助的机会。<br />
现在说说我做过什么？<font style="font-size: 10px; color: #ffffff;">&amp; g! @2 `9 [: f+ ]5 g! z4 "/ f. q</font><br />
一、上海项目的时候，只是负责系统的配置管理，包括代码编译，上线，这个系统比较大，但是还好，我是从别人手上接手的，所以还在顺序。<br />
二、集团项目的的时候，我同时维护9个省的测试上线环境。<br />
由于用户一直是用unix系统，所以顺便学会拉shell ，学会来在ibm，hp，sun的小型机上安装配置软件。<br />
尤其是bes521的安装，简直是无言啊？宝
蓝从总部派人过来，现场安装，配置、测试，美国总部修改bug，然后打补丁，终于，我写了一本安装手册，两年后公司同事还在用。安装ibm的
websphere的时候，我发现需要打操作系统补丁，于是比较傻瓜的我，安装拉最新版的补丁，要命的是这个websphere比较变态，尽然只能用它指
定版本，所以到现在我都恨websphere啊。<br />
要说最大的收获，就是在压力下面，我做事情很负责，我的努力让公司项目经理面对甲方也很硬气。<font style="font-size: 10px; color: #ffffff;">! b&nbsp;&nbsp;^/ I7 E/ s" V</font><br />
三、做公司的openboss系统。这个系统对我的锻炼很大，工作如下：<font style="font-size: 10px; color: #ffffff;">/ d2 ?% d/ f1 K&amp; d0 Y) I</font><br />
1、写cvs脚本，保证代码能在提交的时候,同时建立开发和构建分支，同时不能是分支之上建立分支。<br />
2、和一个没有任何配置管理经验的开发团队扯皮，扯开发流程，扯目录结构，扯Makefile模板，扯代码命名规范，然后想办法让他们执行。<font style="font-size: 10px; color: #ffffff;">9 U1 J- G8 r0 ^2 D% i+ N6 Z</font><br />
这个系统很大，到今天，已经有11个移动，3个网通，3个电信在使用。分出来的系统现在也有15个拉，仅仅营业和账务两个系统，unix后台就有500多个动态库，当时扯皮，现在受益。<br />
3、和总工办
一起搞unix主机下的编译选项，由于用户的环境复杂，所以要求做到，代码写出来后，可以跨cpu，跨操作系统、跨中间件、跨数据库。所以这个过程让我对
unix下的编译器熟悉起来，不然无法做到。让我自豪的是到现在，开发人员只要修改Makefile模板很少的地方，就可以跨平台编译拉。<br />
4、编写自动编译脚本。通过我们开发的自动编译系统，开发人员只要在浏览器中提交编译单就可以自动编译拉。而如果开始的时候，如果没有将目录规划好，我想自动编译就是无源之水。<font style="font-size: 10px; color: #ffffff;">6 H&amp; H1 ?% b; n5 N</font><br />
这个系统我们web部分用jsp，unix用tcl/tk脚本。现在已经集成到QCS的源码管理中，还在改进，还在使用。<font style="font-size: 10px; color: #ffffff;">7 r) H# K. ~- i6 r</font><br />
<br />
四、公司的QCS系统（质量控制系统）。<br />
这是一个配置管理系统，通过rsh将CVS和QCS结合在一起，用jsp和oracle的存储过程开发，其中包括：需求管理、功能点管理、任务管理、源码管理、bug管理、工程故障管理、接口管理、数据库变更管理、版本管理、发布管理、回退管理等模块的系统。<font style="font-size: 10px; color: #ffffff;">2 z( T! {' a7 c* J: A0 v" M</font><br />
<br />
五、参加公司的EPG小组，并且以配置管理员的身份参与评审。<font style="font-size: 10px; color: #ffffff;">+ E* F) S&nbsp;&nbsp;j( B' |# F# u&nbsp;&nbsp;^</font><br />
公司两年前已经通过CMMI 5的认证。我加入公司的公司只是通过拉CMM
2级。后来由于甲方的要求，公司开始CMMI的认证。这中间有大量的文档要写。尤其是配置管理员，在几乎所有的过程中，都要参与评审，所以准备工作做拉好
久。到 CMMI
5级的时候，就要提供大量的统计数据来说明持续改进的结果，所以对QCS就需要不少地方做改动，来收集数据。还好公司一直注意这块，我们的各种脚本，模
板，都是尽量的优化以满足开发测试人员的需要。所以后来的评审中基本没有费什么事就过拉。<font style="font-size: 10px; color: #ffffff;">* G6 J3 w5 "# z</font><br />
<font style="font-size: 10px; color: #ffffff;">( [" N- P( V% F4 "$ d, `</font><br />
在这个项目中，让我对配置管理中的很多概念理解很深。尤其是在评审的时候，将自己平时做的工作用CMMI的语言讲解，感觉的确是锻炼人。<br />
<font style="font-size: 10px; color: #ffffff;">- a% k3 H% s/ Q5 S# ^, |+ T</font><br />
这中间的很多事情，我的感谢我的师傅，虽然他比我年龄还小，而且也没有带我很久，但是很多问题都是和他讨论中加深理解的，不管是从技术上，还是为人都让我学之不尽啊。<br />
<font style="font-size: 10px; color: #ffffff;">1 h( "&nbsp;&nbsp;C) "8 r&nbsp;&nbsp;t- @7 C</font><br />
要做好配置管理，一定要耐心、细心、恒心。<br />
冰冻三尺非一日之寒。<font style="font-size: 10px; color: #ffffff;">, H3 N' z: f+ I&nbsp;&nbsp;y' V) K</font><br />
<font style="font-size: 10px; color: #ffffff;">* j; V, r: J* w, x; P9 p! ]</font><br />
希望以上内容能给新入行的同行一点帮助。<br />
原文：<br />
<h1><a href="http://bbs.scmlife.com/thread-16353-1-1.html" id="thread_subject">http://bbs.scmlife.com/thread-16353-1-1.html<font style="font-size: 10px; color: #ffffff;"> k/ o3 Y6 g) j" ^0 z2 E) o( v9 L5 O</font><br />
我在做配置管理以前做过两年的测试，期间做过两家公司的iso 9000的内审员，然后老板觉得我比较有耐心，所以赶鸭子上架，和前任学习拉一周，我就是配置管理拉，然后不知不觉，已经6年拉，总结一下，看看会需要些什么呢？<br />
1、软件公司的开发流程，对软件工程一定要熟悉，尤其是开发模型，你不能保证公司的所有项目使用一个模型。比如：瀑布、迭代或者极限编程。只有熟悉这些开发模型，你才能参与到公司的流程制定中去。<br />
2、
熟悉一些标准，比如：iso
9000和cmmi。一个公司想要发展大，想要稳定，就一定会有一套稳定的流程。而熟悉标准，会更有利于你理解和说服你的同事。记得以前一个同事说过这样
一句话，一个公司想要长大，那一定必须是一头小象而不能是一只大蚂蚁。而一个做有流程，愿意将公司的事情流程化的公司才能保证不因人成事，才能长大。<font style="font-size: 10px; color: #ffffff;">. @5 "9 E: Q( L0 j1 ~</font><br />
3、沟通能力。配置管理员的工作就是沟通协助需求、开发及测试人员工作。而一个新的项目的建立意味这大家都是新人，来自不同的行业不同的公司，公司文化不
同，做事的方法也不同，你只有有好的沟通能力，才能说服项目经理支持你的工作，才只能说服开发测试人员按你要求的流程工作。<br />
4、编程能力。想做好配置管理，你就不得不编写一些配置脚本，以方便开发测试人员，同时减少自己的工作量。<br />
5、数据库知识。一般来说配置管理员，同时要管理BUG跟踪或需求管理的系统，那免不了老板会让你提供一些统计数据，所以数据库知识也是必不可少的。<br />
6、系统知识。多说公司的配置管理员还要负责开发测试环境的维护，那么有系统知识，无疑可以减少你求助的机会。<br />
现在说说我做过什么？<font style="font-size: 10px; color: #ffffff;">&amp; g! @2 `9 [: f+ ]5 g! z4 "/ f. q</font><br />
一、上海项目的时候，只是负责系统的配置管理，包括代码编译，上线，这个系统比较大，但是还好，我是从别人手上接手的，所以还在顺序。<br />
二、集团项目的的时候，我同时维护9个省的测试上线环境。<br />
由于用户一直是用unix系统，所以顺便学会拉shell ，学会来在ibm，hp，sun的小型机上安装配置软件。<br />
尤其是bes521的安装，简直是无言啊？宝
蓝从总部派人过来，现场安装，配置、测试，美国总部修改bug，然后打补丁，终于，我写了一本安装手册，两年后公司同事还在用。安装ibm的
websphere的时候，我发现需要打操作系统补丁，于是比较傻瓜的我，安装拉最新版的补丁，要命的是这个websphere比较变态，尽然只能用它指
定版本，所以到现在我都恨websphere啊。<br />
要说最大的收获，就是在压力下面，我做事情很负责，我的努力让公司项目经理面对甲方也很硬气。<font style="font-size: 10px; color: #ffffff;">! b&nbsp;&nbsp;^/ I7 E/ s" V</font><br />
三、做公司的openboss系统。这个系统对我的锻炼很大，工作如下：<font style="font-size: 10px; color: #ffffff;">/ d2 ?% d/ f1 K&amp; d0 Y) I</font><br />
1、写cvs脚本，保证代码能在提交的时候,同时建立开发和构建分支，同时不能是分支之上建立分支。<br />
2、和一个没有任何配置管理经验的开发团队扯皮，扯开发流程，扯目录结构，扯Makefile模板，扯代码命名规范，然后想办法让他们执行。<font style="font-size: 10px; color: #ffffff;">9 U1 J- G8 r0 ^2 D% i+ N6 Z</font><br />
这个系统很大，到今天，已经有11个移动，3个网通，3个电信在使用。分出来的系统现在也有15个拉，仅仅营业和账务两个系统，unix后台就有500多个动态库，当时扯皮，现在受益。<br />
3、和总工办
一起搞unix主机下的编译选项，由于用户的环境复杂，所以要求做到，代码写出来后，可以跨cpu，跨操作系统、跨中间件、跨数据库。所以这个过程让我对
unix下的编译器熟悉起来，不然无法做到。让我自豪的是到现在，开发人员只要修改Makefile模板很少的地方，就可以跨平台编译拉。<br />
4、编写自动编译脚本。通过我们开发的自动编译系统，开发人员只要在浏览器中提交编译单就可以自动编译拉。而如果开始的时候，如果没有将目录规划好，我想自动编译就是无源之水。<font style="font-size: 10px; color: #ffffff;">6 H&amp; H1 ?% b; n5 N</font><br />
这个系统我们web部分用jsp，unix用tcl/tk脚本。现在已经集成到QCS的源码管理中，还在改进，还在使用。<font style="font-size: 10px; color: #ffffff;">7 r) H# K. ~- i6 r</font><br />
<br />
四、公司的QCS系统（质量控制系统）。<br />
这是一个配置管理系统，通过rsh将CVS和QCS结合在一起，用jsp和oracle的存储过程开发，其中包括：需求管理、功能点管理、任务管理、源码管理、bug管理、工程故障管理、接口管理、数据库变更管理、版本管理、发布管理、回退管理等模块的系统。<font style="font-size: 10px; color: #ffffff;">2 z( T! {' a7 c* J: A0 v" M</font><br />
<br />
五、参加公司的EPG小组，并且以配置管理员的身份参与评审。<font style="font-size: 10px; color: #ffffff;">+ E* F) S&nbsp;&nbsp;j( B' |# F# u&nbsp;&nbsp;^</font><br />
公司两年前已经通过CMMI 5的认证。我加入公司的公司只是通过拉CMM
2级。后来由于甲方的要求，公司开始CMMI的认证。这中间有大量的文档要写。尤其是配置管理员，在几乎所有的过程中，都要参与评审，所以准备工作做拉好
久。到 CMMI
5级的时候，就要提供大量的统计数据来说明持续改进的结果，所以对QCS就需要不少地方做改动，来收集数据。还好公司一直注意这块，我们的各种脚本，模
板，都是尽量的优化以满足开发测试人员的需要。所以后来的评审中基本没有费什么事就过拉。<font style="font-size: 10px; color: #ffffff;">* G6 J3 w5 "# z</font><br />
<font style="font-size: 10px; color: #ffffff;">( [" N- P( V% F4 "$ d, `</font><br />
在这个项目中，让我对配置管理中的很多概念理解很深。尤其是在评审的时候，将自己平时做的工作用CMMI的语言讲解，感觉的确是锻炼人。<br />
<font style="font-size: 10px; color: #ffffff;">- a% k3 H% s/ Q5 S# ^, |+ T</font><br />
这中间的很多事情，我的感谢我的师傅，虽然他比我年龄还小，而且也没有带我很久，但是很多问题都是和他讨论中加深理解的，不管是从技术上，还是为人都让我学之不尽啊。<br />
<font style="font-size: 10px; color: #ffffff;">1 h( "&nbsp;&nbsp;C) "8 r&nbsp;&nbsp;t- @7 C</font><br />
要做好配置管理，一定要耐心、细心、恒心。<br />
冰冻三尺非一日之寒。<font style="font-size: 10px; color: #ffffff;">, H3 N' z: f+ I&nbsp;&nbsp;y' V) K</font><br />
<font style="font-size: 10px; color: #ffffff;">* j; V, r: J* w, x; P9 p! ]</font><br />
希望以上内容能给新入行的同行一点帮助。<br />
原文：<br />
<h1><a href="http://bbs.scmlife.com/thread-16353-1-1.html" id="thread_subject"><br />
</a>
</h1>
<br />
</a>
</h1>
<img src ="http://www.blogjava.net/jasmine214--love/aggbug/350199.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-05-13 20:52 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350199.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>提问的智慧</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350198.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 13 May 2011 12:49:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350198.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/350198.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/350198.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/350198.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最近在论坛及群中发现很多人求助，可是总是抓不住主题，所以找啦一个很多年前就有人写的文章给大家看看。* Z7 @+ T) |$ x怎么提问，怎么才能高效率的获得答案。作者：Eric Steven Raymond&nbsp; &nbsp;&nbsp;&nbsp;&lt;esr@thyrsus.com&gt;Thyrsus Enterprises&nbsp; &nbsp;&nbsp;&nbs...&nbsp;&nbsp;<a href='http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350198.html'>阅读全文</a><img src ="http://www.blogjava.net/jasmine214--love/aggbug/350198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-05-13 20:49 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我关于自动编译的一点经验 [转] 	</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350197.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Fri, 13 May 2011 12:44:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350197.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/350197.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350197.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/350197.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/350197.html</trackback:ping><description><![CDATA[<!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><![endif]--><!--[if !mso]>
<style>
st1":*{behavior:url(#ieooui) }
</style>
<![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.0pt;
font-family:"Times New Roman";}
</style>
<![endif]-->
<p><span style="font-family: 宋体;">原文：http://bbs.scmlife.com/thread-16603-1-1.html<br />
</span></p>
<p><span style="font-family: 宋体;">一个项目想要成功，那配置管理的努力是必不可少的。如何做一个好的配置管理，同时减轻自己的负担，那就是一个值得认真思考的问题拉。</span><span style="font-size: 7.5pt; color: white;">+ Z, Z7 d1 W/ J/ e) Q0 A* O1 J# i+ X</span><span><br />
</span><span style="font-family: 宋体;">一个产品想要实现持续集成及日创建，那么非得有一套好的自动编译系统支撑才可以，否则对于一个庞大的系统而言，一个配置管理就算累死也无法满足需求的。</span><span><br />
</span><span style="font-family: 宋体;">下面以我的经验说说任何构建一个自动编译系统。</span><span><br />
</span><span style="font-size: 7.5pt; color: white;">$ E( i$ {4 U: N</span><span><br />
</span><span style="font-family: 宋体;">为了更好的自动编译，我想应该建立一个这样的系统，那就是：</span><span><br />
1</span><span style="font-family: 宋体;">、开发人员或定时触发。</span><span><br />
2</span><span style="font-family: 宋体;">、自动更新编译环境。</span><span style="font-size: 7.5pt; color: white;">- P$ e; s&nbsp;&nbsp;`% ^" c* U2 A0 L</span><span><br />
3</span><span style="font-family: 宋体;">、自动编译。</span><span><br />
<span style="display: none;">( b: C$ m* F&nbsp;&nbsp;t: W9
w&nbsp;&nbsp;l</span>4</span><span style="font-family: 宋体;">、自动分析编译结果。</span><span style="font-size: 7.5pt; color: white;">. U5 A! [6 X4 h6 Z2 ]+ |4 V9 v</span><span><br />
5</span><span style="font-family: 宋体;">、自动通知开发、测试及配置管理员。</span><span style="font-size: 7.5pt; color: white;">$ C+ ~9 h&amp; D! y4 m" c% d</span><span><br />
<br />
</span><span style="font-family: 宋体;">下面我假设情况如下：</span><span><br />
1</span><span style="font-family: 宋体;">、操作系统：平台包括：</span>HP-UX<span style="font-family: 宋体;">、</span>SunOS<span style="font-family: 宋体;">、</span>AIX<span style="font-family: 宋体;">、</span>Linux <span style="font-family: 宋体;">、</span>Windows <span style="font-family: 宋体;">（均包括多个版本）、。</span><span style="font-size: 7.5pt; color: white;">&nbsp;&nbsp;M! c$ t9 ": k</span><span><br />
2</span><span style="font-family: 宋体;">、数据库包括：</span><span>oracle
8i</span><span style="font-family: 宋体;">、</span>9i<span style="font-family: 宋体;">、</span>10G<br />
3<span style="font-family: 宋体;">、编译器包括：</span>aCC<span style="font-family: 宋体;">、</span>CC<span style="font-family: 宋体;">、</span>xlC<span style="font-family: 宋体;">、</span>gcc<span style="font-family: 宋体;">、</span>bcb(windows <span style="font-family: 宋体;">上的集成开发环境</span>) <span style="font-family: 宋体;">、</span>java<span style="font-family: 宋体;">（包括多个版本）</span><span style="font-size: 7.5pt; color: white;">/ R" N3 J* F$ "% L- R, D' b</span><span><br />
4</span><span style="font-family: 宋体;">、项目规模超过千万行代码、模块众多、调用复杂。</span><span style="font-size: 7.5pt; color: white;"># H! A# y: "8 J% f7 C, G! j" `( E</span><span><br />
</span><span style="font-family: 宋体;">那么在这样一个情况下，如果我们考虑用一般的商用工具做，显然成本是很高的。</span><span style="font-size: 7.5pt; color: white;">0 y; l( I* Y: x</span><span><br />
</span><span style="font-family: 宋体;">对于这样一个庞大，复杂的系统，我想在项目启动后，首先要做的是：</span><span><br />
1</span><span style="font-family: 宋体;">、定义编码规范。</span><span style="font-size: 7.5pt; color: white;">0 L</span><span style="font-size: 7.5pt; color: white;"># S* D9 |' y2 @3 @1 G&nbsp;&nbsp;h</span><span><br />
2</span><span style="font-family: 宋体;">、定义</span>C++<span style="font-family: 宋体;">及</span>java<span style="font-family: 宋体;">的编译选项（由于</span>C++<span style="font-family: 宋体;">语言中编译器及平台版本不同，</span>32<span style="font-family: 宋体;">、</span>64<span style="font-family: 宋体;">位要求及数据库的版本等不同要求，所以编译选项显然要提取出来单独处理）。</span><span><br />
3</span><span style="font-family: 宋体;">、定义</span>Makefile <span style="font-family: 宋体;">规范。</span><span><br />
4</span><span style="font-family: 宋体;">、定义模块目录结构。</span><span><br />
5</span><span style="font-family: 宋体;">、定义接口提供方式。</span><span><br />
<span style="display: none;">4 C( J&nbsp;&nbsp;w$ v1 n*
_&nbsp;&nbsp;{, {+ m</span></span><span style="font-family: 宋体;">在定义以上内容的时</span> <span style="font-family: 宋体;">候，一定要遵循一个原则，符合命名规范、尽量可配置、易懂、易于理解。最后组合出的编译命令的字符串不要太长（</span>unix<span style="font-family: 宋体;">操作系统下，不同版本的</span><span>shell
</span><span style="font-family: 宋体;">对一个命令的长度有不同要求、同时由于</span>Makefile<span style="font-family: 宋体;">中如果有很多</span>shell <span style="font-family: 宋体;">脚本的话，编译性能也会受影响）。</span><span style="font-size: 7.5pt; color: white;">3 U&amp; P* h8 Q6 x&amp; A8 E+ P</span><span><br />
</span><span style="font-family: 宋体;">在我用过的系统中，</span>make <span style="font-family: 宋体;">工具，</span>unix <span style="font-family: 宋体;">平台我们使用的是</span> GNU make <span style="font-family: 宋体;">版本</span>3.80<span style="font-family: 宋体;">，</span>java <span style="font-family: 宋体;">用的是</span> ant<span style="font-family: 宋体;">，</span>windows <span style="font-family: 宋体;">平台</span>C++<span style="font-family: 宋体;">用的是</span>bcb <span style="font-family: 宋体;">自带的</span>make<span style="font-family: 宋体;">，不过在编译前先要将</span>bcb<span style="font-family: 宋体;">的工程文件</span>bpr<span style="font-family: 宋体;">文件转换为</span>Makefile<span style="font-family: 宋体;">文件，使用的工具是</span>bpr2make<span style="font-family: 宋体;">（之所以不用</span>bcb<span style="font-family: 宋体;">直接编译，</span> <span style="font-family: 宋体;">主要是为拉自动编译，自动分发编译结果）。</span><span><br />
</span><span style="font-size: 7.5pt; color: white;">2 [3 `" W; x% d- O</span><span><br />
</span><span style="font-family: 宋体;">为了更好的跟踪代码及需求、</span>bug<span style="font-family: 宋体;">变更情况，自动编译系统，应该从开发人员提交代码开始，到发布结束。</span><span style="font-size: 7.5pt; color: white;">( W- J% J4 O4 O/ E, a" m% s</span><span><br />
</span><span style="font-family: 宋体;">流程如下：</span><span style="font-size: 7.5pt; color: white;">( V+ t: ~4 G+ }3 V* e' H; G8 ": k</span><span><br />
1</span><span style="font-family: 宋体;">、开发人员提交代码。</span><span><br />
2</span><span style="font-family: 宋体;">、编译脚本触发，从版本库更新代码到编译服务器。</span><span><br />
3</span><span style="font-family: 宋体;">、设置编译需要的环境变量。</span><span><br />
4</span><span style="font-family: 宋体;">、构造编译需要的</span>Makefile<span style="font-family: 宋体;">。</span><span style="font-size: 7.5pt; color: white;">6
z% i( G5 ~. U2 l( q#
I3 ^+ z9 ~</span><span><br />
5</span><span style="font-family: 宋体;">、执行编译。</span><span><br />
6</span><span style="font-family: 宋体;">、分析编译结果、记录编译结果。</span><span style="font-size: 7.5pt; color: white;">* N2 |9 P5 d% i: N. L</span><span><br />
7</span><span style="font-family: 宋体;">、发邮件通知开发、配置管理、测试人员等相关人。</span><span style="font-size: 7.5pt; color: white;"># k5 |$ u9 ]2 `1 L2 ]0 I</span><span><br />
8</span><span style="font-family: 宋体;">、更新到测试环境测试。</span><span style="font-size: 7.5pt; color: white;">&nbsp;&nbsp;t, {9 D4 y3 ?7 v( Y5 q8 H- @</span><span><br />
9</span><span style="font-family: 宋体;">、配置管理员发布。</span><span><br />
</span><span style="font-size: 7.5pt; color: white;">2 ]2 b# _: ]5 q5 S# G! S* F</span><span><br />
</span><span style="font-family: 宋体;">下面我以</span>cvs<span style="font-family: 宋体;">或</span>svn<span style="font-family: 宋体;">为源码版本库做作说明，需要写一些适当的脚本，并且需要数据库的配合才能工作的比较顺利。</span><span><br />
1</span><span style="font-family: 宋体;">、建议用户表</span><span><br />
<span style="display: none;">( z&nbsp;&nbsp;q&nbsp;&nbsp;O: |- F0 R6
r</span>2</span><span style="font-family: 宋体;">、在数据库中建立产品表。</span><span><br />
3</span><span style="font-family: 宋体;">、在数据库中建立模块表（需要记录模块优先级、模块路径、</span>Makefile <span style="font-family: 宋体;">文件的名称等功能）。</span><span style="font-size: 7.5pt; color: white;">/ w* n9 y' D3 y3 R( L3 u9 x</span><span><br />
4</span><span style="font-family: 宋体;">、建立需求表、任务单表、</span>bug<span style="font-family: 宋体;">表、编译记录表。</span><span style="font-size: 7.5pt; color: white;">, s' t5 N4 m5 L&amp; t) N- Q* X* [</span><span><br />
5</span><span style="font-family: 宋体;">、编写代码提交脚本。实现提交代码的同时，在编译记录表中增加记录，并关联需求单、任务单、</span>BUG<span style="font-family: 宋体;">单功能。</span><span style="font-size: 7.5pt; color: white;">3 O+ N0 n3 e2 p' f</span><span><br />
6</span><span style="font-family: 宋体;">、编写自动编译脚本。实现定时查询数据库，根据编译单，进行编译的功能。需要实现，获取编译单后，自动生成编译环境所需的环境变量，构造编译用</span> Makefile<span style="font-family: 宋体;">，更新待编译代码，编译完成后分析编译结果，给被编译代码打</span>tag<span style="font-family: 宋体;">，获取编译结果的特征串，然后记录到数据库中，并发邮件通知开发人员、</span>
<span style="font-family: 宋体;">测试人员及配置管理人员。</span><span><br />
<br />
</span><span style="font-family: 宋体;">如果以上脚本实现，那么，不管你是要日创建还是随时编译，还是全系统编译，都是轻松的事情拉。</span><span><br />
</span><span style="font-family: 宋体;">虽然</span>windows <span style="font-family: 宋体;">平台和</span>unix <span style="font-family: 宋体;">平台差别很大，</span>c++<span style="font-family: 宋体;">和</span>java<span style="font-family: 宋体;">的差异也很大，但是如果大家将以上要求都用函数实现。我想迁移还是很方便的。</span><span style="font-size: 7.5pt; color: white;">1 t" v+ t&nbsp;&nbsp;U' U*
`" N% ~. L</span><span><br />
</span><span style="font-family: 宋体;">尤其是脚本语言，多数是支持跨平台的。</span><span><br />
<span style="display: none;">2 _* W: V3 t/ Q0 _0 C' q/ k" @) j)
T&amp; m</span></span><span style="font-family: 宋体;">这里主要可能碰到的问题是。</span><span style="font-size: 7.5pt; color: white;">7 r8 O- u! R2 t6 B% @</span><span><br />
1</span><span style="font-family: 宋体;">、模块结构规划不合理。</span><span><br />
<span style="display: none;">: ?# j&nbsp;&nbsp;z: ?' |* g. |0 w. T*
E9 n&nbsp;&nbsp;m</span>2</span><span style="font-family: 宋体;">、公共调用文件的安装问题。</span><span><br />
3</span><span style="font-family: 宋体;">、模块编译顺序的问题。对于复杂的系统，那么调用关系就决定了编译顺序，可能要多次调整。</span><span><br />
4</span><span style="font-family: 宋体;">、编译结果的安装问题。最好是编译完成通知测试人员，让他们自己安装。否则你自动杀掉他们正在测试的进程，他们会找你算账的。</span><span style="font-size: 7.5pt; color: white;">( k/ |( ?$ e' {$ T: q</span><span><br />
5</span><span style="font-family: 宋体;">、编译结果的分析问题。编译结果的分析就需要自己写正则表达式来分析日志了，级联编译中是无法通过失败信号获取编译失败的，只能分析日志。</span><span><br />
6</span><span style="font-family: 宋体;">、邮件发送问题。</span>unix <span style="font-family: 宋体;">平台，配置好</span>DNS<span style="font-family: 宋体;">和</span>sendmail<span style="font-family: 宋体;">就好啦，</span>windows<span style="font-family: 宋体;">平台，如果没有找到你所用脚本语言的邮件发送函数，那么你就的自己用</span><span>telnet
</span><span style="font-family: 宋体;">加</span> smtp <span style="font-family: 宋体;">协议实现拉。</span><span style="font-size: 7.5pt; color: white;">- h5 F!
e" h1 R3 N% F5 e</span><span><br />
<br />
<span style="display: none;">6 `! g" j" Q- l$ f, U8 ^) W0
@# y# y</span></span><span style="font-family: 宋体;">可能有人奇怪我为什么要设计一个数据出来，我想如果有数据库的话，方便维护人员根据编译目标文件的特征串，查找出，这是那一次编译的，生成他的源码有那些，具体版本是什么。</span><span style="font-size: 7.5pt; color: white;">/ n3 i&amp; _+ p9 n5 N) V&amp;
D&nbsp;&nbsp;w</span><span><br />
</span><span style="font-family: 宋体;">同时也可以查找出是为那个需求或</span>BUG<span style="font-family: 宋体;">而修改代码的，修改了那些地方等。同时也可以通过数据库统计，分析出，模块代码的变更情况和工作量，进度等。</span><span style="font-size: 7.5pt; color: white;">8 W/ |; s&amp; w&amp; x* v( |</span><span><br />
</span><span style="font-family: 宋体;">同时也可以分析出那些人老是提交错，经常容易犯那些错误，编译流程改进，作为</span>cmmi 5<span style="font-family: 宋体;">级的数据提供。</span><span style="font-size: 7.5pt; color: white;">1 P/ e5 r$ D8 u0 j7 x' q' R0 ?</span><span><br />
</span><span style="font-family: 宋体;">拉拉杂杂写啦一大堆，希望对大家有用。</span></p>
<p><span style="font-family: 宋体;">看到论坛里面有很多人询问，工具的选择和使用问题。个人建议：如果没有采购的想法。那么我建议使用</span>SVN<span style="font-family: 宋体;">做版本管理工具。理由如下：</span><span><br />
</span><span style="font-family: 宋体;">一、</span>SVN<span style="font-family: 宋体;">的开发团队就是当初</span>CVS<span style="font-family: 宋体;">的开发团队。</span><span style="font-size: 7.5pt; color: white;">( q3 "9 K- W( V" O* i/ n/ S" D</span><span><br />
1</span><span style="font-family: 宋体;">、正式由于</span>CVS<span style="font-family: 宋体;">的很多缺陷，所以才放弃</span>CVS<span style="font-family: 宋体;">，改开发</span>SVN<span style="font-family: 宋体;">的。</span><span><br />
2</span><span style="font-family: 宋体;">、</span>CVS<span style="font-family: 宋体;">以后只会修改</span>BUG<span style="font-family: 宋体;">，不会在出新功能拉。</span><span><br />
3</span><span style="font-family: 宋体;">、</span>CVS<span style="font-family: 宋体;">的权限功能很不完全，犹如鸡肋。</span><span><br />
</span><span style="font-family: 宋体;">二、</span>SVN<span style="font-family: 宋体;">相对于</span>CVS<span style="font-family: 宋体;">有很多优点。</span><span style="font-size: 7.5pt; color: white;">) o+ p; C1 M3 f</span><span><br />
SVN</span><span style="font-family: 宋体;">的优点如下：</span><span><br />
1</span><span style="font-family: 宋体;">、天然支持</span>web<span style="font-family: 宋体;">。</span>SVN<span style="font-family: 宋体;">服务器是可以和</span>apache<span style="font-family: 宋体;">集成的，所以天然就支持</span>HTTP<span style="font-family: 宋体;">协议，就可以通过互联网访问，同时可以使用</span>apache<span style="font-family: 宋体;">的权限系统。而</span>CVS<span style="font-family: 宋体;">只能通过</span>CVSWEB<span style="font-family: 宋体;">来通过浏览器访问。</span><span style="font-size: 7.5pt; color: white;">4 ^1 h3 V2 ]0 P( Z# [&nbsp;&nbsp;q, `; "$ q</span><span><br />
2</span><span style="font-family: 宋体;">、</span>SVN<span style="font-family: 宋体;">支持文件的移动，支持文件的改名，支持目录版本。</span><span><br />
3</span><span style="font-family: 宋体;">、</span>SVN<span style="font-family: 宋体;">提供拉</span>API<span style="font-family: 宋体;">，提供拉各种语言的开发库，这个是</span>CVS<span style="font-family: 宋体;">所不支持的。</span>CVS<span style="font-family: 宋体;">的二次开发，只能通过命令行的方式做脚本，否则你就要在</span>CVS<span style="font-family: 宋体;">的</span>C<span style="font-family: 宋体;">代码中做接口，才能增加或修改功能。</span><span><br />
4</span><span style="font-family: 宋体;">、</span>SVN<span style="font-family: 宋体;">便于和自己开发的配置管理工具集成。原因如上。</span><span style="font-size: 7.5pt; color: white;">8 |3 g7 P&nbsp;&nbsp;o/ _</span><span><br />
5</span><span style="font-family: 宋体;">、</span>SVN<span style="font-family: 宋体;">可以通过</span>LDAP<span style="font-family: 宋体;">和公司的域结合起来，实现单点认证。</span><span><br />
</span><span style="font-family: 宋体;">三、相对于</span>CVS<span style="font-family: 宋体;">和</span>SVN<span style="font-family: 宋体;">，</span>VSS<span style="font-family: 宋体;">有几个个很大的缺点。</span><span><br />
1</span><span style="font-family: 宋体;">、</span>VSS<span style="font-family: 宋体;">是基于</span>CHECKOUT<span style="font-family: 宋体;">、锁模式的，而</span>SVN<span style="font-family: 宋体;">和</span>CVS<span style="font-family: 宋体;">及基于</span>CHECKOUT<span style="font-family: 宋体;">、合并模式的。后者显然更适合协同开发，适合多人修改同一份代码。而且作为配置管理员，也不用疲于奔命的去删除锁。</span><span><br />
2</span><span style="font-family: 宋体;">、</span>VSS<span style="font-family: 宋体;">只支持</span>windows<span style="font-family: 宋体;">平台，而</span>CVS<span style="font-family: 宋体;">和</span>SVN<span style="font-family: 宋体;">是跨平台的。也许一时无所谓，但是如果有一天公司转向类</span>unix<span style="font-family: 宋体;">平台，你就得迁移配置库，重新编写使用手册，并且做培训，为什么不把问题消灭在萌芽状态呢。</span><span style="font-size: 7.5pt; color: white;">* }0 x4 `" `4 e2 `7 Q5 `% _</span><span><br />
3</span><span style="font-family: 宋体;">、</span>VSS<span style="font-family: 宋体;">是要共享目录以便访问。这样在网络病毒猖獗的日子里，你就和病毒做斗争去吧。同时代码安全和是一个大问题啊。</span><span><br />
4</span><span style="font-family: 宋体;">、</span>VSS<span style="font-family: 宋体;">是不支持</span>web<span style="font-family: 宋体;">访问的。</span><span style="font-size: 7.5pt; color: white;">9 V5 b: _" E1 U# ?1 X" o</span><span><br />
5</span><span style="font-family: 宋体;">、权限配置也不够友好。</span><span style="font-size: 7.5pt; color: white;">" S. y$ J, X8</span></p>
<img src ="http://www.blogjava.net/jasmine214--love/aggbug/350197.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-05-13 20:44 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/05/13/350197.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git历险记（四）——索引与提交的幕后故事</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/350012.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Wed, 11 May 2011 06:58:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/350012.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/350012.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/350012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/350012.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/350012.html</trackback:ping><description><![CDATA[<h2>不一样的索引</h2>
<p>我想如果看过<a href="http://www.infoq.com/cn/git-adventures">《Git历险记》的前面三篇文章</a>的朋友可能已经知道怎么用<a href="http://www.kernel.org/pub/software/scm/git/docs/git-add.html">git add</a>，<a href="http://www.kernel.org/pub/software/scm/git/docs/git-commit.html">git commit</a>这两个命令了；知道它们一个是把文件暂存到索引中为下一次提交做准备，一个创建新的提交（commit）。但是它们台前幕后的一些有趣的细节大家不一定知晓，请允许我一一道来。</p>
<p>Git 索引是一个在你的工作目录（working tree）和项目仓库间的暂存区域(staging area)。有了它,
你可以把许多内容的修改一起提交(commit)。 如果你创建了一个提交(commit)，那么提交的一般是暂存区里的内容,
而不是工作目录中的内容。</p>
<p>一个Git项目中文件的状态大概分成下面的两大类，而第二大类又分为三小类：</p>
<ol>
    <li>未被跟踪的文件（untracked file）</li>
    <li>已被跟踪的文件（tracked file）
    <ol>
        <li>被修改但未被暂存的文件（changed but not updated或modified）</li>
        <li>已暂存可以被提交的文件（changes to be committed 或staged）</li>
        <li>自上次提交以来，未修改的文件(clean 或 unmodified)</li>
    </ol>
    </li>
</ol>
<p>看到上面的这么多的规则，大家早就头大了吧。老办法，我们建一个Git测试项目来试验一下：</p>
<p>我们先来建一个空的项目：</p>
<pre>$rm -rf stage_proj<br />
$mkdir stage_proj<br />
$cd stage_proj<br />
$git init<br />
Initialized empty Git repository in /home/test/work/test_stage_proj/.git/<br />
</pre>
<p>我们还创建一个内容是&#8220;hello, world&#8221;的文件：</p>
<pre>$echo "hello,world" &gt; readme.txt</pre>
<p>现在来看一下当前工作目录的状态，大家可以看到&#8220;readme.txt&#8221;处于未被跟踪的状态（untracked file）：</p>
<pre>$git status<br />
# On branch master<br />
#<br />
# Initial commit<br />
#<br />
# Untracked files:<br />
#&nbsp;&nbsp; (use "git add &lt;file&gt;..." to include in what will be committed)<br />
#<br />
#&nbsp;&nbsp; readme.txt<br />
nothing added to commit but untracked files present (use "git add" to track)<br />
</pre>
<p>把&#8220;readme.txt"加到暂存区： $git add readme.txt</p>
<p>现在再看一下当前工作目录的状态：</p>
<pre>$git status<br />
# On branch master<br />
#<br />
# Initial commit<br />
#<br />
# Changes to be committed:<br />
#&nbsp;&nbsp; (use "git rm --cached &lt;file&gt;..." to unstage)<br />
#<br />
#&nbsp;&nbsp; new file:&nbsp;&nbsp; readme.txt<br />
#<br />
</pre>
<p>可以看到现在"readme.txt"的状态变成了已暂存可以被提交（changes to be committed），这意味着我们下一步可以直接执行&#8220;git commit&#8220;把这个文件提交到本地的仓库里去了。</p>
<p>暂存区（staging
area）一般存放在&#8220;git目录&#8220;下的index文件（.git/index）中，所以我们把暂存区有时也叫作索引（index）。索引是一个二进制格
式的文件，里面存放了与当前暂存内容相关的信息，包括暂存的文件名、文件内容的SHA1哈希串值和文件访问权限，整个索引文件的内容以暂存的文件名进行排
序保存的。</p>
<p>但是我不想马上就把文件提交，我想看一下暂存区（staging area）里的内容，我们执行<a href="http://www.kernel.org/pub/software/scm/git/docs/git-ls-files.html">git ls-files</a>命令看一下：</p>
<pre>$git ls-files --stage<br />
100644 2d832d9044c698081e59c322d5a2a459da546469 0&nbsp;&nbsp; readme.txt<br />
</pre>
<p>我们如果有看过<a href="http://www.infoq.com/cn/news/2011/02/git-adventures-local-repository">上一篇文章</a>里
的"庖丁解牛",
你会发现&#8220;git目录&#8220;里多出了&#8221;.git/objects/2d/832d9044c698081e59c322d5a2a459da546469&#8221;这
么一个文件，再执行&#8220;git cat-file -p 2d832d&#8221;
的话，就可以看到里面的内容正是&#8220;hello,world"。Git在把一个文件添加暂存区时，不但把它在索引文件(.git/index)里挂了号，而
且把它的内容先保存到了&#8220;git目录&#8220;里面去了。</p>
<p>如果我们执行&#8221;git add&#8220;命令时不小心把不需要的文件也加入到暂存区中话，可以执行&#8220;git rm --cached filename" 来把误添加的文件从暂存区中移除。</p>
<p>现在我们先在"readme.txt"文件上做一些修改后：</p>
<pre>$echo "hello,world2" &gt;&gt; readme.txt</pre>
<p>再来看一下暂存区的变化:</p>
<pre>$git status<br />
# On branch master<br />
#<br />
# Initial commit<br />
#<br />
# Changes to be committed:<br />
#&nbsp;&nbsp; (use "git rm --cached &lt;file&gt;..." to unstage)<br />
#<br />
#&nbsp;&nbsp; new file:&nbsp;&nbsp; readme.txt<br />
#<br />
# Changed but not updated:<br />
#&nbsp;&nbsp; (use "git add &lt;file&gt;..." to update what will be committed)<br />
#&nbsp;&nbsp; (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)<br />
#<br />
#&nbsp;&nbsp; modified:&nbsp;&nbsp; readme.txt<br />
#</pre>
<p>大家可以看到命令输出里多了一块内容：&#8220;changed but not updated ...... modified:
readme.txt&#8221;。大家可能会觉得很奇怪，我前面不是把"readme.txt"这个文件给添加到暂存区里去了吗，这里怎么又提示我未添加到暂存区
（changed but not updated）呢，是不是Git搞错了呀。</p>
<p>Git 没有错，每次执行&#8220;git
add&#8221;添加文件到暂存区时，它都会把文件内容进行SHA1哈希运算，在索引文件中新加一项，再把文件内容存放到本地的&#8220;git目录&#8220;里。如果在上次执行
&#8220;git add&#8221;之后再对文件的内容进行了修改，那么在执行&#8220;git
status&#8221;命令时，Git会对文件内容进行SHA1哈希运算就会发现文件又被修改了，这时&#8220;readme.txt&#8220;就同时呈现了两个状态：被修改但未
被暂存的文件（changed but not updated），已暂存可以被提交的文件（changes to be
committed）。如果我们这时提交的话，就是只会提交第一次&#8220;git add"所以暂存的文件内容。</p>
<p>我现在对于&#8220;hello,world2"的这个修改不是很满意，想要撤消这个修改，可以执行<a href="http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html">git checkout</a>这个命令：</p>
<pre>$git checkout -- readme.txt</pre>
<p>现在再来看一下仓库里工作目录的状态：</p>
<pre>$git status<br />
# On branch master<br />
#<br />
# Initial commit<br />
#<br />
# Changes to be committed:<br />
#&nbsp;&nbsp; (use "git rm --cached &lt;file&gt;..." to unstage)<br />
#<br />
#&nbsp;&nbsp; new file:&nbsp;&nbsp; readme.txt<br />
#</pre>
<p>好的，现在项目恢复到我想要的状态了，下面我就用<a href="http://www.kernel.org/pub/software/scm/git/docs/git-commit.html">git commit</a> 命令把这个修改提交了吧：</p>
<pre>$git commit -m "project init"<br />
[master (root-commit) 6cdae57] project init&nbsp;&nbsp; 1 files changed, 1 insertions(+), 0 deletions(-)&nbsp;&nbsp;&nbsp; create mode 100644 readme.txt<br />
</pre>
<p>现在我们再来看一下工作目录的状态：</p>
<pre>$git status<br />
# On branch master<br />
nothing to commit (working directory clean)</pre>
<p>大家可以看到&#8220;nothing to commit (working directory clean)&#8221;；如果一个工作树（working
tree）中所有的修改都已提交到了当前分支里（current head），那么就说它是干净的（clean），反之它就是脏的(dirty)。</p>
<h2>SHA1值内容寻址</h2>
<p>正如<a href="http://www.advogato.org/person/apenwarr/diary/371.html">Git is the next Unix</a>
一文中所说的一样，Git是一种全新的使用数据的方式（Git is a totally new way to operate on
data）。Git把它所管理的所有对象（blob，tree，commit，tag&#8230;&#8230;），全部根据它们的内容生成SHA1哈希串值作为对象名；根据目
前的数学知识，如果两块数据的SHA1哈希串值相等，那么我们就可以认为这两块数据是相同 的。这样会带来的几个好处：</p>
<ol>
    <li>Git只要比较对象名，就可以很快的判断两个对象的内容是否相同。</li>
    <li>因为在每个仓库（repository）的&#8220;对象名&#8221;的计算方法都完全一样，如果同样的内容存在两个不同的仓库中，就会存在相同的&#8220;对象名&#8221;。</li>
    <li>Git还可以通过检查对象内容的SHA1的哈希值和&#8220;对象名&#8221;是否匹配，来判断对象内容是否正确。</li>
</ol>
<p>我们通过下面的例子，来验证上面所说的是否属实。现在创建一个和&#8220;readme.txt&#8220;内容完全相同的文件&#8221;readme2.txt&#8220;，然后再把它提交到本地仓库中：</p>
<pre>$echo "hello,world" &gt; readme2.txt<br />
$git add readme2.txt<br />
$git commit -m "add new file: readme2.txt"<br />
[master 6200c2c] add new file: readme2.txt<br />
1 files changed, 1 insertions(+), 0 deletions(-)<br />
create mode 100644 readme2.txt<br />
</pre>
<p>下面的这条很复杂的命令是查看当前的提交（HEAD）所包含的blob对象：</p>
<pre>$git cat-file -p HEAD | head -n 1 | cut -b6-15 | xargs git cat-file -p<br />
100644 blob 2d832d9044c698081e59c322d5a2a459da546469&nbsp;&nbsp;&nbsp; readme.txt<br />
100644 blob 2d832d9044c698081e59c322d5a2a459da546469&nbsp;&nbsp;&nbsp; readme2.txt</pre>
<p>我们再来看看上一次提交（HEAD^）所包含的blob对象：</p>
<pre>$git cat-file -p HEAD^ | head -n 1 | cut -b6-15 | xargs git cat-file -p<br />
100644 blob 2d832d9044c698081e59c322d5a2a459da546469&nbsp;&nbsp;&nbsp; readme.txt</pre>
<p>很明显大家看到尽管当前的提交比前一次多了一个文件，但是它们之间却是在共用同一个blob对象：&#8220;2d832d9&#8221;。</p>
<h2>No delta, just snapshot</h2>
<p>Git 与大部分你熟悉的版本控制系统，如Subversion、CVS、Perforce 之间的差别是很大的。传统系统使用的是：
&#8220;增量文件系统&#8221; （Delta Storage
systems），它们存储是每次提交之间的差异。而Git正好与之相反，它是保存的是每次提交的完整内容（snapshot）；它会在提交前根据要提交
的内容求SHA1哈希串值作为对象名，看仓库内是否有相同的对象，如果没有就将在&#8220;.git/objects"目录创建对应的对象，如果有就会重用已有的
对象，以节约空间。</p>
<p>下面我们来试验一下Git是否真的是以&#8220;snapshot&#8221;方式保存提交的内容。</p>
<p>先修改一下"readme.txt"，给里面加点内容，再把它暂存，最后提交到本地仓库中：</p>
<pre>$echo "hello,world2" &gt;&gt; readme.txt<br />
$git add readme.txt<br />
$git commit -m "add new content for readme.txt"<br />
[master c26c2e7] add new content for readme.txt&nbsp;&nbsp; 1 files changed, 1 insertions(+), 0 deletions(-)</pre>
<p>我们现在看看当前版本所包含的blob对象有哪些：</p>
<pre>$git cat-file -p HEAD | head -n 1 | cut -b6-15 | xargs git cat-file -p<br />
100644 blob 2e4e85a61968db0c9ac294f76de70575a62822e1&nbsp;&nbsp;&nbsp; readme.txt<br />
100644 blob 2d832d9044c698081e59c322d5a2a459da546469&nbsp;&nbsp;&nbsp; readme2.txt</pre>
<p>从上面的命令输出，我们可以看到"readme.txt"已经对应了一个新的blob对象：&#8220;2e4e85a&#8221;，而之前版本的"readme.txt&#8220;对应的blob对象是：&#8220;2d832d9&#8221;。下面我们再来看一看这两个&#8221;blob&#8220;里面的内容和我们的预期是否相同：</p>
<pre>$git cat-file -p 2e4e85a<br />
hello,world<br />
hello,world2<br />
$git cat-file -p 2d832d9<br />
hello,world</pre>
<p>大家可以看到，每一次提交的文件内容还是全部保存的（snapshot）。</p>
<h2>小结</h2>
<p>Git内在机制和其它传统的版本控制系统（VCS）间存在本质的差异，所以Git的里"add"操作的含义和其它VCS存在差别也不足为奇，&#8220;git add&#8220;不但能把未跟踪的文件（untracked file）添加到版本控制之下，也可以把修改了的文章暂存到索引中。</p>
<p>同时，由于采用&#8220;SHA1哈希串值内容寻值&#8220;和&#8221;快照存储（snapshot）&#8220;，让Git成为一个速度非常非常快的版本控制系统（VCS）。</p>
<h2>参考</h2>
<ul>
    <li><a href="http://book.git-scm.com/">GitCommunityBook</a><a href="http://gitbook.liuhui998.com/"> 中文版</a></li>
    <li><a href="http://progit.org/book/">ProGit</a><a href="http://progit.chunzi.me/zh"> 中文版</a></li>
</ul>
<h2>致谢</h2>
<p>感谢上帝对我的眷顾，让我可以有写作专栏的这样一个机会。</p>
<p>感谢朋友们在写作过程的无私帮助：<a href="http://www.infoq.com/cn/author/%E5%BC%A0%E5%87%AF%E5%B3%B0">张凯峰</a>，<a href="http://blog.liuw.name/">刘炜</a>，<a href="http://www.juvenxu.com/">许晓斌</a>，<a href="http://www.dbanotes.net/">Fenng&#8230;&#8230;</a></p>
<p>特别要感謝家人默默支持：）</p>
<p>原文：http://www.infoq.com/cn/news/2011/03/git-adventures-index-commit<br />
</p><img src ="http://www.blogjava.net/jasmine214--love/aggbug/350012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-05-11 14:58 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/05/11/350012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git 历险记（三）——创建一个自己的本地仓库</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349999.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Wed, 11 May 2011 02:56:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349999.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/349999.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349999.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/349999.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/349999.html</trackback:ping><description><![CDATA[<!--[if !mso]>

v":* {behavior:url(#default#VML);}
o":* {behavior:url(#default#VML);}
w":* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}

<![endif]--><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><![endif]--><!--[if !mso]>

st1":*{behavior:url(#ieooui) }

<![endif]--><!--[if gte mso 10]>

/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}

<![endif]-->
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">如果我们要把一个项目加入到Git的版本管理中，可以在项目所在的目录用<span><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-init.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFDjD0EMwGOr9fmxxqsJuBxIn1gbQ">git
init</a></span>命令建立一个空的本地仓库，然后再用<span><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-add.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNHqz555w3br1EOt9FY9ev-ktCsr1Q">git
add</a></span>命令把它们都加入到Git本地仓库的暂存区（<span>stage
or index</span>）中，最后再用<span><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-commit.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFIooWs08Q2yIFcgtDrUgD9Sa6ooQ">git
commit</a></span>命令提交到本地仓库里。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">创建一个新的项目目录，并生成一些简单的文件内容：</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">$ mkdir test_proj</span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">$ cd test_proj</span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">$ echo &#8220;hello,world&#8221; &gt; readme.txt</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">在项目目录创建新的本地仓库，并把项目里的所有文件全部添加、提交到本地仓库中去：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ git init #</span><span style="font-size: 12pt; font-family: 宋体;">在当前的目录下创建一个新的空的本地仓库</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Initialized empty Git repository in
/home/user/test_proj/.git/</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ git add . #</span><span style="font-size: 12pt; font-family: 宋体;">把前目录下的所有文件全部添加到暂存区</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ git commit -m 'project init' #</span><span style="font-size: 12pt; font-family: 宋体;">创建提交</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">[master (root-commit) b36a785] project init</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">1 files changed, 1 insertions(+), 0 deletions(-)</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">create mode 100644 readme.txt</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 18pt; font-family: 宋体;">Git</span></strong><strong><span style="font-size: 18pt; font-family: 宋体;">目录的结构</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-init.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFDjD0EMwGOr9fmxxqsJuBxIn1gbQ">git
init</a></span><span style="font-size: 12pt; font-family: 宋体;">命令在项目的顶层目录中建了一个名为：&#8220;.git&#8221;的目录，它的别名是 &#8220;Git目录&#8221;（<span>Git
directory</span>）。这时&#8221;Git目录&#8221;中虽然有一些文件，但是没有任何提交（commit）在里面，所以我们叫它是空仓库（empty Git repository）。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">和<span>
SVN</span>不同，一个Git项目一般只在项目的根目录下建一个&#8220;.git&#8221;目录，而SVN则会在项目的每一个目录下建一个&#8221;.svn&#8221;目录；这也我喜欢Git的原因之一：）</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Git</span><span style="font-size: 12pt; font-family: 宋体;">把所有的历史提交信息全部存储在&#8220;Git目录&#8221;里，它就是一个Git项目的仓库；你对本地的源代码进行编辑修改后创建的提交也都会先保存在这
里面，然后再推送到远端的服务器。当我们我把项目目录和&#8220;Git目录&#8221;一起拷到其它电脑里，它能马上正常的工作（所有的提交信息全都保存在Git目录 里）；甚至可以只把&#8220;Git目录&#8221;拷走也行，但是要再签出（checkout）一次。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Git</span><span style="font-size: 12pt; font-family: 宋体;">为了 调试的方便，它可以指定项目的Git目录的位置。有两种办法：一是设置&#8220;GIT_DIR&#8221;环境变量，二是在命令行里设定&#8220;--git-dir--git-dir&#8221;参数指定它的位置，大家可以看一下这里<span>(<a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2F&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNHWf-A8f_I0yQb_aiFQZrXvWN-fbw">git(1)
Manual Page</a>)</span>。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 18pt; font-family: 宋体;">庖丁解牛</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">前面的这些东东我在<a href="http://www.google.com/url?q=http%3A%2F%2Fwww.infoq.com%2Fcn%2Fnews%2F2011%2F01%2Fgit-adventures-1&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNEyNOhf4K7Bojpy-USGG665F0BBsw">第一篇</a>里也大概的讲过一些，但是今天我们想不但要开动这辆叫&#8220;Git&#8221;的跑车，还想看看它里面有些什么样的零件，是怎么构成的。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">OK</span><span style="font-size: 12pt; font-family: 宋体;">，我们来看看&#8220;test_proj&#8221;项目里的&#8220;Git目录&#8221;的结构：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$cd test_proj/.git </span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ ls | more </span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">branches/ # </span><span style="font-size: 12pt; font-family: 宋体;">新版的Git已经不再使用这个目录，所以大家看到它 #一般会是空的</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">COMMIT_EDITMSG # </span><span style="font-size: 12pt; font-family: 宋体;">保存着上一次提交时的注释信息</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">config # </span><span style="font-size: 12pt; font-family: 宋体;">项目的配置信息</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">description # </span><span style="font-size: 12pt; font-family: 宋体;">项目的描述信息</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">HEAD # </span><span style="font-size: 12pt; font-family: 宋体;">项目当前在哪个分支的信息</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">hooks/ # </span><span style="font-size: 12pt; font-family: 宋体;">默认的&#8220;hooks&#8221; 脚本文件</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">index # </span><span style="font-size: 12pt; font-family: 宋体;">索引文件，git add 后把要添加的项暂存到这里</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">info/ # </span><span style="font-size: 12pt; font-family: 宋体;">里面有一个exclude文件，指定本项目要忽略的文件 #，看一下这里</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">logs/ # </span><span style="font-size: 12pt; font-family: 宋体;">各个refs的历史信息</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">objects/ # </span><span style="font-size: 12pt; font-family: 宋体;">这个目录非常重要，里面存储都是Git的数据对象</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;"># </span><span style="font-size: 12pt; font-family: 宋体;">包括：提交(commits), 树对象(trees)，二进制对象 #（blobs）,标签对象（tags）。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">#</span><span style="font-size: 12pt; font-family: 宋体;">不明白没有关系，后面会讲的。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">refs/ # </span><span style="font-size: 12pt; font-family: 宋体;">标识着你的每个分支指向哪个提交（commit）。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我先用<span><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-log.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNHGOF0PbZgg56SCNAUc6b8YcZ0HCw">git
log命令</a></span>来看一下这个Git项目里有哪些提交：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ git log</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">commit 58b53cfe12a9625865159b6fcf2738b2f6774844</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Author: liuhui998 &lt;liuhui998@nospam.com&gt;</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Date: Sat Feb 19 18:10:08 2011 +0800</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">project init</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">大家可以看到目前只有一个提交（commit）对象，而它的名字就 是：&#8221;58b53cfe12a9625865159b6fcf2738b2f6774844&#8221;。这个名字就是对象内容的一个SHA签名串值，只要对象里面
的内容不同，那么我们就可以认为对象的名字不会相同，反之也成立。我在使用时一般不用把这个40个字符输全，只要把前面的5~8个字符输完就可以（前提是 和其它的对象名不冲突）。为了方便表示，在不影响表达的情况下，我会只写SHA串值的前6个字符。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们可以用<span><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-cat-file.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNEoC8gCO_c4b7cZ6sYxcs4tNQ2EEQ">git
cat-file</a></span>来看一下这个提交里的内容是什么:</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ git cat-file -p 58b53c </span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">tree 2bb9f0c9dc5caa1fb10f9e0ccbb3a7003c8a0e13</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">author liuhui998 &lt;liuhui998@nospam.com&gt; 1298110208
+0800</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">committer liuhui998 &lt;liuhui998@nospam.com&gt;
1298110208 +0800</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">project init</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">大家可以看到：提交&#8220;58b53c&#8221; 是引用一个名为&#8220;2bb9f0&#8221;的树对象（tree）。一个树对象（tree）可以引用一个或多个二进制对象（blob）, 每个二进制对象都对应一个文件。 更进一步, 树对象也可以引用其他的树对象，从而构成一个目录层次结构。我们再看一下这个树对象（tree）里面有什么东东：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ git cat-file -p 2bb9f0</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">100644 <strong>blob 2d832d9044c698081e59c322d5a2a459da546469
readme.txt</strong></span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">不难看出，2bb9f0&#8221;这个树对象（tree）包括了了一个二进制对象（blob），对应于我们在前面创建的那个叫 &#8221;readme.txt&#8221;的文件。现在我们来看看这个&#8221;blob&#8221;里的数据是不是和前面的提交的内容一致：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ git cat-file -p 2d832d</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">hello,world</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">哈哈，熟悉的&#8220;hello,world&#8221;又回来了。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">想不想看看提交对象、树对象和二进制对象是怎么在&#8221;Git目录&#8220;中存储的；没有问题，执行下面的命令，看看&#8221;.git/objects&#8221;目录里的内容：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">$ find .git/objects</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects/2b</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects/<strong>2b/b9f0c9dc5caa1fb10f9e0ccbb3a7003c8a0e13</strong></span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects/2d</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects<strong>/2d/832d9044c698081e59c322d5a2a459da546469</strong></span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects/58</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects/<strong>58/b53cfe12a9625865159b6fcf2738b2f6774844</strong></span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects/info</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">.git/objects/pack</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">如果大家仔细看上面命令执行结果中的粗体字，所有的对象都使用SHA签名串值作为索引存储在&#8221;.git/objects&#8221;目录之下；SHA串的前两个字符作为目录名，后面的38个字符作为文件名。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">这些文件的内容其实是压缩的数据外加一个标注类型和长度的头。类型可以是提交对象（commit）、二进制对象（blob）、 树对象（tree）或者标签对象（tag）。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 18pt; font-family: 宋体;">如何clone一个远程项目</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我身边的很多朋友是因为要得到某个开源项目的代码，所以才开始学习使用Git。而获取一个项目的代码的一般的做法就是用<span><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-clone.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNH6iEjeR36XCbWHKGgsAFet6EA_og">git
clone</a></span>命令进行直接复制。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">例如，有些朋友可能想看一下最新的<a href="http://www.google.com/url?q=http%3A%2F%2Fgit.kernel.org%2F%3Fp%3Dlinux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git%3Ba%3Dsummary&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFH3yns1QmLp-eP2iG75j_IfOnR5Q">linux内核源代码</a>，当我们打开它的<a href="http://www.google.com/url?q=http%3A%2F%2Fgit.kernel.org%2F%3Fp%3Dlinux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git%3Ba%3Dsummary&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFH3yns1QmLp-eP2iG75j_IfOnR5Q">网站</a>时，发现有如下面的一段提示：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">URL</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">URL</span><span style="font-size: 12pt; font-family: 宋体;">下面的三行字符串表示三个地址，我们可以通过这三个地址得到同样的一份Linux内核源代码。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">也就是说下面这三条命令最终得到的是同一份源代码：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">git clone
http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">git cone
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们先来看一下URL，git://、http://、https://这些代表是传输git仓库的协议形式，而&#8220;<a href="http://www.google.com/url?q=http%3A%2F%2Fgit.kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNHMKd3sqQYTqxWfWCYHzntVAuXQCA">git.kernel.org</a>&#8220;则代表了Git仓库存储的服务器名字（域名），<span>&#8220;<a href="http://www.google.com/url?q=https%3A%2F%2Fgit.kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNF2MiBP8HaUZ0irlRK3_Ka-5XQ-eQ">/pub/scm/linux/kernel/git/torvalds/linux-2.6.git&#8221;</a>
</span>则代表了Git仓库在服务器上位置。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Git </span><span style="font-size: 12pt; font-family: 宋体;">仓库除了可以通过上面的</span><span style="font-size: 12pt; font-family: 宋体;">git</span><span style="font-size: 12pt; font-family: 宋体;">、</span><span style="font-size: 12pt; font-family: 宋体;">http</span><span style="font-size: 12pt; font-family: 宋体;">、</span><span style="font-size: 12pt; font-family: 宋体;">https</span><span style="font-size: 12pt; font-family: 宋体;">协议传输外还可以通过</span><span style="font-size: 12pt; font-family: 宋体;">ssh</span><span style="font-size: 12pt; font-family: 宋体;">、</span><span style="font-size: 12pt; font-family: 宋体;">ftp(s)</span><span style="font-size: 12pt; font-family: 宋体;">、</span><span style="font-size: 12pt; font-family: 宋体;">rsync</span><span style="font-size: 12pt; font-family: 宋体;">等协议来传输。<span><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.kernel.org%2Fpub%2Fsoftware%2Fscm%2Fgit%2Fdocs%2Fgit-clone.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNH6iEjeR36XCbWHKGgsAFet6EA_og">git
clone</a></span>的本质就是把&#8220;Git目录&#8221;里面的内容拷贝过来，大家想想看，一般的&#8220;Git目录&#8221;里有成千上万的各种对象（提交对象，树对象，二进制对象......)，如果逐一复制的话，其效率就可想而知。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">如果通过git、ssh协议传输，服务器端会在传输前把需要传输的各种对象先打好包再进行传输；而http（s）协议则会反复请求要传输的不同对 象。如果仓库里面的提交不多的话，前者和后者的效率相差不多；但是若仓库里有很多提交的话，git、ssh协议进行传输则会更有效率。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">不过现在Git对http（s）协议传输Git仓库做了一定的优化，http（s）传输现在也能达到ssh协议的效率，有兴趣的朋友可以看一下这里（<span><a href="http://www.google.com/url?q=http%3A%2F%2Fprogit.org%2F2010%2F03%2F04%2Fsmart-http.html&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNH3nDvNOr6JXlew6_A3otOmOTRfXw">Smart
HTTP Transport</a></span>）。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">好的，现在我们执行了下面这条命令，把linux-2.6的最新版源代码clone下来：</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">$cd ~/</span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">$mkdir temp</span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">$git clone
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Initialized empty Git repository in
/home/liuhui/temp/linux-2.6/.git/</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">remote: Counting objects: 1889189, done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">remote: Compressing objects: 100% (303141/303141), done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Receiving objects: 100% (1889189/1889189), 385.03 MiB |
1.64 MiB/s, done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">remote: Total 1889189 (delta 1570491), reused 1887756
(delta 1569178)</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Resolving deltas: 100% (1570491/1570491), done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Checking out files: 100% (35867/35867), done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">当我们执行了<span>&#8220;git clone
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git&#8221;</span>这条命令后大家可以看到这条输出：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Initialized empty Git repository in
/home/user/temp/linux-2.6/.git/</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">这就是意味着我们在本地先建了一个&#8220;linux-2.6&#8221;目录，然后在这个目录建了一个空的Git本地仓库（Git目录）；里面将会存储从网上拉下来的历史提交。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">下面两条输入代表服务器现在调用<span><a href="http://www.google.com/url?q=http%3A%2F%2Fgit-pack-objects%2F&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFejHf4TiO1wTav6c-SWWSSTWLhNQ">
git-pack-objects</a> </span>对它的仓库进行打包和压缩：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">remote: Counting objects: 1888686, done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">remote: Compressing objects: 100% (302932/302932), done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">然后客户端接收服务器端发过送过来的数据：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Receiving objects: 100% (1889189/1889189), 385.03 MiB |
1.64 MiB/s, done.</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">在我们执行完上面的clone linux-2.6代码的的操作后，Git会从&#8220;Git目录&#8221;里把最新的代码到签出（checkout）到&#8220;linux-2.6&#8221;这个目录里面。我们一般
把本地的&#8220;linux-2.6&#8221;这个目录叫做&#8221;工作目录&#8220;（<span>work
directory</span>），它里面保存着你从其它地方clone（<span>or
checkout</span>）过来的代码。当你在项目的不同分支间切换时，&#8220;工作目录&#8221;中的文件可能会被替换或者删除；&#8220;工作目录&#8221;只是保存着当前的工作，你可以修 改里面文件的内容直到下次提交为止。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">大家还记得前面的&#8220;庖丁解牛&#8221;吗，是不是觉得只杀一头叫&#8220;hello,world&#8221;的小牛太不过瘾了。没有问题，拿起前面的那把小刀，来剖析一下现在躺在你硬盘里这头叫&#8220;linux-2.6&#8221;大牛看看，我想一定很好玩。</span></p>
<div style="text-align: center;" align="center"><span style="font-size: 12pt; font-family: 宋体;">
<hr width="100%" align="center" size="2" />
</span></div>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">在写篇文章的过程中，我要感谢在那些关心我并提出真诚意见的朋友，如果没有你们真诚的意见，我也许没有这么强烈的紧迫感，也不会深深的感到自己的不足。我是第一次写专栏，<a href="http://www.infoq.com/cn/bycategory.action?authorName=%E5%BC%A0%E5%87%AF%E9%94%8B">张凯锋</a>同学给了我很大的帮助。最后还是要感谢我的家人，是他们让我有时间来进行写作：）</span></p>
<p style="text-align: left;" align="left">原文：http://www.infoq.com/cn/news/2011/02/git-adventures-local-repository<br />
</p><img src ="http://www.blogjava.net/jasmine214--love/aggbug/349999.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-05-11 10:56 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349999.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git历险记（二）——Git的安装和配置（转）</title><link>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349992.html</link><dc:creator>幻海蓝梦</dc:creator><author>幻海蓝梦</author><pubDate>Wed, 11 May 2011 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349992.html</guid><wfw:comment>http://www.blogjava.net/jasmine214--love/comments/349992.html</wfw:comment><comments>http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349992.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jasmine214--love/comments/commentRss/349992.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jasmine214--love/services/trackbacks/349992.html</trackback:ping><description><![CDATA[<p>各位同学，上回<a href="http://www.infoq.com/cn/news/2011/01/git-adventures-1">Git历险记（一）</a>讲了一个 &#8220;hello Git&#8221; 的小故事。有的同学可能是玩过了其它分布式版本控制系统（DVCS），看完之后就触类旁通对Git就了然于胸了；也有的同学可能还如我当初入手Git一样，对它还是摸不着头脑。</p>
<p>从这一篇开始，我就将比较&#8220;啰嗦&#8221;的和大家一起从零开始经历Git使用的每一步，当然对我而言这也是一个重新认识Git的过程。</p>
<p>使用Git的第一步肯定是安装Git，因为在多数平台上Git是没有预装的。我平时主要的工作环境是windows和Linux（ubuntu），我想看这篇文章的同学多半也是在这两个平台下工作；下面我讲一下如何在这两个平台下安装和配置Git。</p>
<p>BTW:如果是苹果平台的用户的安装可以参看一下这里(<a href="http://gitbook.liuhui998.com/2_1.html">1</a>,<a href="http://progit.chunzi.me/zh/ch1-4.html">2</a>)，配置和命令行的使用与windows、Linux（*nix）平台差别不大。</p>
<h3><strong>Linux (*nix) 平台</strong></h3>
<p>Linus开发Git的最初目的就是为了开发Linux内核服务的，自然它对Linux的平台支持也是最棒的。在Linux下安装Git大约有几种方法：</p>
<p><strong>从源代码开始(这种方法也适合于多数*nix平台)</strong></p>
<p>从<a href="http://git-scm.com/">Git官网</a>的<a href="http://git-scm.com/download">下载页面</a>下载它最新稳定版的<a href="http://kernel.org/pub/software/scm/git/git-1.7.3.5.tar.bz2">源代码</a>，就可以从源代码开始编译、安装：</p>
<pre>$ wget http://kernel.org/pub/software/scm/git/git-1.7.3.5.tar.bz2<br />
$ tar -xjvf git-1.7.3.5.tar.bz2<br />
$ cd git-1.7.3.5<br />
$ make prefix=/usr all ;# prefix设置你的Git安装目录<br />
$ sudo make prefix=/usr install ;# 以root权限运行<br />
</pre>
<p>为了编译Git的源代码，我们还需要一些库: <a href="http://expat.sourceforge.net/">expat</a>、<a href="http://curl.linux-mirror.org/">curl</a>、 <a href="http://www.zlib.net/">zlib</a> 和 <a href="http://www.openssl.org/">openssl</a>； 除了expat 外，其它的库可能在你的机器上都安装了。</p>
<p><strong>使用安装包管理器（apt 或 yum）</strong></p>
<p>在 fedora 等系统下用<a href="http://fedoraproject.org/wiki/Tools/yum">yum</a> ：</p>
<pre>$ yum install git-core </pre>
<p>在debian, ubuntu等系统下用<a href="http://en.wikipedia.org/wiki/Advanced_Packaging_Tool">apt</a> ：</p>
<pre>$ apt-get install git-core</pre>
<p>有时候，你系统里的安装包管理器出现了问题，或是要安装Git的机器不能上网、没有编译器的话，你可以从下面的站点去下载 &#8220;.deb&#8221; 或 &#8220;.rpm&#8221;的安装包：</p>
<ul>
    <li><a href="http://kernel.org/pub/software/scm/git/RPMS/">RPM Packages</a></li>
    <li><a href="http://www.backports.org/debian/pool/main/g/git-core/">Stable Debs</a></li>
</ul>
<h3><strong>Windows平台</strong></h3>
<p>windows平台有两个模拟*nix like运行环境的工具：<a href="http://www.cygwin.com/">cygwin</a>，<a href="http://www.mingw.org/wiki/MSYS">msys</a>；Git在<a href="http://www.cygwin.com/">cygwin</a>，<a href="http://www.mingw.org/wiki/MSYS">msys</a>下都有相应的移植版本。我个人觉得msys平台下的<a href="http://code.google.com/p/msysgit/">msysGit</a>最好用，现在我在windows下也是用的这个版本。</p>
<p>很多同学可能要问，现在windows下有那多Git用户，为什么Git不直接出一个windows native版。俺当年翻看了一下<a href="http://www.kernel.org/pub/software/scm/git/git-0.01.tar.bz2">Git的源代码</a>，它里面使用了大量的*nix平台的native api，而这些api在windows下是没有的，所以必须要用cygwin、msys这样的一个中间层来满足软件移植的要求。</p>
<p>下面我&#8220;啰嗦&#8221;一下如何在windows下安装msysGit。</p>
<h3><strong>下载</strong></h3>
<p>到它的<a href="http://code.google.com/p/msysgit/downloads/list">下载页面</a>去下载一个最新的完整安装包，笔者在撰写本文时下载的是<a href="http://msysgit.googlecode.com/files/Git-1.7.3.1-preview20101002.exe">这个</a>。</p>
<h3><strong>安装</strong></h3>
<p>安装的过程没有什么好说的，一般是开始安装后，一路的点击&#8220;下一步&#8221;。由于windows平台的换行符（CRLF）和Linux(*nix)平台的换行符（LF）不同，那么在windows下开发其它平台软件的朋友有一个地方要注意（见下图)：</p>
<p><img _p="true" alt="" _href="img://image1.jpg" src="http://www.infoq.com/resource/news/2011/01/git-adventures-install-config/zh/resources/image1.JPG" border="0" /></p>
<p>在这里一最好选&#8220;Checkout as-is, commit as-is&#8221;这个选项，这样，Git就不会修改你代码的换行符风格。</p>
<p>以前有个朋友因为选错了这个选项，以致他在windows平台下的一签出（checkout）其它平台的代码，就会显示&#8221;已修改&#8220;（modified），不过后来可能msysGit也认识到这个问题了，就把默认选项改成了这个选项。</p>
<p>BTW: 其实前面两项也是有用的，如果对windows和Linux(*nix)平台<a href="http://en.wikipedia.org/wiki/Newline">如何处理换行符</a>很熟悉的话，也可以尝试一下前面两个选项：）</p>
<h2><strong>配置Git</strong></h2>
<p>在Linux下和windows下配置Git的方法差不多，只是在Linux下，可以在命令行里直接使用<a href="http://www.kernel.org/pub/software/scm/git/docs/git-config.html">git config</a>进行配置, 而在windows下则要先打开&#8220;Git Bash&#8221;，进入msysGit命令行界面，再用<a href="http://www.kernel.org/pub/software/scm/git/docs/git-config.html">git config</a>命令进行相应的配置操作。</p>
<p>好了，前面安装好了Git，现在我们开始配置：</p>
<p>第一个需要配置的就是用户的用户名和email，因为这些内容会出现在你的每一个提交（commit）里面的，像下面这样：</p>
<pre>$ git log #我们用git log查看当前仓库的提交（commit）日志<br />
commit 71948005382ff8e02dd8d5e8d2b4834428eece24<br />
Author: author &lt;author@corpmail.com&gt;<br />
Date: Thu Jan 20 12:58:05 2011 +0800<br />
Project init<br />
</pre>
<p>下面的这两行命令就是设置用户名和email：</p>
<pre>$ git config <strong>--global </strong>user.name author #将用户名设为author<br />
$ git config <strong>--global </strong>user.email author@corpmail.com #将用户邮箱设为author@corpmail.com<br />
</pre>
<p>Git的配置信息分为全局和项目两种，上面命令中带了&#8220;--global"参数，这就意味是在进行全局配置，它会影响本机上的每个一个Git项目。</p>
<p>大家看到，上面我们用的是@corpmail（公司邮箱）；但是有时候我们可能也参与了一些开源项目，那么就需要新的用户名和自己的私人邮箱，Git 可以为每个项目设定不同的配置信息。</p>
<p>在命令行环境，进入Git项目所在目录，执行下面的命令：</p>
<pre>$ git config　user.name nickname#将用户名设为nickname<br />
$ git config　user.email nickname@gmail.com #将用户邮箱设为nickname@gmail.com<br />
</pre>
<p>Git的设计哲学和Linux（*nix）一样，尽量的使用<a href="http://www.faqs.org/docs/artu/textualitychapter.html">&#8220;文本化&#8221;（Textuality）</a>；它里面尽量用文本化的形式存储信息，对于配置信息也更是如此，用户的这些配置信息全部是存储在文本文件中。Git的全局配置文件是存放在"~/.gitconfig"（用户目录下的.gitconfig）文件中：</p>
<p>我们用cat、head命令查看全局配置信息文件，并假设相关配置信息存储在文件的前3行（当然也有可能不在前3行，这里只是为了方便表示）</p>
<pre>$ cat ~/.gitconfig | head -3 <br />
[user]<br />
name = author<br />
email = author@corpmail.com<br />
</pre>
<p>而项目配置文件是存放在Git项目所在目录的".git/config"文件中，这里也像上面一样用cat、head命令查看一下：</p>
<pre>$ cat .git/config | head -3<br />
[user]<br />
name = nickname<br />
<br />
</pre>
<p>如果大家对于Git熟悉后，可以直修改&#8221;~/.gitconfig&#8221;,&#8221;.git/config&#8221;这两个文件进行配置。</p>
<p>Git里还有很多可以配置的地方，大家可以参考一下<a href="http://www.kernel.org/pub/software/scm/git/docs/git-config.html">git config</a> 和 <a href="http://gitbook.liuhui998.com/5_7.html">定制git</a>。</p>
<hr />
<p>这一篇写起来有点平淡无奇，但这是一个Git用户迈出的第一步。后面我还会有一系列的文章出来，都是我个人使用过程中的感悟。</p>
<p>有朋友问我：&#8220;为什么把文章叫作：&#8216;Git历险记&#8217;&#8221;。这是因为在使用Git的历程中，我碰到过N多的问题；同时也觉得它有点小复杂。但是当这些问题解开后，就有时不得不赞叹它设计的巧妙之处。</p>
<p>如果大家对于我的文章有什么问题和建议，欢迎给我写邮件：<img _p="true" alt="" _href="img://image1.jpg" src="http://www.infoq.com/resource/news/2011/01/git-adventures-install-config/zh/resources/image2.JPG" border="0" /></p>
<p>之前我建立了一个 <a href="https://groups.google.com/group/git123">git中文用户组</a> ，如果大家在使用Git的过程中碰到什么麻烦事，欢迎你在这个用户组里提问。</p>
<p>参考资料：</p>
<ul>
    <li><a href="http://book.git-scm.com/">GitCommunityBook</a> <a href="http://gitbook.liuhui998.com/">中文版</a></li>
    <li><a href="http://progit.chunzi.me/zh">ProGit</a> <a href="http://progit.chunzi.me/zh">中文版</a></li>
    <li><a href="http://www.kernel.org/pub/software/scm/git/docs/git-config.html">git config</a></li>
</ul>
<p>感谢<a href="http://www.infoq.com/cn/bycategory.action?authorName=%E5%BC%A0%E5%87%AF%E5%B3%B0">张凯峰</a>对本文的策划及无比耐心的审校。</p>
<p>感谢家人在我的写作过程中的默默支持。</p>
<pre>原文：http://www.infoq.com/cn/news/2011/01/git-adventures-install-config<br />
email = nickname@gmail.com</pre><img src ="http://www.blogjava.net/jasmine214--love/aggbug/349992.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jasmine214--love/" target="_blank">幻海蓝梦</a> 2011-05-11 10:26 <a href="http://www.blogjava.net/jasmine214--love/archive/2011/05/11/349992.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>