﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-www.testage.net---软件测试---RedHat Linux测试环境搭建---MYLIFE</title><link>http://www.cnitblog.com/jakiegu/</link><description>测试时代的gufeng</description><language>zh-cn</language><lastBuildDate>Mon, 04 May 2026 20:56:38 GMT</lastBuildDate><pubDate>Mon, 04 May 2026 20:56:38 GMT</pubDate><ttl>60</ttl><item><title>性能测试-根据Loadrunner官方说明来解释Vu的进程与线程区别</title><link>http://www.cnitblog.com/jakiegu/archive/2009/06/11/59284.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Thu, 11 Jun 2009 07:52:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2009/06/11/59284.html</guid><wfw:comment>http://www.cnitblog.com/jakiegu/comments/59284.html</wfw:comment><comments>http://www.cnitblog.com/jakiegu/archive/2009/06/11/59284.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/jakiegu/comments/commentRss/59284.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jakiegu/services/trackbacks/59284.html</trackback:ping><description><![CDATA[在Loadrunner里面生成Vu的方式有2种，在&#8220;Runtime settings&#8221;里面有设置，具体看下图，如果选择Run Vuser as a
<p>thread表示Vu按照一个线程生成，如果选择 Run Vuser as a process，则Vu按照进程（非多线程）方式生成<br><img src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/6.11111111.PNG" border=0><br>&nbsp; </p>
<p><span>下面我对上述的话做一个简单的翻译：</span></p>
<p><span>Loadrunner</span><span>支持多线程环境，使用多线程的方法能使每台负载生成器运行更多的</span><span>VU</span><span>，但是只有支持线程安全的协议，才能使用</span><span>Loadrunner</span><span>的</span><span>VU</span><span>并发方式</span></p>
<p><span>下表列出哪些协议不能支持线程并发</span></p>
<p><span>Sybase-Dblib,Infomix,Tuxedo,and PeopleSoft-Tuxedo</span></p>
<p><span>当使用进程并发是，在任务管理器中有</span><span>mdrv.exe</span><span>的进程，比如下图，我以</span><span>10</span><span>个</span><span>VU</span><span>用户并发，就会在任务管理器中出现</span><span>10</span><span>个</span><span>mmdrv</span><span>进程</span></p>
<p><img src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/6.222222222222222222222.JPG" border=0><br><br></p>
<div title="Print Page Break" style="FONT-SIZE: 1px; PAGE-BREAK-BEFORE: always; VERTICAL-ALIGN: middle; HEIGHT: 1px; BACKGROUND-COLOR: #c0c0c0">&nbsp; </div>
<p>&nbsp; </p>
<p><span>如果以多线程方式并发，只会出现一个</span><span>mmdrv</span><span>进程，一个进程可以支持</span><span>50VU</span><span>的线程并发，</p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Loadrunner</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的参考帮助还说明了，如果采用多线程方式并发，</span><span lang=EN-US>Load Generator</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将会比多进程支持更多的用户，具体的一个</span><span lang=EN-US>VU</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">占用内存的取值根据</span><span lang=EN-US>Loadrunner</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的版本不同而不同。</span></p>
<p></span><img height=134 src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/6.22222222.PNG" width=99 border=0>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;Loadrunner8.1<br><img src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/6.3333333.PNG" border=0></p>
<p>Loadrunner9.0<br>&nbsp; <span>由于本人对操作系统底层的原理并不是特别懂，我知道如果一个</span><span>VU</span><span>从外部访问的话都会以一个进程的方式请求和分配系统的资源，当</span><span>VU</span><span>并模拟成了线程的方式，我不知道仿真度上面是否有区别，还请知道的人多多提出自己的意见。<br></p>
<div title="Print Page Break" style="FONT-SIZE: 1px; PAGE-BREAK-BEFORE: always; VERTICAL-ALIGN: middle; HEIGHT: 1px; BACKGROUND-COLOR: #c0c0c0">&nbsp; </div>
</span><a href="http://www.cnitblog.com/jakiegu/"><br>文章最后附上进程和线程的区别，摘自baidu<br>进程和线程的区别：<br>解释一：<br>&nbsp;
<p><span>线程是一种操作系统对象，代表着一个进程中要被执行的代码的路径。每一个</span><span>WIN32</span><span>应用程序至少有一个线程</span><span>--</span><span>通常称</span><span>为住线程或默认线程</span><span>--</span><span>但应用程序可以自由地创建其他线程来执行其他任务！</span></p>
<p><span>进程是程序的一次动态执行过程，它对应了从代码加载、执行到执行完毕的一个完整过程，这个过程也是进程本身从产</span><span>生、发展到消亡的过程</span><span>线程是比进程更小的执行单位。一个进程在其执行过程能够中，可以产生</span> <span>多个线程，形成多条执行线索。每条线索，</span><span>即每个线程也有它自身的产生、存在和消亡过程，也是一个动态的概念。</span><span>一个程序应该只有一个进程吧，但是可以拥有多个线程。</span></p>
<p><span>可以说，一个执文件被运行后，就可以称为是一个进程了。但是进程只是存在内存中，实际上他是不会做任何事情的。</span><span>这个时候，起作用的就是线程了。线程是程序的执行者，一个程序至少有一个线程，但是在多线程的操作系统中，可以</span><span>有一个以上的线程。</span></p>
<p>&nbsp;<span>其实我们可以把线程看成是我们排队买肯德鸡吃（循环的排队，一直排下去，知道我不想买了，退出）。每人都有机会</span><span>到达队伍的最前端去买东西，这个就好比是线程，都有机会被程序执行。但是线程真正起作用的时候，就是我们在队伍</span><span>的最前端买东西到东西买完后，这一段时间，这是线程真正执行的阶段。</span><br><br>解释二：<br><span>进程和线程都是由操作系统所体现的程序运行的基本单元，系统利用该基本单元实现系统对应用的并发性。<br></span><span>进程和线程的区别在于：</span></p>
<p><span>简而言之</span><span>,</span><span>一个程序至少有一个进程</span><span>,</span><span>一个进程至少有一个线程</span><span>.</span><span>线程的划分尺度小于进程，使得多线程程序的并发性高。</span><span>另外，进程在执行过程中拥有独立的内存单元，而多个线程共享内存，从而极大地提高了程序的运行效率。</span><span>线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出</span> <span>口。但是</span><span>线程不能够独立执行，必须依存在应用程序中，由应用程序提供多个线程执行控制。</span><span>从逻辑角度来看，多线程的意义在于一个应用程序中，有多个执行部分可以同时执行。但操作系统并没有将多个线程看</span><span>做多个独立的应用，来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。</span><span>进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动</span><span>,</span><span>进程是系统进行资源分配和调度的一个独立单位</span><span>. </span><span>线程是进程的一个实体</span><span>,</span><span>是</span><span>CPU</span><span>调度和分派的基本单位</span><span>,</span><span>它是比进程更小的能独立运行的基本单位</span><span>.</span><span>线程自己基本上不拥有</span><span>系统资源</span><span>,</span><span>只拥有一点在运行中必不可少的资源</span><span>(</span><span>如程序计数器</span><span>,</span><span>一组寄存器和栈</span><span>),</span><span>但是它可与同属一个进程的其他的线</span><span>程共享进程所拥有的全部资源</span><span>. </span><span>一个线程可以创建和撤销另一个线程</span><span>;</span><span>同一个进程中的多个线程之间可以并发执行</span><span>.<br></span></p>
<p><br>关于进程安全<br>&nbsp; </p>
<p><span>如果你的代码所在的进程中有多个线程在同时运行，而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的，而且其他的变量的值也和预期的是一样的，就是线程安全的。</span><span>或者说</span><span>:</span><span>一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性</span><span>,</span><span>也就是说我们不用考虑同步的问题。</span><span>线程安全问题都是由全局变量及静态变量引起的。</span><span>若每个线程中对全局变量、静态变量只有读操作，而无写操作，一般来说，这个全局变量是线程安全的；若有多个线程同时执行写操作，一般都需要考虑线程同步，否则就可能影响线程安全。</span></p>
<p><span>举例：</span></p>
<p><span>　比如一个</span><span> ArrayList </span><span>类，在添加一个元素的时候，它可能会有两步来完成：</span><span>1. </span><span>在</span><span> Items[Size] </span><span>的位置存放此元素；</span><span>2. </span><span>增大</span><span> Size </span><span>的值。</span><span> </span></p>
<p><span>　　在单线程运行的情况下，如果</span><span> Size = 0</span><span>，添加一个元素后，此元素在位置</span><span> 0</span><span>，而且</span><span> Size=1</span><span>；</span><span> </span></p>
<p><span>　　而如果是在多线程情况下，比如有两个线程，线程</span><span> A </span><span>先将元素存放在位置</span><span> 0</span><span>。但是此时</span><span> CPU </span><span>调度线程</span><span>A</span><span>暂停，线程</span><span> B </span><span>得到运行的机会。线程</span><span>B</span><span>也向此</span><span> ArrayList </span><span>添加元素，因为此时</span><span> Size </span><span>仍然等于</span><span> 0 </span><span>（注意哦，我们假设的是添加一个元素是要两个步骤哦，而线程</span><span>A</span><span>仅仅完成了步骤</span><span>1</span><span>），所以线程</span><span>B</span><span>也将元素存放在位置</span><span>0</span><span>。然后线程</span><span>A</span><span>和线程</span><span>B</span><span>都继续运行，都增加</span><span> Size </span><span>的值。</span><span> </span></p>
<p><span>　　那好，现在我们来看看</span><span> ArrayList </span><span>的情况，元素实际上只有一个，存放在位置</span><span> 0</span><span>，而</span><span> Size </span><span>却等于</span><span> 2</span><span>。这就是&#8220;线程不安全&#8221;了。</span><br><br>test8848-谷峰</a></p>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/59284.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2009-06-11 15:52 <a href="http://www.cnitblog.com/jakiegu/archive/2009/06/11/59284.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>参数化--LoadRunner中文版帮助和英文版帮助有一点出入，各位测试工程师注意了</title><link>http://www.cnitblog.com/jakiegu/archive/2008/12/15/52645.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Mon, 15 Dec 2008 08:48:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/12/15/52645.html</guid><wfw:comment>http://www.cnitblog.com/jakiegu/comments/52645.html</wfw:comment><comments>http://www.cnitblog.com/jakiegu/archive/2008/12/15/52645.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/jakiegu/comments/commentRss/52645.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jakiegu/services/trackbacks/52645.html</trackback:ping><description><![CDATA[这几天看LR的中文版帮助，有一个地方总搞不明白。就是参数化file选项中sequentail+once选项的参数方式，中文版帮助如图<br><img height=384 alt="" src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/LR1.jpg" width=626 border=0><br>英文版帮助如下<br><img height=560 alt="" src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/LR12.jpg" width=845 border=0><br>业务说明：<br>以测试工程师的角色添加缺陷，并设置为3次迭代，设置并发为2个用户<br><img height=297 alt="" src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/31111.jpg" width=539 border=0><br><img height=72 alt="" src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/21111.jpg" width=1128 border=0><br>实际结果证明英文版还是对的，呵呵，广大测试朋友注意了<br><img height=322 alt="" src="http://www.cnitblog.com/images/cnitblog_com/jakiegu/result.jpg" width=721 border=0><br>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/52645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-12-15 16:48 <a href="http://www.cnitblog.com/jakiegu/archive/2008/12/15/52645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Git版本管理工具中文教程连载4</title><link>http://www.cnitblog.com/jakiegu/archive/2008/09/22/49377.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Mon, 22 Sep 2008 11:41:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/09/22/49377.html</guid><wfw:comment>http://www.cnitblog.com/jakiegu/comments/49377.html</wfw:comment><comments>http://www.cnitblog.com/jakiegu/archive/2008/09/22/49377.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/jakiegu/comments/commentRss/49377.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jakiegu/services/trackbacks/49377.html</trackback:ping><description><![CDATA[&nbsp;<strong><span>提取版本库中的数据</span></strong><strong></strong>
<p align=left><span>这是个很有用的小技巧，如果你对你现在的工作目录下的东西已经不耐烦了，随时可以取出你提交过的东西覆盖掉当前的文件，譬如：</span><span> </span></p>
<p align=left><span>$ git-checkout -f foo.c</span></p>
<div>
<p align=left><strong><span>标定版本</span></strong><strong></strong></p>
</div>
<p align=left><span>在</span><span> git </span><span>中，有两种类型的标签，</span><span>&#8220;</span><span>轻标签</span><span>&#8221;</span><span>和</span><span>&#8220;</span><span>署名标签</span><span>&#8221;</span><span>。</span><span> </span></p>
<p align=left><span>技术上说，一个</span><span>&#8220;</span><span>轻标签</span><span>&#8221;</span><span>和一个分支没有任何区别，只不过我们将它放在了</span><span> </span><span>.git/refs/tags/</span><span> </span><span>目录，而不是</span><span> </span><span>heads</span><span> </span><span>目录。因此，打一个</span><span>&#8220;</span><span>轻标签</span><span>&#8221;</span><span>再简单不过了。</span><span> </span></p>
<p align=left><span>$ git-tag my-first-tag</span></p>
<p align=left><span>如果你打算针对某个</span><span>commit ID</span><span>来打标签，虽然该命令可以通过</span><span>gitk</span><span>里的右键菜单来实现，但是该命令对实际应用是很有帮助的。</span><span> </span></p>
<p align=left><span>$ git-tag mytag f0af<st1:chmetcnv UnitName="F" SourceValue="6283824688" HasSpace="False" Negative="False" NumberType="1" TCSC="0" w:st="on">6283824688f</st1:chmetcnv>9d23426031734657661b54388</span></p>
<p align=left><span>&#8220;</span><span>署名标签</span><span>&#8221;</span><span>是一个真正的</span><span> git </span><span>对象，它不但包含指向你想标记的状态的指针，还有一个标记名和信息，可选的</span><span> PGP </span><span>签名。你可以通过</span><span> </span><span>-a</span><span> </span><span>或者是</span><span> </span><span>-s</span><span> </span><span>选项来创建</span><span>&#8220;</span><span>署名标签</span><span>&#8221;</span><span>。</span><span> </span></p>
<p align=left><span>$ git-tag -s &lt;tag-name&gt;</span></p>
<div>
<p align=left><strong><span>合并外部工作</span></strong><strong></strong></p>
</div>
<p align=left><span>通常的情况下，合并其他的人的工作的情况会比合并自己的分支的情况要多，这在</span><span> git </span><span>中是非常容易的事情，和你运行</span><span> </span><span>git-merge</span><span> </span><span>命令没有什么区别。事实上，远程合并的无非就是</span><span>&#8220;</span><span>抓取（</span><span>fetch</span><span>）一个远程的版本库中的工作到一个临时的标签中</span><span>&#8221;</span><span>，然后再使用</span><span> </span><span>git-merge</span><span> </span><span>命令。</span><span> </span></p>
<p align=left><span>可以通过下面的命令来抓取远程版本库</span><span>: </span></p>
<p align=left><span>$ git-fetch &lt;remote-repository&gt;</span></p>
<p align=left><span>根据不同的远程版本库所使用的通讯协议的路径来替代上面的</span><span> </span><span>remoted-repository</span><span> </span><span>就可以了。</span><span> </span></p>
<p align=left><em><span>Rsync </span></em></p>
<p align=left><span>rsync://remote.machine/patch/to/repo.git/</span><span> </span></p>
<p align=left><em><span>SSH </span></em></p>
<p align=left><span>remote.machine:/path/to/repo.git</span><span><br>or<br></span><span>ssh://remote.machine/patch/to/repo.git/</span><span> </span></p>
<p align=left><span>这是可以上传和下载的双向传输协议，当然，你要有通过</span><span> </span><span>ssh</span><span> </span><span>协议登录远程机器的权限。它可以找出两端的机器提交过的对象集之中相互缺少了那些对象，从而得到需要传输的最小对象集。这是最高效地交换两个版本库之间的对象的方式（在</span><span> git </span><span>兼容的所有传输协议当中）。</span><span> </span></p>
<p align=left><span>下面是个取得</span><span> SSH </span><span>远程版本库的命令例子：</span><span> </span></p>
<p align=left><span>$ git-fetch robin@192.168.1.168:/path/to/gittutorcn.git&nbsp;</span><strong><span>(1)</span></strong></p>
<p align=left>&nbsp;</p>
<p align=left><strong><span>(1)</span></strong><span> </span><span>这里<span> robin </span>是登录的用户名，<span>192.168.1.168 </span>是保存着主版本库的机器的<span> IP </span>地址。</span></p>
<p align=left><em><span>Local directory </span></em></p>
<p align=left><span>/path/to/repo.git/</span><span> </span></p>
<p align=left><span>本地目录的情况和</span><span> SSH </span><span>情况是一样的。</span><span> </span></p>
<p align=left><em><span>git Native </span></em></p>
<p align=left><span>git://remote.machine/path/to/repo.git/</span><span> </span></p>
<p align=left><span>git </span><span>自然协议是设计来用于匿名下载的，它的工作方式类似于</span><span> SSH </span><span>协议的交换方式。</span><span> </span></p>
<p align=left><em><span>HTTP(S) </span></em></p>
<p align=left><span>http://remote.machine/path/to/repo.git/</span></p>
<p align=left><span>到这里可能有些朋友已经想到，实际上，我们可以通过</span><span> Rsync, SSH </span><span>之类的双向传输方式来建立类似</span><span> CVS</span><span>，</span><span>SVN </span><span>这样的中心版本库模式的开发组织形式。</span><span> </span></p>
<div>
<p align=left><strong><span>通过电子邮件交换工作</span></strong><strong></strong></p>
</div>
<p align=left><span>读过上一节之后，有的朋友可能要问，如果版本库是通过单向的下载协议发布的，如</span><span> HTTP</span><span>，我们就无法将工作上传到公共的版本库中。别人也不能访问我的机器来抓取我的工作，那怎么办呢？</span><span> </span></p>
<p align=left><span>不必担心，我们还有</span><span> email </span><span>！别忘了</span><span> git </span><span>本来就是为了管理</span><span> Linux </span><span>的内核开发而设计的。所以，它非常适合像</span><span> Linux Kernel </span><span>这样的开发组织形式高度分散，严重依赖</span><span> email </span><span>来进行交流的项目。</span><span> </span></p>
<p align=left><span>下面模拟你参加到《</span><span>Git </span><span>中文教程》的编写工作中来，看看我们可以怎么通过</span><span> email </span><span>进行工作交流。你可以通过下面的命令下载这个项目的版本库。</span><span> </span></p>
<p align=left><span>$ git-clone http://www.bitsun.com/git/gittutorcn.git</span></p>
<p align=left><span>之后，你会在当前目录下得到一个叫</span><span> </span><span>gittutorcn</span><span> </span><span>的目录，这就是你的项目的工作目录了。默认地，它会有两个分支：</span><span> </span><span>master</span><span> </span><span>和</span><span> </span><span>origin</span><span>，你可以直接在</span><span> </span><span>master</span><span> </span><span>下展开工作，也可以创建你自己的工作分支，但是千万不要修改</span><span> </span><span>origin</span><span> </span><span>分支，切记！因为它是公共版本库的镜像，如果你修改了它，那么就不能生成正确的对公共版本库的</span><span> </span><span>patch</span><span> </span><span>文件了。</span><span> </span></p>
<table cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top>
            <p align=left><strong><u><span>Note</span></u></strong></p>
            </td>
            <td>
            <p align=left><span>如果你的确修改过 <span>origin</span><span> </span>分支的内容，那么在生成 <span>patch</span><span> </span>文件之前，请用 <span>git-reset --hard</span><span> </span>命令将它逆转到最原始的，没经过任何修改的状态。<span> </span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p align=left><span>你可以直接在</span><span> </span><span>master</span><span> </span><span>下开展工作，也可以创建你自己的工作分支。当你对项目做了一定的工作，并提交到库中。我们用</span><span> </span><span>git-show-branch</span><span> </span><span>命令先看下库的状态。</span><span> </span></p>
