﻿<?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>C++博客-我的编程乐园-随笔分类-Git</title><link>http://www.cppblog.com/deercoder/category/18145.html</link><description>&lt;P&gt;&lt;FONT style="FONT-SIZE: 20px" color=#ff0000&gt;积累，坚持！&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT style="FONT-SIZE: 20px" color=#ff0000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ---------我是一只IT小小鸟&lt;/FONT&gt;&lt;/P&gt;</description><language>zh-cn</language><lastBuildDate>Sat, 14 Apr 2012 12:33:08 GMT</lastBuildDate><pubDate>Sat, 14 Apr 2012 12:33:08 GMT</pubDate><ttl>60</ttl><item><title>使用Mercurial同步版本库出错</title><link>http://www.cppblog.com/deercoder/archive/2012/04/07/170387.html</link><dc:creator>刘畅</dc:creator><author>刘畅</author><pubDate>Sat, 07 Apr 2012 13:29:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2012/04/07/170387.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/170387.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2012/04/07/170387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/170387.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/170387.html</trackback:ping><description><![CDATA[今天在使用Mercurial同步版本库的时候，出现错误：<br /><br /><div>warning: code.google.com certificate with fingerprint ed:2e:18:55:ee:6b:cc:4c:cb:8b:11:a8:74:5c:97:9e:1d:42:b5:be not verified (check hostfingerprints or web.cacerts config setting)</div><div>destination directory: ipv6-hosts</div><div>abort: Operation not permitted: /media/Code/ipv6-hosts/ipv6-hosts/.hg/requires<br />半天死活找不到原因，记得在Git下面checkout Google Code项目的时候并没有出现类似的提示，由于以前没有接触过Mercurial，因此花了点时间Google一下，最终发现大致的过程也不过如此，init， checkout，pull等等。<br /><br />但是回到正题，不论是init还是clone都会出现上面的错误，提示权限问题，抱着试试的态度，使用sudo命名，记过成功的init和clone，看来不论是哪里，都要注意权限。<br /><br />不过额外再说一点，同样的，我在该目录下面新建一个文件夹，利用git init来初始化的时候，却并没有碰到相同的问题，只能说明，Git和Mercurial的机制可能不同，后者在操作的过程中需要加入提升权限的口令。记录一下，由于使用Mercurial的机会也不是很多，这里只是拷贝一下版本库，并无太多深入研究，所以先记录在这里吧。</div> <div class="vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><img src ="http://www.cppblog.com/deercoder/aggbug/170387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">刘畅</a> 2012-04-07 21:29 <a href="http://www.cppblog.com/deercoder/archive/2012/04/07/170387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GitHub使用简介</title><link>http://www.cppblog.com/deercoder/archive/2011/11/13/160050.html</link><dc:creator>刘畅</dc:creator><author>刘畅</author><pubDate>Sun, 13 Nov 2011 15:49:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2011/11/13/160050.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/160050.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2011/11/13/160050.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/160050.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/160050.html</trackback:ping><description><![CDATA[<div><div></div></div><div><div>1. 关于GitHub的常见使用方法，请参考官网上面的说明。本篇文档只是针对于常用的，而且容易犯错的用法进行说明。仅仅是个人观点。</div><div></div><div>2. 如何使用GitHub？</div><div>(1) 常用的是首先在GitHub上创建一个版本库，然后接下来的工作是在本机创建一个版本库，注意不一定要和原来那个版本的文件名相同。比如原来创建的版本为HelloWorld，那么本机完全可以使用一个文件名为HelloRyan这样的文件夹。只是需要在后续操作中配置相应的信息即可。</div><div>(2) 本机创建文件夹后，需要进行Git的配置。首先git init来初始化一个版本库，然后需要建立和远程版本库的链接。这里使用git remote add命令来添加。</div><div>git remote add origin url</div><div>其中origin是你指定的url的别名，你完全可以取其他的名称。而url则是版本库信息对应的路径，这里在GitHub上面你创建的版本库上面，有一个SSH/HTTP/Git Read-Only这些选项，你需要的做的就是选择一个url，填写即可。比如</div><div>git remote add helloworld git@github.com:username/repname.git</div><div>(3) 建立起本机和远程的联系之后，还可以对Git进行简单配置，比如邮箱，用户名，比较工具啥的，由于本文不是初级教程，所以此部分内容略。详见官方文档。</div><div>(4) 本机进行工程开发，比如新建文件，然后提交。等等</div><div>(5) 保证和远程同步，因此需要将本机的版本库push到远程上去，为此使用：</div><div>git push origin branch</div><div>其中，origin就是刚刚取的别名，比如是helloworld，而后面的就是要推送到的分支名，比如master。具体就看你本机和远程的分支，对应的别名了。</div><div>(6) 完成了上述修改后，可能会在另外一个场合拉取代码，此时还是相同的步骤，创建一个文件夹，git init来初始化版本库，然后同样git remote add xxx xxx。</div><div>接下来的任务就是执行pull命令：git pull xxx branch(其中xxx就是前面的origin,helloworld这些别名)。</div><div></div><div>简单的用法就介绍到这里。</div><div>下面说说一些用到的体会，总结。</div><div></div><div>(1) 首先是关于git remote add xxx xxx这个用法。这个做法是取别名，避免了每次都要输入完整的路径名，当然，你也可以这么做，当然没问题。</div><div>比如：git pull url master，就是把远程的url这个拉取到本机的master分支上。</div><div>可是每次都这么做多麻烦，为此使用别名，以后就直接通过别名来push，pull。</div><div>实际上，昨晚这个工作后，会在.git目录下面的config文件中写入一个项，用来指示该别名的信息,如下所示：</div><div>[remote "origin"]</div><div><span style="white-space:pre">	</span>url = git@github.com:xxx/rep.git</div><div><span style="white-space:pre">	</span>fetch = +refs/heads/*:refs/remotes/origin/*</div><div></div><div>上面就是别名origin这个别名的信息。记录了目标远程版本库的地址。</div><div></div><div>(2) SSH方式还是HTTPS方式。</div><div>在版本库的SSH方式和HTTPS方式是不同的，具体来说就是url信息的不同，但是，实际的认证机制也是不同的。当建立了本机密钥之后，使用ssh方式实际上是不需要再次认证的，而https则每次需要输入密码。</div><div>比如，上面的url = git@github.com:xxx/rep.git使用的是ssh方式，那么我进入一个版本库中，push到远程的时候，是不需要输入用户名和密码的，这个只在你初始时候使用到。而如果我的url是以https方式来做的话，如url = https://xxxx，这样我在进行更新，push或者pull的时候，都会提示你输入GitHub的帐号和密码的。实际上，GitHub是鼓励使用ssh方式的，在官方文档也有说明，不过对于无法使用ssh服务的地方来说，https又多了一种方式，给用户也带来了方便。</div><div></div><div>(3) 常用的命令和Git的使用似乎并不需要有太多的说明，但是要想掌握这个工具还是需要很大的尝试和努力。这里推荐下图形化使用工具TGit（Windows）以及gitg(Linux)版本。通过图形化工具能够帮助我们熟悉提交图，掌握基本的操作，有时候图形化界面能够极大的方便我们操作，比如右键可以打Tag，查看分支，所有分支，Diff等等。</div><div>在Windows下面，先要安装Git程序，然后安装TGit，指定Git路径，此时可以利用Cygwin的命令行界面来操作Git，同时可以在右键菜单中使用TGit来查看提交图。</div><div>在Linux下面，就直接使用命令行来工作，同时利用gitg等图形化工具来观察提交图等。</div><div></div><div>(4)协同工作。在GitHub上面有很多开源项目可以参与到开发学习，可以搜索相关项目，fork该项目，然后在自己的版本库中就会出现，此时通过pull可以更新到本机，然后再进行开发，当你开发之后push上去，再通过向开发者发送请求让其了解到你进行的修复，然后他根据自己的判断是否采纳，更新版本库来决定是否让你的这次提交并入到版本库中。</div><div></div><div>(4)更多关于Github的使用请参见官网：https://github.com,里面讲述了如何从建立版本库到创建分支，管理版本库的知识。</div></div><div></div><div></div> <div class="vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><img src ="http://www.cppblog.com/deercoder/aggbug/160050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">刘畅</a> 2011-11-13 23:49 <a href="http://www.cppblog.com/deercoder/archive/2011/11/13/160050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Git Stash用法</title><link>http://www.cppblog.com/deercoder/archive/2011/11/13/160007.html</link><dc:creator>刘畅</dc:creator><author>刘畅</author><pubDate>Sat, 12 Nov 2011 16:36:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2011/11/13/160007.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/160007.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2011/11/13/160007.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/160007.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/160007.html</trackback:ping><description><![CDATA[最近在使用Git管理项目工程的时候，遇到了很多问题，也学习到了很多关于Git常见使用的技巧，下面就其中关于Git Stash的用法和大家分享下。<br />首先，简单介绍下Git Stash命令的用法，详细的用法在man文档中有相关介绍，下面我来说明常见的使用。<br />git stash: 备份当前的工作区的内容，从最近的一次提交中读取相关内容，让工作区保证和上次提交的内容一致。同时，将当前的工作区内容保存到Git栈中。<br />git stash pop: 从Git栈中读取最近一次保存的内容，恢复工作区的相关内容。由于可能存在多个Stash的内容，所以用栈来管理，pop会从最近的一个stash中读取内容并恢复。<br />git stash list: 显示Git栈内的所有备份，可以利用这个列表来决定从那个地方恢复。<br />git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现，原来stash的哪些节点都消失了。<br />关于Git Stash的详细解释，适用场合，这里做一个说明：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">使用git的时候，我们往往使用branch解决任务切换问题，例如，我们往往会建一个自己的分支去修改和调试代码,&nbsp;如果别人或者自己发现原有的分支上有个不得不修改的bug，我们往往会把完成一半的代码&nbsp;commit提交到本地仓库，然后切换分支去修改bug，改好之后再切换回来。这样的话往往log上会有大量不必要的记录。其实如果我们不想提交完成一半或者不完善的代码，但是却不得不去修改一个紧急Bug，那么使用</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;stash</span><span style="color: #000000; ">'</span><span style="color: #000000; ">就可以将你当前未提交到本地（和服务器）的代码推入到Git的栈中，这时候你的工作区间和上一次提交的内容是完全一样的，所以你可以放心的修&nbsp;Bug，等到修完Bug，提交到服务器上后，再使用</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;stash&nbsp;apply</span><span style="color: #000000; ">'</span><span style="color: #000000; ">将以前一半的工作应用回来。也许有的人会说，那我可不可以多次将未提交的代码压入到栈中？答案是可以的。当你多次使用</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;stash</span><span style="color: #000000; ">'</span><span style="color: #000000; ">命令后，你的栈里将充满了未提交的代码，这时候你会对将哪个版本应用回来有些困惑，</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;stash&nbsp;list</span><span style="color: #000000; ">'</span><span style="color: #000000; ">命令可以将当前的Git栈信息打印出来，你只需要将找到对应的版本号，例如使用</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;stash&nbsp;apply&nbsp;stash@{1}</span><span style="color: #000000; ">'</span><span style="color: #000000; ">就可以将你指定版本号为stash@{</span><span style="color: #000000; ">1</span><span style="color: #000000; ">}的工作取出来，当你将所有的栈都应用回来的时候，可以使用</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;stash&nbsp;clear</span><span style="color: #000000; ">'</span><span style="color: #000000; ">来将栈清空。<br />在这里顺便提下git&nbsp;format</span><span style="color: #000000; ">-</span><span style="color: #000000; ">patch&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">n&nbsp;,&nbsp;n是具体某个数字，&nbsp;例如&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;format-patch&nbsp;-1</span><span style="color: #000000; ">'</span><span style="color: #000000; ">&nbsp;这时便会根据log生成一个对应的补丁，如果&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">git&nbsp;format-patch&nbsp;-2</span><span style="color: #000000; ">'</span><span style="color: #000000; ">&nbsp;那么便会生成2个补丁，当然前提是你的log上有至少有两个记录。</span></div><br />看过上面的信息，就可以知道使用场合了：当前工作区内容已被修改，但是并未完成。这时Boss来了，说前面的分支上面有一个Bug，需要立即修复。可是我又不想提交目前的修改，因为修改没有完成。但是，不提交的话，又没有办法checkout到前面的分支。此时用Git Stash就相当于备份工作区了。然后在Checkout过去修改，就能够达到保存当前工作区，并及时恢复的作用。<br /><br />下面，将我使用过程中遇到的一个问题和大家分享：<br /><br />首先，在Git Stash之后，提交图如下所示：<br /><img src="http://www.cppblog.com/images/cppblog_com/deercoder/Git_Stash_1.png" alt="" width="832" height="266" border="0" /><br />从图中可以看到，develop和newdevelop是在同一个分支上，因为分支newdevelop是在develop分支的基础上开发的。想加入一个新的特性，所以就开了newdevelop分支，然后就在上面加东西，加特性，该代码。这个时候工作的内容已经变化了，但是develop和newdevelop都是指向同一个提交的，因为newdevelop上面还木有提交。<br />这个时候，Boss来了，说develop上面有个Bug，赶快改一下，手头的工作先放放，稳定版本不能有缺陷。没办法，当前正在newdevelop上搞的high呢，就Git Stash一下。所以会看到上面有两个节点，红色以及上面一个。就是stash之后的结果，注意是在newdevelop上面进行的stash。<br /><br />正如前面所说，stash会暂存当前的工作区内容，然后将工作区内容保持和上次提交相同，此时内容都是上面8a32那个提交的内容。从终端中查看相应的信息内容，如下：<br /><img src="http://www.cppblog.com/images/cppblog_com/deercoder/Git_Stash_2.png" alt="" width="644" height="374" border="0" /><br />印证了签名的说法，newdevelop是有修改，modified，然后stash之后，工作区是最近一次提交，此时newdevelop和develop都是相同的，所以再git status查看发现，都一样，nothing to commit.<br /><br />然后Stash完成之后，就要Fix Bug了。为此，回到develop分支上进行修复，然后提交，完成后的提交图如下所示：<br /><div><img src="http://www.cppblog.com/images/cppblog_com/deercoder/Git_Stash_3.png" alt="" width="822" height="194" border="0" /></div>从途中可以看到，newdevelop还是在下面，因为指向的是老的那个8a32的commit。新的develop由于修复了Bug，所以产生一个新提交。<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/deercoder/Git_Stash_4.png" alt="" width="635" height="167" border="0" /><br />然后在develop上面修复了Bug之后，在回到newdevelop上面进行一个新的特性的继续编码，此时checkout回去的时候，没有神马内容可以提交，因为都存在Stash中了，没有任何修改。如上图。<br /><br />那么，恢复工作区内容吧。于是git stash pop（注意这里由于只Stash了一次所以使用pop，具体你存放了多少，要恢复哪一个要自己清楚，否则会出错！）<br /><img src="http://www.cppblog.com/images/cppblog_com/deercoder/Git_Stash_5.png" alt="" width="645" height="428" border="0" /><br />恢复之后，从上图中可以看到，此时再git status就会发现文件有修改，说明恢复过来了。然后就继续编码，提交一个稳定的新特性版本，如下图，产生的新提交为0906.<br />然后再查看提交图，会发现，stash pop之后，对应的存放的stash被清空掉了，提交图中，newdevelop上面对应一个新的提交。并且在develop上面。分支的develop那个红色，即为前面修复Bug的那个提交。<br /><img src="http://www.cppblog.com/images/cppblog_com/deercoder/Git_Stash_6.png" alt="" width="816" height="122" border="0" /><br /><br />总结起来：<br />操作很简单，但是头脑要清楚。要在哪个分支上修复Bug，要暂存哪个地方的内容，之后修复完了在那个地方提交，然后要到哪个分支上面恢复工作区，都是需要注意的，否则，很容易造成提交图混乱。只有弄清楚了工作流程，才不容易出错，才能保证很高的工作效率。<br />最后一句：Git是神器，就要看你如何驾驭它了。<img src ="http://www.cppblog.com/deercoder/aggbug/160007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">刘畅</a> 2011-11-13 00:36 <a href="http://www.cppblog.com/deercoder/archive/2011/11/13/160007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>