<p align=left><span>* [master] your buddy's contribution</span></p>
<p align=left><span>&nbsp;! [origin] degining of git-format-patch example</span></p>
<p align=left><span>--</span></p>
<p align=left><span>*&nbsp;[master] your buddy's contribution</span></p>
<p align=left><span>*+ [origin] degining of git-format-patch example</span></p>
<p align=left><span>上面就假设你已经提交了一个叫</span><span> "your buddy's contribution" </span><span>的工作。现在我们来看看怎么通过</span><span> email </span><span>来交流工作了。</span><span> </span></p>
<p align=left><span>$ git-fetch origin<span>&nbsp;&nbsp;&nbsp; </span><strong>(1)</strong></span></p>
<p align=left><span>$ git-rebase origin<span>&nbsp;&nbsp;&nbsp; </span><strong>(2)</strong></span></p>
<p align=left><span>$ git-format-patch origin<span>&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>(3)</strong></span></p>
<p align=left>&nbsp;</p>
<p align=left><strong><span>(1)</span></strong><span>更新<span> origin </span>分支，防止<span> origin </span>分支不是最新的公共版本，产生错误的补丁文件；</span></p>
<p align=left><strong><span>(2)</span></strong><span>将你在<span> master </span>上提交的工作迁移到新的源版本库的状态的基础上；</span></p>
<p align=left><strong><span>(3)</span></strong><span>生成补丁文件；</span></p>
<p align=left><span>上面的几个命令，会在当前目录下生成一个大概名为</span><span> </span><span>0001-your-buddy-s-contribution.txt</span><span> </span><span>补丁文件</span><span>, </span><span>建议你用文本工具查看一下这个文件的具体形式，然后将这个文件以附件的形式发送到项目维护者的邮箱：</span><span> <span><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#118;&#111;&#114;&#116;&#117;&#110;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">vortune@gmail.com</a> </span></span></p>
<p align=left><span>当项目的维护者收到你的邮件后，只需要用</span><span> </span><span>git-am</span><span> </span><span>命令，就可以将你的工作合并到项目中来。</span><span> </span></p>
<p align=left><span>$ git-checkout -b buddy-incomming</span></p>
<p align=left><span>$ git-am /path/to/0001-your-buddy-s-contribution.txt</span></p>
<div>
<p align=left><strong><span>用</span></strong><strong><span> Git </span></strong><strong><span>协同工作</span></strong><strong></strong></p>
</div>
<p align=left><span>假设</span><span> Alice </span><span>在一部机器上自己的个人目录中创建了一个项目</span><span> /home/alice/project, Bob </span><span>想在同一部机器自己的个人目录中为这个项目做点什么。</span><span> </span></p>
<p align=left><span>Bob </span><span>首先这样开始：</span></p>
<p align=left><span>$ git-clone /home/alice/project myrepo</span></p>
<p align=left><span>这样就创建了一个保存着</span><span> Alice </span><span>的版本库的镜像的新目录</span><span> "myrepo"</span><span>。这个镜像保存着原始项目的起点和它的发展历程。</span><span> </span></p>
<p align=left><span>接着</span><span> Bob </span><span>对项目做了些更改并提交了这些更改：</span></p>
<p align=left><span>(</span><span>编辑一些文件<span>)</span></span></p>
<p align=left>&nbsp;</p>
<p align=left><span>$ git-commit -a </span></p>
<p align=left>&nbsp;</p>
<p align=left><span>(</span><span>如果需要的话再重复这个步骤<span>)</span></span></p>
<p align=left><span>当他搞定之后，他告诉</span><span> Alice </span><span>将他的东西从</span><span> /home/bob/myrepo </span><span>中引入，她只需要这样：</span><span> </span></p>
<p align=left><span>$ cd /home/alice/project</span></p>
<p align=left><span>$ git pull /home/bob/myrepo</span></p>
<p align=left><span>这样就将</span><span> Bob </span><span>的版本库中的</span><span> "master" </span><span>分支的变化引入了。</span><span> Alice </span><span>也可以通过在</span><span> pull </span><span>命令的后面加入参数的方式来引入其他的分支。</span><span> </span></p>
<p align=left><span>在导入了</span><span> Bob </span><span>的工作之后，用</span><span> "git-whatchanged" </span><span>命令可以查看有什么信的提交对象。如果这段时间里以来，</span><span>Alice </span><span>也对项目做过自己的修改，当</span><span> Bob </span><span>的修改被合并进来的时候，那么她需要手动修复所有的合并冲突。</span><span> </span></p>
<p align=left><span>谨慎的</span><span> Alice </span><span>在导入</span><span> Bob </span><span>的工作之前，希望先检查一下。那么她可以先将</span><span> Bob </span><span>的工作导入到一个新创建的临时分支中，以方便研究</span><span> Bob </span><span>的工作：</span><span> </span></p>
<p align=left><span>$ git fetch /home/bob/myrepo master:bob-incoming</span></p>
<p align=left><span>这个命令将</span><span> Bob </span><span>的</span><span> master </span><span>分支的导入到名为</span><span> bob-incoming </span><span>的分支中（不同于</span><span> git-pull </span><span>命令，</span><span>git-fetch </span><span>命令只是取得</span><span> Bob </span><span>的开发工作的拷贝，而不是合并经来）。接着：</span><span> </span></p>
<p align=left><span>$ git whatchanged -p master..bob-incoming</span></p>
<p align=left><span>这会列出</span><span> Bob </span><span>自取得</span><span> Alice </span><span>的</span><span> master </span><span>分支之后开始工作的所有变化。检查过这些工作，并做过必须的调整之后，</span><span> Alice </span><span>就可以将变化导入到她的</span><span> master </span><span>分支中：</span><span> </span></p>
<p align=left><span>$ git-checkout master</span></p>
<p align=left><span>$git-pull . bob-incoming</span></p>
<p align=left><span>最后的命令就是将</span><span> "bob-incoming" </span><span>分支的东西导入到</span><span> Alice </span><span>自己的版本库中的，稍后，</span><span>Bob </span><span>就可以通过下面的命令同步</span><span> Alice </span><span>的最新变化。</span><span> </span></p>
<p align=left><span>$ git-pull</span></p>
<p align=left><span>注意不需为这个命令加入</span><span> Alice </span><span>的版本库的路径，因为当</span><span> Bob </span><span>克隆</span><span> Alice </span><span>的版本库的时候，</span><span> git </span><span>已经将这个路径保存到</span><span> .git/remote/origin </span><span>文件中，它将会是所以的导入操作的默认路径。</span><span> </span></p>
<p align=left><span>Bob </span><span>可能已经注意到他并没有在他的版本库中创建过分支（但是分支已经存在了）：</span><span> </span></p>
<p align=left><span>$ git branch</span></p>
<p align=left><span>* master</span></p>
<p align=left><span>&nbsp;origin</span></p>
<p align=left><span>"origin" </span><span>分支，它是运行</span><span> "git-clone" </span><span>的时候自动创建的，他是</span><span> Alice </span><span>的</span><span> master </span><span>分支的原始镜像，</span><span> Bob </span><span>应该永远不要向这个分支提交任何东西。</span><span> </span></p>
<p align=left><span>如果</span><span> Bob </span><span>以后决定在另外一部主机上开展工作，那么他仍然需要通过</span><span> SSH </span><span>协议从新克隆和导入（</span><span> Alice </span><span>的版本库）：</span><span> </span></p>
<p align=left><span>$ git-clone alice.org:/home/alice/project/ myrepo</span></p>
<p align=left><span>我们可以使用</span><span> git </span><span>自然协议，或者是</span><span> rsync, http </span><span>等协议的任何一种，详情请参考</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/git-pull.html" target=_blank>git-pull</a></span></span><span>。</span><span> </span></p>
<span>Git </span><span>同样可以建立类似</span><span> CVS </span><span>那样的开发模式，也就是所有开发者都向中心版本库提交工作的方式，详情参考</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/git-push.html" target=_blank>git_push</a> </span></span><span>和</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/cvs-migration.html" target=_blank>git for CVS users</a> </span></span><span>。</span>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/49377.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-09-22 19:41 <a href="http://www.cnitblog.com/jakiegu/archive/2008/09/22/49377.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git版本管理工具中文教程连载3 </title><link>http://www.cnitblog.com/jakiegu/archive/2008/09/09/48874.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Tue, 09 Sep 2008 03:44:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/09/09/48874.html</guid><wfw:comment>http://www.cnitblog.com/jakiegu/comments/48874.html</wfw:comment><comments>http://www.cnitblog.com/jakiegu/archive/2008/09/09/48874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/jakiegu/comments/commentRss/48874.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jakiegu/services/trackbacks/48874.html</trackback:ping><description><![CDATA[&nbsp;
<p align=left><span>1d2fa05b13b63e<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="39" UnitName="F">39f</st1:chmetcnv>621d8ee911817df0662d9b7 Some fun</span></p>
<p align=left><span>d2659fcf690ec<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="693" UnitName="C">693c</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="4" UnitName="C">04c</st1:chmetcnv>82b03202fc5530d50960 some work</span></p>
<p align=left><span>found 1 common ancestor(s):</span></p>
<p align=left><span>3ecebc0cb<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="4894" UnitName="a">4894a</st1:chmetcnv>33208dfa<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="7" UnitName="C">7c</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="7" UnitName="C">7c</st1:chmetcnv>6fc8b<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="5" UnitName="F">5f</st1:chmetcnv>9da0eda a new day for git</span></p>
<p align=left><span>Auto-merging hello</span></p>
<p align=left><span>CONFLICT (content): Merge conflict in hello</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>Automatic merge failed; fix up by hand</span></p>
<p align=left><span>git </span><span>的提示指出，在合并作用于文件</span><span> hello </span><span>的</span><span> 'Some fun' </span><span>和</span><span> 'some work' </span><span>这两个对象时有冲突，具体通俗点说，就是在</span><span> </span><span>master</span><span>, </span><span>robin</span><span> </span><span>这两个分支中的</span><span> hello </span><span>文件的某些相同的行中的内容不一样。我们需要手动解决这些冲突，现在先让我们看看现在的</span><span> hello </span><span>文件中的内容。</span><span> </span></p>
<p align=left><span>$ cat hello</span></p>
<p align=left><span>此时的</span><span> hello </span><span>文件应是这样的，用过其他的版本控制系统的朋友应该很容易看出这个典型的冲突表示格式：</span><span> </span></p>
<p align=left><span>Hello World</span></p>
<p align=left><span>It's a new day for git</span></p>
<p align=left><span>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD/hello</span></p>
<p align=left><span>Play, play, play</span></p>
<p align=left><span>=======</span></p>
<p align=left><span>Work, work, work</span></p>
<p align=left><span>&gt;&gt;&gt;&gt;&gt;&gt;&gt; d2659fcf690ec<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="693" UnitName="C">693c</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="4" UnitName="C">04c</st1:chmetcnv>82b03202fc5530d50960/hello</span></p>
<p align=left><span>我们用编辑器将</span><span> hello </span><span>文件改为：</span><span> </span></p>
<p align=left><span>Hello World</span></p>
<p align=left><span>It's a new day for git</span></p>
<p align=left><span>Play, play, play</span></p>
<p align=left><span>Work, work, work</span></p>
<p align=left><span>现在可以将手动解决了冲突的文件提交了。</span><span> </span></p>
<p align=left><span>$ git-commit -i hello</span></p>
<p align=left><span>以上是典型的两路合并（</span><span>2-way merge</span><span>）算法，绝大多数情况下已经够用。但是还有更复杂的三路合并和多内容树合并的情况。详情可参看：</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html" target=_blank>git-read-tree</a></span></span><span>，</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html" target=_blank>git-merge</a> </span></span><span>等文档。</span><span> </span></p>
<div>
<p align=left><strong><span>逆转与恢复：</span></strong><strong><span>git-reset</span></strong></p>
</div>
<p align=left><span>项目跟踪工具的一个重要任务之一，就是使我们能够随时逆转（</span><span>Undo</span><span>）和恢复（</span><span>Redo</span><span>）某一阶段的工作。</span><span> </span></p>
<p align=left><span><a href="http://www.kernel.org/pub/software/scm/git/docs/git-reset.html" target=_blank>git-reset </a></span><span>命令就是为这样的任务准备的。它将当前的工作分支的</span><span> </span><em><span>头</span></em><span> </span><span>定位到以前提交的任何版本中，它有三个重置的算法选项。</span><span> </span></p>
<p align=left><strong><span>命令形式：</span></strong><strong></strong></p>
<p align=left><strong><span>git-reset [--mixed | --soft | --hard] [&lt;commit-ish&gt;] </span></strong></p>
<p align=left><strong><span>命令的选项：</span></strong><strong></strong></p>
<p align=left><em><span>--mixed </span></em></p>
<p align=left><span>仅是重置索引的位置，而不改变你的工作树中的任何东西（即，文件中的所有变化都会被保留，也不标记他们为待提交状态），并且提示什么内容还没有被更新了。这个是默认的选项。</span><span> </span></p>
<p align=left><em><span>--soft </span></em></p>
<p align=left><span>既不触动索引的位置，也不改变工作树中的任何内容，我们只是要求这些内容成为一份好的内容（之后才成为真正的提交内容）。这个选项使你可以将已经提交的东西重新逆转至</span><span>&#8220;</span><span>已更新但未提交（</span><span>Updated but not Check in</span><span>）</span><span>&#8221;</span><span>的状态。就像已经执行过</span><span> </span><span>git-update-index</span><span> </span><span>命令，但是还没有执行</span><span> </span><span>git-commit</span><span> </span><span>命令一样。</span><span> </span></p>
<p align=left><em><span>--hard </span></em></p>
<p align=left><span>将工作树中的内容和头索引都切换至指定的版本位置中，也就是说自</span><span> &lt;commit-ish&gt; </span><span>之后的所有的跟踪内容和工作树中的内容都会全部丢失。因此，这个选项要慎用，除非你已经非常确定你的确不想再看到那些东西了。</span><span> </span></p>
<p align=left><strong><span>一个重要技巧－－逆转提交与恢复</span></strong><strong></strong></p>
<p align=left><span>可能有人会问，</span><span>--soft </span><span>选项既不重置头索引的位置，也不改变工作树中的内容，那么它有什么用呢？现在我们介绍一个</span><span> --soft </span><span>选项的使用技巧。下面我们用例子来说明：</span><span> </span></p>
<p align=left><span>$ git-checkout master</span></p>
<p align=left><span>$ git-checkout -b softreset</span></p>
<p align=left><span>$ git-show-branch</span></p>
<p align=left><span>这里我们创建了一个</span><span> </span><span>master</span><span> </span><span>的拷贝分支</span><span> </span><span>softreset</span><span>，现在我们可以看到两个分支是在同一起跑线上的。</span><span> </span></p>
<p align=left><span>! [master] Merge branch 'robin'</span></p>
<p align=left><span>&nbsp;! [robin] some work</span></p>
<p align=left><span>&nbsp;* [softreset] Merge branch 'robin'</span></p>
<p align=left><span>---</span></p>
<p align=left><span>- - [master] Merge branch 'robin'</span></p>
<p align=left><span>+ * [master^] Some fun</span></p>
<p align=left><span>++* [robin] some work</span></p>
<p align=left><span>我们为</span><span> </span><span>文件增加一些内容并提交。</span><span> </span></p>
<p align=left><span>$ echo "Botch, botch, botch" &gt;&gt; hello</span></p>
<p align=left><span>$ git-commit -a -m "some botch"</span></p>
<p align=left><span>$ git-show-branch</span></p>
<p align=left><span>我们可以看到此时</span><span> </span><span>softreset</span><span> </span><span>比</span><span> </span><span>master</span><span> </span><span>推进了一个版本</span><span> "some botch" </span><span>。</span><span> </span></p>
<p align=left><span>! [master] Merge branch 'robin'</span></p>
<p align=left><span>&nbsp;! [robin] some work</span></p>
<p align=left><span>&nbsp;* [softreset] some botch</span></p>
<p align=left><span>---</span></p>
<p align=left><span>&nbsp;* [softreset] some botch</span></p>
<p align=left><span>- - [master] Merge branch 'robin'</span></p>
<p align=left><span>+ * [master^] Some fun</span></p>
<p align=left><span>++* [robin] some work</span></p>
<p align=left><span>现在让我们来考虑这样的一种情况，假如我们现在对刚刚提交的内容不满意，那么我们再编辑项目的内容，再提交的话，那么</span><span> "some botch" </span><span>的内容就会留在版本库中了。我们当然不希望将有明显问题的内容留在版本库中，这个时候</span><span> </span><span>--soft</span><span> </span><span>选项就很有用了。为了深入了解</span><span> </span><span>--soft</span><span> </span><span>的机制，我们看看现在</span><span> softreset </span><span>分支的头和</span><span> ORIG_HEAD </span><span>保存的索引。</span><span> </span></p>
<p align=left><span>$ cat .git/refs/heads/softreset .git/ORIG_HEAD</span></p>
<p align=left><span>结果如下：</span><span> </span></p>
<p align=left><span>5e7cf906233e052bdca<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="8" UnitName="C">8c</st1:chmetcnv>598cad2cb<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="5478" UnitName="F">5478f</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="9540" UnitName="a">9540a</st1:chmetcnv></span></p>
<p align=left><span>7bbd1370e<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="2" UnitName="C">2c</st1:chmetcnv>667d955b<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="6" UnitName="F">6f</st1:chmetcnv>6652bf8274efdc1fbd3</span></p>
<p align=left><span>现在用</span><span> </span><span>--soft</span><span> </span><span>选项逆转刚才提交的内容：</span><span> </span></p>
<p align=left><span>git-reset --soft HEAD^</span></p>
<p align=left><span>现在让我们再看看</span><span> .git/ORIG_HEAD </span><span>的中保存了什么？</span><span> </span></p>
<p align=left><span>$ cat .git/ORIG_HEAD</span></p>
<p align=left><span>结果如下：</span><span> </span></p>
<p align=left><span>5e7cf906233e052bdca<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="8" UnitName="C">8c</st1:chmetcnv>598cad2cb<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="5478" UnitName="F">5478f</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="9540" UnitName="a">9540a</st1:chmetcnv></span></p>
<p align=left><span>看！现在的</span><span> .git/ORIG_HEAD </span><span>等于逆转前的</span><span> .git/refs/heads/softreset </span><span>。也就是说，</span><span>git-reset --soft HEAD^</span><span> </span><span>命令逆转了刚才提交的版本进度，但是它将那次提交的对象的索引拷贝到了</span><span> .git/ORIG_HEAD </span><span>中。</span><span> </span></p>
<p align=left><span>我们再编辑</span><span> hello </span><span>文件成为下面的内容：</span><span> </span></p>
<p align=left><span>Hello World</span></p>
<p align=left><span>It's a new day for git</span></p>
<p align=left><span>Play, play, play</span></p>
<p align=left><span>Work, work, work</span></p>
<p align=left><span>Nice, nice, nice</span></p>
<p align=left><span>我们甚至可以比较一下现在的工作树中的内容和被取消了的那次提交的内容有什么差异：</span><span> </span></p>
<p align=left><span>$ git-diff ORIG_HEAD</span></p>
<p align=left><span>结果如下：</span><span> </span></p>
<p align=left><span>diff --git a/hello b/hello</span></p>
<p align=left><span>index f978676..dd<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="2" UnitName="C">02c</st1:chmetcnv>32 100644</span></p>
<p align=left><span>--- a/hello</span></p>
<p align=left><span>+++ b/hello</span></p>
<p align=left><span>@@ -2,4 +2,4 @@ Hello World</span></p>
<p align=left><span>&nbsp;It's a new day for git</span></p>
<p align=left><span>&nbsp;Play, play, play</span></p>
<p align=left><span>&nbsp;Work, work, work</span></p>
<p align=left><span>-Botch, botch, botch</span></p>
<p align=left><span>+Nice, nice, nice</span></p>
<p align=left><span>接着，我们可以恢复刚才被取消了的那次提交了。</span><span> </span></p>
<p align=left><span>$ git-commit -a -c ORIG_HEAD</span></p>
<p align=left><span>注意，这个命令会打开默认的文本编辑器以编辑原来提交的版本日志信息，我们改为</span><span> "nice work" </span><span>。大家可以自行用</span><span> </span><span>git-show-branch</span><span> </span><span>命令来查看一下现在的分支状态。并且我们还可以不断地重复上述的步骤，一直修改到你对这个版本进度满意为止。</span><span> </span></p>
<p align=left><span>git-reset </span><span>命令还有很多的用途和技巧，请参考</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/git-reset.html" target=_blank>git-reset </a></span></span><span>，以及</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/everyday.html" target=_blank>Everyday GIT with 20 commands or So </a></span></span><span>。</span><span> </span></p>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/48874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-09-09 11:44 <a href="http://www.cnitblog.com/jakiegu/archive/2008/09/09/48874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git版本管理工具中文教程连载2</title><link>http://www.cnitblog.com/jakiegu/archive/2008/09/09/48873.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Tue, 09 Sep 2008 03:42:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/09/09/48873.html</guid><wfw:comment>http://www.cnitblog.com/jakiegu/comments/48873.html</wfw:comment><comments>http://www.cnitblog.com/jakiegu/archive/2008/09/09/48873.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/jakiegu/comments/commentRss/48873.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jakiegu/services/trackbacks/48873.html</trackback:ping><description><![CDATA[<span>此时，我们可以再次使用组合命令</span><span> </span><span>git-update-index</span><span> </span><span>和</span><span> </span><span>git-commit</span><span> </span><span>将我们的工作提交到版本库中。</span><span> </span>
<p align=left><span>$ git-update-index hello</span></p>
<p align=left><span>$ git-commit -m "new day for git"</span></p>
<p align=left><span>实际上，如果要提交的文件都是已经纳入</span><span> git </span><span>版本库的文件，那么不必为这些文件都应用</span><span> </span><span>git-update-index</span><span> </span><span>命令之后再进行提交，下面的命令更简捷并且和上面的命令是等价的。</span><span> </span></p>
<p align=left><span>$ git-commit -a -m "new day for git"</span></p>
<div>
<p align=left><strong><span>管理分支：</span></strong><strong><span>git-branch</span></strong></p>
</div>
<p align=left><span>直至现在为止，我们的项目版本库一直都是只有一个分支</span><span> </span><span>master</span><span>。在</span><span> git </span><span>版本库中创建分支的成本几乎为零，所以，不必吝啬多创建几个分支。下面列举一些常见的分支策略，仅供大家参考：</span><span> </span></p>
<p align=left><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>创建一个属于自己的个人工作分支，以避免对主分支</span><span> </span><span>master</span><span> </span><span>造成太多的干扰，也方便与他人交流协作。</span><span> </span></p>
<p align=left><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>当进行高风险的工作时，创建一个试验性的分支，扔掉一个烂摊子总比收拾一个烂摊子好得多。</span><span> </span></p>
<p align=left><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>合并别人的工作的时候，最好是创建一个临时的分支，关于如何用临时分支合并别人的工作的技巧，将会在后面讲述。</span><span> </span></p>
<p align=left><strong><span>创建分支</span></strong><strong></strong></p>
<p align=left><span>下面的命令将创建我自己的工作分支，名叫</span><span> robin</span><span>，并且将以后的工作转移到这个分支上开展。</span><span> </span></p>
<p align=left><span>$ git-branch robin</span></p>
<p align=left><span>$ git-checkout robin</span></p>
<p align=left><strong><span>删除分支</span></strong><strong></strong></p>
<p align=left><span>要删除版本库中的某个分支，使用</span><span> </span><span>git-branch -D</span><span> </span><span>命令就可以了，例如：</span><span> </span></p>
<p align=left><span>$ git-branch -D branch-name</span></p>
<p align=left><strong><span>查看分支</span></strong><strong></strong></p>
<p align=left><span>运行下面的命令可以得到你当前工作目录的分支列表：</span><span> </span></p>
<p align=left><span>$ git-branch</span></p>
<p align=left><span>如果你忘记了你现在工作在哪个分支上，运行下面的命令可以告诉你：</span><span> </span></p>
<p align=left><span>$ cat .git/HEAD </span></p>
<div>
<p align=left><strong><span>查看项目的发展变化和比较差异</span></strong><strong></strong></p>
</div>
<p align=left><span>这一节介绍几个查看项目的版本库的发展变化以及比较差异的很有用的命令： </span></p>
<p align=left><strong><span>git-show-branch</span></strong></p>
<p align=left><strong><span>git-diff</span></strong></p>
<p align=left><strong><span>git-whatchanged</span></strong></p>
<p align=left>&nbsp;</p>
<p align=left><span>我们现在为 <span>robin</span><span>, <span>master</span> </span>两个分支都增加一些内容。 </span></p>
<p align=left><span>$ git-checkout robin</span></p>
<p align=left><span>$ echo "Work, work, workd" &gt;&gt; hello</span></p>
<p align=left><span>$ git-commit -m "Some workd" -i hello</span></p>
<p align=left><span>$ git-checkout master</span></p>
<p align=left><span>$ echo "Play, play, play" &gt;&gt; hello</span></p>
<p align=left><span>$ echo "Lots of fun" &gt;&gt; example</span></p>
<p align=left><span>$ git-commit -m "Some fun" -i hello example</span></p>
<p align=left><span>git-show-branch</span><span> </span><span>命令可以使我们看到版本库中每个分支的世系发展状态，并且可以看到每次提交的内容是否已进入每个分支。 </span></p>
<p align=left><span>$ git-show-branch </span></p>
<p align=left><span>这个命令让我们看到版本库的发展记录。 </span></p>
<p align=left><span>* [master] Some fun</span></p>
<p align=left><span>&nbsp;! [robin] some work</span></p>
<p align=left><span>--</span></p>
<p align=left><span>*&nbsp;[master] Some fun</span></p>
<p align=left><span>&nbsp;+ [robin] some work</span></p>
<p align=left><span>*+ [master^] a new day for git</span></p>
<p align=left><span>譬如我们要查看世系标号为 <span>master^</span><span> </span>和 <span>robin</span><span> </span>的版本的差异情况，我们可以使用这样的命令： </span></p>
<p align=left><span>$ git-diff master^ robin</span></p>
<p align=left><span>我们可以看到这两个版本的差异： </span></p>
<p align=left><span>diff --git a/hello b/hello</span></p>
<p align=left><span>index <st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="263414" UnitName="F">263414f</st1:chmetcnv>..cc<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="44" UnitName="C">44c</st1:chmetcnv>73 100644</span></p>
<p align=left><span>--- a/hello</span></p>
<p align=left><span>+++ b/hello</span></p>
<p align=left><span>@@ -1,2 +1,3 @@</span></p>
<p align=left><span>&nbsp;Hello World</span></p>
<p align=left><span>&nbsp;It's a new day for git</span></p>
<p align=left><span>+Work, work, work</span></p>
<table cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top>
            <p align=left><strong><u><span>Note</span></u></strong></p>
            </td>
            <td>
            <p align=left><span>关于<span> GIT </span>版本世系编号的定义，请参看 <span><a href="http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html" target=_blank>git-rev-parse </a></span>。 </span></p>
            </td>
        </tr>
    </tbody>
</table>
<p align=left><span>我们现在再用 <span>git-whatchanged</span><span> </span>命令来看看 <span>master</span><span> </span>分支是怎么发展的。 </span></p>
<p align=left><span>$ git-checkout master</span></p>
<p align=left><span>$ git-whatchanged </span></p>
<p align=left><span>diff-tree 1d2fa05... (from 3ecebc0...)</span></p>
<p align=left><span>Author: Vortune.Robin </span></p>
<p align=left><span>Date:<span>&nbsp;&nbsp; </span>Tue Mar 21 02:24:31 2006 +0800</span></p>
<p align=left>&nbsp;</p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span>Some fun</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>:100644 <st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="True" SourceValue="100644" UnitName="F">100644 f</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="24" UnitName="C">24c</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="74" UnitName="a">74a</st1:chmetcnv>... <st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="7" UnitName="F">7f</st1:chmetcnv>8b141... M&nbsp;example</span></p>
<p align=left><span>:100644 100644 <st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="263414" UnitName="F">263414f</st1:chmetcnv>... 06fa<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="6" UnitName="a">6a</st1:chmetcnv>2... M&nbsp;hello</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>diff-tree 3ecebc0... (from <st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="895" UnitName="F">895f</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="9" UnitName="a">09a</st1:chmetcnv>...)</span></p>
<p align=left><span>Author: Vortune.Robin </span></p>
<p align=left><span>Date:<span>&nbsp;&nbsp; </span>Tue Mar 21 02:17:23 2006 +0800</span></p>
<p align=left>&nbsp;</p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span>a new day for git</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>:100644 100644 557db03... <st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="263414" UnitName="F">263414f</st1:chmetcnv>... M&nbsp;hello</span></p>
<p align=left><span>从上面的内容中我们可以看到，在 <span>robin</span><span> </span>分支中的日志为<span> "Some work" </span>的内容<span>, </span>并没有在 <span>master</span><span> </span>分支中出现。 </span></p>
<div>
<p align=left><strong><span>合并两个分支：</span></strong><strong><span>git-merge</span></strong></p>
</div>
<p align=left><span>既然我们为项目创建了不同的分支，那么我们就要经常地将自己或者是别人在一个分支上的工作合并到其他的分支上去。现在我们看看怎么将</span><span> </span><span>robin</span><span> </span><span>分支上的工作合并到</span><span> </span><span>master</span><span> </span><span>分支中。现在转移我们当前的工作分支到</span><span> </span><span>master</span><span>，并且将</span><span> </span><span>robin</span><span> </span><span>分支上的工作合并进来。</span><span> </span></p>
<p align=left><span>$ git-checkout master</span></p>
<p align=left><span>$ git-merge "Merge work in robin" HEAD robin</span></p>
<p align=left><span>合并两个分支，还有一个更简便的方式，下面的命令和上面的命令是等价的。</span><span> </span></p>
<p align=left><span>$ git-checkout master</span></p>
<p align=left><span>$ git-pull . robin</span></p>
<p align=left><span>但是，此时</span><span> git </span><span>会出现合并冲突提示：</span><span> </span></p>
<p align=left><span>Trying really trivial in-index merge...</span></p>
<p align=left><span>fatal: Merge requires file-level merging</span></p>
<p align=left><span>Nope.</span></p>
<p align=left><span>Merging HEAD with d2659fcf690ec<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="693" UnitName="C">693c</st1:chmetcnv><st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="4" UnitName="C">04c</st1:chmetcnv>82b03202fc5530d50960</span></p>
<p align=left><span>Merging:</span></p>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/48873.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-09-09 11:42 <a href="http://www.cnitblog.com/jakiegu/archive/2008/09/09/48873.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git版本管理工具中文教程连载1</title><link>http://www.cnitblog.com/jakiegu/archive/2008/09/09/snooker.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Tue, 09 Sep 2008 03:40:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/09/09/snooker.html</guid><wfw:comment>http://www.cnitblog.com/jakiegu/comments/48872.html</wfw:comment><comments>http://www.cnitblog.com/jakiegu/archive/2008/09/09/snooker.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/jakiegu/comments/commentRss/48872.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jakiegu/services/trackbacks/48872.html</trackback:ping><description><![CDATA[&nbsp;<span>Git --- The stupid content tracker, </span><span>傻瓜内容跟踪器。</span><span>Linus </span><span>是这样给我们介绍</span><span> <span>Git </span></span><span>的。</span><span> </span>
<p align=left><span>Git </span><span>是用于</span><span> Linux </span><span>内核开发的版本控制工具。与常用的版本控制工具</span><span> CVS, Subversion </span><span>等不同，它采用了分布式版本库的方式，不必服务器端软件支持，使源代码的发布和交流极其方便。</span><span> Git </span><span>的速度很快，这对于诸如</span><span> Linux kernel </span><span>这样的大项目来说自然很重要。</span><span> Git </span><span>最为出色的是它的合并跟踪（</span><span>merge tracing</span><span>）能力。</span><span> </span></p>
<p align=left><span>实际上内核开发团队决定开始开发和使用</span><span> Git </span><span>来作为内核开发的版本控制系统的时候，世界开源社群的反对声音不少，最大的理由是</span><span> Git </span><span>太艰涩难懂，从</span><span> Git </span><span>的内部工作机制来说，的确是这样。但是随着开发的深入，</span><span>Git </span><span>的正常使用都由一些友好的脚本命令来执行，使</span><span> Git </span><span>变得非常好用，即使是用来管理我们自己的开发项目，</span><span>Git </span><span>都是一个友好，有力的工具。现在，越来越多的著名项目采用</span><span> Git </span><span>来管理项目开发，例如：</span><span>wine, U-boot </span><span>等，详情看</span><span> <span><a href="http://www.kernel.org/git" target=_blank>http://www.kernel.org/git</a> </span></span></p>
<p align=left><span>作为开源自由原教旨主义项目，</span><span>Git </span><span>没有对版本库的浏览和修改做任何的权限限制。它只适用于</span><span> Linux / Unix </span><span>平台，没有</span><span> Windows </span><span>版本，目前也没有这样的开发计划。</span><span> </span></p>
<p align=left><span>本文将以</span><span> Git </span><span>官方文档</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/tutorial.html" target=_blank>Tutorial</a></span></span><span>，</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/core-tutorial.html" target=_blank>core-tutorial</a> </span></span><span>和</span><span> <span><a href="http://www.kernel.org/pub/software/scm/git/docs/everyday.html" target=_blank>Everyday GIT</a> </span></span><span>作为蓝本翻译整理，但是暂时去掉了对</span><span> Git </span><span>内部工作机制的阐述，力求简明扼要，并加入了作者使用</span><span> Git </span><span>的过程中的一些心得体会，注意事项，以及更多的例子。建议你最好通过你所使用的</span><span> Unix / Linux </span><span>发行版的安装包来安装</span><span> Git, </span><span>你可以</span><span><a href="http://www.bitsun.com/documents/gittutorcn.htm"><span><span>在线浏览本文</span></span></a> </span><span>，也可以通过下面的命令来得到本文最新的版本库，并且通过后面的学习用</span><span> Git </span><span>作为工具参加到本文的创作中来。</span></p>
<p align=left><span>$ git-clone http://www.bitsun.com/git/gittutorcn.git</span></p>
<div>
<p align=left><strong><span>创建一个版本库：</span></strong><strong><span>git-init-db</span></strong></p>
</div>
<p align=left><span>创建一个</span><span> Git </span><span>版本库是很容易的，只要用命令</span><span> </span><span>git-init-db</span><span> </span><span>就可以了。现在我们来为本文的写作创建一个版本库：</span></p>
<p align=left><span>$ mkdir gittutorcn</span></p>
<p align=left><span>$ cd gittutorcn</span></p>
<p align=left><span>$ git-init-db</span></p>
<p align=left><span>git </span><span>将会作出以下的回应</span></p>
<p align=left><span>defaulting to local storage area</span></p>
<p align=left><span>这样，一个空的版本库就创建好了，并在当前目录中创建一个叫<span> .git </span>的子目录。你可以用 <span>ls -a</span><span> </span>查看一下，并请注意其中的三项内容： </span></p>
<p align=left><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>一个叫<span> HEAD </span>的文件，我们现在来查看一下它的内容： </span></p>
<p align=left><span>$ cat .git/HEAD</span></p>
<p align=left><span>现在<span> HEAD </span>的内容应该是这样： </span></p>
<p align=left><span>ref: refs/heads/master</span></p>
<p align=left><span>我们可以看到，<span>HEAD </span>文件中的内容其实只是包含了一个索引信息，并且，这个索引将总是指向你的项目中的当前开发分支。</span></p>
<p align=left><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>一个叫<span> objects </span>的子目录，它包含了你的项目中的所有对象，我们不必直接地了解到这些对象内容，我们应该关心是存放在这些对象中的项目的数据。</span></p>
<table cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top>
            <p align=left><strong><u><span>Note</span></u></strong></p>
            </td>
            <td>
            <p align=left><span>关于<span> git </span>对象的分类，以及<span> git </span>对象数据库的说明，请参看 <span><a href="http://www.kernel.org/pub/software/scm/git/docs/#Discussion," target=_blank>[Discussion]</a> </span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p align=left><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>一个叫<span> refs </span>的子目录，它用来保存指向对象的索引。</span></p>
<p align=left><span>具体地说，子目录 <span>refs</span><span> </span>包含着两个子目录叫 <span>heads</span><span> </span>和 <span>tags</span>，就像他们的名字所表达的意味一样：他们存放了不同的开发分支的<em>头</em>的索引<span>, </span>或者是你用来标定版本的<em>标签</em>的索引。 </span></p>
<p align=left><span>请注意：<span>master</span><span> </span>是默认的分支，这也是为什么 <span>.git/HEAD</span><span> </span>创建的时候就指向 <span>master</span><span> </span>的原因，尽管目前它其实并不存在。<span> git </span>将假设你会在 <span>master</span><span> </span>上开始并展开你以后的工作，除非你自己创建你自己的分支。 </span></p>
<p align=left><span>另外，这只是一个约定俗成的习惯而已，实际上你可以将你的工作分支叫任何名字，而不必在版本库中一定要有一个叫 <span>master</span><span> </span>的分支，尽管很多<span> git </span>工具都认为 <span>master</span><span> </span>分支是存在的。 </span></p>
<p align=left><span>现在已经创建好了一个<span> git </span>版本库，但是它是空的，还不能做任何事情，下一步就是怎么向版本库植入数据了。 </span></p>
<div>
<p align=left><strong><span>植入内容跟踪信息：</span></strong><strong><span>git-add</span></strong></p>
</div>
<p align=left><span>为了简明起见，我们创建两个文件作为练习：</span><span> </span></p>
<p align=left><span>$ echo "Hello world" &gt; hello</span></p>
<p align=left><span>$ echo "Silly example" &gt; example</span></p>
<p align=left><span>我们再用</span><span> </span><span>git-add</span><span> </span><span>命令将这两个文件加入到版本库文件索引当中：</span><span> </span></p>
<p align=left><span>$ git-add hello example</span></p>
<p align=left><span>git-add </span><span>实际上是个脚本命令，它是对</span><span> git </span><span>内核命令</span><span> </span><span>git-update-index</span><span> </span><span>的调用。因此上面的命令和下面的命令其实是等价的：</span><span> </span></p>
<p align=left><span>$ git-update-index --add hello example</span></p>
<p align=left><span>如果你要将某个文件从</span><span> git </span><span>的目录跟踪系统中清除出去，同样可以用</span><span> </span><span>git-update-index</span><span> </span><span>命令。例如：</span><span> </span></p>
<p align=left><span>$ git-update-index --force-remove foo.c</span></p>
<table cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top>
            <p align=left><strong><u><span>Note</span></u></strong></p>
            </td>
            <td>
            <p align=left><span>git-add</span><span> </span><span>可以将某个目录下的所有内容全都纳入内容跟踪之下，例如： <span>git-add ./path/to/your/wanted</span><span> </span>。但是在这样做之前，应该注意先将一些我们不希望跟踪的文件清理掉，例如，<span>gcc </span>编译出来的<span> *.o </span>文件，<span>vim </span>的交换文件<span> .*.swp </span>之类。 </span></p>
            </td>
        </tr>
    </tbody>
</table>
<p align=left><span>应该建立一个清晰的概念就是，</span><span>git-add</span><span> </span><span>和</span><span> </span><span>git-update-index</span><span> </span><span>只是刷新了</span><span> git </span><span>的跟踪信息，</span><span>hello </span><span>和</span><span> example </span><span>这两个文件中的内容并没有提交到</span><span> git </span><span>的内容跟踪范畴之内。</span><span> </span></p>
<div>
<p align=left><strong><span>提交内容到版本库：</span></strong><strong><span>git-commit</span></strong></p>
</div>
<p align=left><span>既然我们刷新了</span><span> Git </span><span>的跟踪信息，现在我们看看版本库的状态：</span><span> </span></p>
<p align=left><span>$ git-status</span></p>
<p align=left><span>我们能看到</span><span> git </span><span>的状态提示：</span><span> </span></p>
<p align=left><span>#</span></p>
<p align=left><span># Initial commit</span></p>
<p align=left><span>#</span></p>
<p align=left><span>#</span></p>
<p align=left><span># Updated but not checked in:</span></p>
<p align=left><span>#<span>&nbsp;&nbsp; </span>(will commit)</span></p>
<p align=left><span>#</span></p>
<p align=left><span>#<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>new file: example</span></p>
<p align=left><span>#<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>new file: hello</span></p>
<p align=left><span>#</span></p>
<p align=left><span>提示信息告诉我们版本库中加入了两个新的文件，并且</span><span> git </span><span>提示我们提交这些文件，我们可以通过</span><span> </span><span>git-commit</span><span> </span><span>命令来提交：</span><span> </span></p>
<p align=left><span>$ git-commit -m "Initial commit of gittutor reposistory"</span></p>
<div>
<p align=left><strong><span>查看当前的工作：</span></strong><strong><span>git-diff</span></strong></p>
</div>
<p align=left><span>git-diff</span><span> </span><span>命令将比较当前的工作目录和版本库数据库中的差异。现在我们编辑一些文件来体验一下</span><span> git </span><span>的跟踪功能。</span><span> </span></p>
<p align=left><span>$ echo "It's a new day for git" &gt;&gt; hello</span></p>
<p align=left><span>我们再来比较一下，当前的工作目录和版本库中的数据的差别。</span><span> </span></p>
<p align=left><span>$ git-diff</span></p>
<p align=left><span>差异将以典型的</span><span> patch </span><span>方式表示出来：</span><span> </span></p>
<p align=left><span>diff --git a/hello b/hello</span></p>
<p align=left><span>index a<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="5" UnitName="C">5c</st1:chmetcnv>1966..bd<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="9212" UnitName="C">9212c</st1:chmetcnv> 100644</span></p>
<p align=left><span>--- a/hello</span></p>
<p align=left><span>+++ b/hello</span></p>
<p align=left><span>@@ -1 +1,2 @@</span></p>
<p align=left><span>&nbsp;Hello, world</span></p>
<p align=left><span>+It's a new day for git</span></p>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/48872.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-09-09 11:40 <a href="http://www.cnitblog.com/jakiegu/archive/2008/09/09/snooker.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LoadRunner端口映射</title><link>http://www.cnitblog.com/jakiegu/archive/2008/07/15/46746.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Tue, 15 Jul 2008 07:18:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/07/15/46746.html</guid><wfw:comment>http://www.cnitblog.com/jakiegu/comments/46746.html</wfw:comment><comments>http://www.cnitblog.com/jakiegu/archive/2008/07/15/46746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/jakiegu/comments/commentRss/46746.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/jakiegu/services/trackbacks/46746.html</trackback:ping><description><![CDATA[<p>LR的Port端口映射的视频演示<br></p>
<p><a href="http://www.tudou.com/programs/view/MSDYcTpzrfU/">http://www.tudou.com/programs/view/MSDYcTpzrfU/</a></p>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/46746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-07-15 15:18 <a href="http://www.cnitblog.com/jakiegu/archive/2008/07/15/46746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux内核测试三部曲（3）</title><link>http://www.cnitblog.com/jakiegu/archive/2008/06/19/45881.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Thu, 19 Jun 2008 05:23:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/06/19/45881.html</guid><description><![CDATA[阶段三 容错性测试<br><br>你的新内核已经通过了测试的前两个阶段了吗？现在，可以开始实验了。那就是，做一些任何一个正常人在普通工作中都不会做的蠢事，因为没人会知道那些蠢事会导致内核崩溃。那到底需要做些什么事呢？好的，如果存在一个&#8220;标准的&#8221;程序的话，那它当然早就被包含在一些测试套件中了。<br><br>例如，第三阶段可以从拔掉和重插USB设备开始。从理论上讲，重插一个USB设置不应该会产生任何事情，至少从用户的角度看来。如果USB子系统存在bug,连续进行很多次这样的测试就可能会导致内核崩溃(这个测试如果出现问题，说明了之前未曾有人在类似系统配置下尝试这个测试)。<br>接下来，你可以编写一个脚本，连续读取/proc目录中文件的内容，等等。一句话，在这阶段，你应该做些普通用户永远不会做的事(或者极常少做：为什么有人会不断重复地挂载和卸载某个文件系统呢？)
<img src ="http://www.cnitblog.com/jakiegu/aggbug/45881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-06-19 13:23 <a href="http://www.cnitblog.com/jakiegu/archive/2008/06/19/45881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux内核测试三部曲（2）</title><link>http://www.cnitblog.com/jakiegu/archive/2008/06/19/45879.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Thu, 19 Jun 2008 05:20:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/06/19/45879.html</guid><description><![CDATA[阶段二（自动测试）<br><br>测试的下一阶段是，使用专门设计的程序来检查特定的内核子系统能否正常工作。我们还执行内核的退化以及性能测试。后者对于内核开发员（还有我们）来说，相当地重要，因为它使得我们能识别出损害性能的改变。比如，如果我们把内核从2.6.x-rc1升级到2.6.x-rc2后，有种文件系统的性能却降低了10%，查找导致这种情况发生的补丁无疑是个好主意。<br><br>关于内核的自动测试，我们推荐你使用AutoTest 套件(<a href="http://test.kernel.org/autotest/">http://test.kernel.org/autotest/</a>)。该套件包含了很多测试应用程序以及统计工具，而且相当简单的用户界面。<br><br>为了安装AutoTest你以root帐户可以进入到/usr/local 目录并运行<br><br># svn checkout svn://test.kernel.org/autotest/trunk autotest<br><br>虽然通常不推荐以root帐户运行类似命令，但这个命令应该是安全的，除非你不信任你的DNS服务器，因为它只是下载一些文件，并保存到/usr/local下。除此之外，你还得以root帐户运行AutoTest，因为它的一些测试要求超级用户权限才能完成。所以，你不应该在生产系统上使用AutoTest:在极端情况下，保存在进行特权级测试的系统中的数据可能会受到损坏甚至毁坏，我们相信你不喜欢你的产品数据会发生这种情况。<br>根据设计，AutoTest是非交互式性的，所以一旦启动，你就不需要再关心它了(当然了，如果有坏事真的发生了，你就要不得不恢复系统了，但这是另外一个话题)。要启动测试，你可以到/usr/local/autotest/client目录下 (我们假设AutoTest被安装到了/usr/local下),然后以root身份执行：<br><br># bin/autotest tests/test_name/control<br><br>这里，test_name是位于目录/usr/local/autotest/client/tests中的目录名称，该目录中含有你想要进行的测试。控制文件tests/test_name/control包含了为AutoTest准备的指令。最简单的情况下，只需要一个这样的指令，也就是：<br><br>job.run_test(&#8217;test_name&#8217;)<br><br>这里，test_name是包含控制文件的目录名称。更加复杂的控制文件的内容可能类似下面：<br><br>job.run_test(&#8217;pktgen&#8217;, &#8217;eth0&#8217;, 50000, 0, tag=&#8217;clone_skb_off&#8217;)<br>job.run_test(&#8217;pktgen&#8217;, &#8217;eth0&#8217;, 50000, 1, tag=&#8217;clone_skb_on&#8217;)<br><br>这里，测试名称后面的字符串表示的是应当要传递到测试程序的参数。你可以修改这些参数，但是首先要阅读测试程序的文档以及脚本tests/test_name/test_name.py(比如tests/pktgen/pktgen.py)。实际上AutoTest就是使用该脚本来启动测试的(可能你已经注意到，<br>AutoTest脚本是用Python语言写的)。脚本sts/test_name/test_name.py的执行结果保存在目录results/default/test_name/中，该目录中的status文件包含着标识测试是否已经成功完成的信息。想取消正在进行的测试，按Ctrl+C即可。<br>如果你想连续运行一串测试，最好的做法是准备单独一个文件，该文件中包含着多个AutoTest的指令。这个文件中的指令和上面提到的控制文件中的指令类似。比如，文件samples/all_tests包含有运行所有可以测试指令，其中前五行如下<br><br>job.run_test(&#8217;aiostress&#8217;)<br>job.run_test(&#8217;bonnie&#8217;)<br>job.run_test(&#8217;dbench&#8217;)<br>job.run_test(&#8217;fio&#8217;)<br>job.run_test(&#8217;fsx&#8217;)<br><br>要运行这个文件中的指令所请求的全部测试，你可以做使用命令bin/autotest samples/all_tests。但是要记得这要花很长的时间才能完成。类似地，要运行定制的一串测试，得把为AutoTest准备的指令们放到一个文件里面，然后给这个文件起个名称，这个名称将作为命令行的一个参数传递给autotest.要并行地运行几个测试，你得准备一个特殊的控制文件，这个控制文件包含的指令如下:<br><br>def kernbench():<br>job.run_test(&#8217;kernbench&#8217;, 2, 5)<br>def dbench():<br>job.run_test(&#8217;dbench&#8217;)<br>job.parallel([kernbench], [dbench])<br><br>在测试执行的过程序中，在任何时间里，你都可以通过按Ctrl+C来停止它们。<br>为了造福那些不喜欢命令行和配置文件的朋友，ATCC (AutoTest Control Center )已经被发明出来了。如果你运行它，比如通过命令ui/menu,将会得到一个用菜单驱动的简单界面，你可以通过界面选择测试和profiling工具，浏览测试结果，还可以通过它来限制范围，配置它们。<br>如果你厌烦了AutoTest套件中包含的一系列工具，可以访问站点<a href="http://ltp.sourceforge.net/tooltable.php">http://ltp.sourceforge.net/tooltable.php</a> 。该站点有可以用于linux内核测试的全面的工具清单。<br><br>
<img src ="http://www.cnitblog.com/jakiegu/aggbug/45879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-06-19 13:20 <a href="http://www.cnitblog.com/jakiegu/archive/2008/06/19/45879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux内核测试三部曲（1）</title><link>http://www.cnitblog.com/jakiegu/archive/2008/06/19/45878.html</link><dc:creator>Test8848-谷峰</dc:creator><author>Test8848-谷峰</author><pubDate>Thu, 19 Jun 2008 05:17:00 GMT</pubDate><guid>http://www.cnitblog.com/jakiegu/archive/2008/06/19/45878.html</guid><description><![CDATA[通常，有多种测试linux内核的方法，但我们只关注下面这4种：<br><br>1. 在平时的工作中使用内核的测试版本.<br><br>2. 在新内核上运行专用的测试套件，比如LTP.<br><br>3. 新内核安装后，做些非常规的事情.<br><br>4. 新内核安装后，测试系统的性能.<br><br>当然，测试过程它们可以混合运用，所以可以认为它们是测试过程的不同阶段。<br><br><br>阶段一:内核的冒烟测试<br><br>内核测试的第一阶段很简单：我们尝试着启动内核，然后把它用在平时的工作中。<br><br>&#8226; 在以全功能配置启动系统之前，推荐先用init=/bin/bash命令行参数来启动内核。它使得内核只启动一个bash进程。这样，你可以检查在最小配置下是否能正常挂载和卸载文件系统，然后，你可以测试一些更加复杂的内核功能，比如挂起到disk或RAM的缓冲。这种情况下，唯一被挂载了的模块是位于initrd映象中的那些模块。提到 了initrd映象。通常，你可以参考你的boot loader文档来获取更多关于手工向内核传递命令行的信息(我们的观点是，如果使用的是GRUB，会更容易操作些。)<br><br>&#8226; 接着，建议以runlevel 2来启动系统(通常，是通过把数字2作为命令行参数传递给内核)，这时，网络服务器和X服务器还没启动(你的系统有可能为这个用途使用的是另一个runlevel，尽管不大可能，所以你应该查看/etc/inittab文件确认一下)。在这个配置下，你可以检查网络接口是否能工作，你还可以尝试手工启动X服务器来确认它不会崩溃掉。<br><br>&#8226; 最后，根据需要，你可以把系统启动到runlevel 5(也就是全功能)或者3（也就是除了X，全功能开启）<br>现在，你已经可以按平时的样子使用系统一段时间了。但是，如果想快点测试内核，你可以执行一些典型的操作，比如下载一些文件，读取邮件，浏览一些站点，抓取一些音轨(我们假设，使用的是合法买来的音频CD)，刻录一张CD或DVD等等操作来连续地检查是否有任何一项会出错。出错的话，就意味着内核有问题存在了
<img src ="http://www.cnitblog.com/jakiegu/aggbug/45878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/jakiegu/" target="_blank">Test8848-谷峰</a> 2008-06-19 13:17 <a href="http://www.cnitblog.com/jakiegu/archive/2008/06/19/45878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>