开始本文前,首先让我来抛砖引玉:svn和git到底有什么区别
相信读过 蒋鑫《git权威指南》的同学都大概了解了git和Subversion的区别和优劣了。
那么,为什么我要用git,原因大概有5个:
GIT跟SVN一样有自己的集中式版本库或服务器。但,GIT更倾向于被使用于分布式模式,也就是每个开发人员从中心版本库/服务器上chect out代码后会在自己的机器上克隆一个自己的版本库。可以这样说,如果你被困在一个不能连接网络的地方时,就像在飞机上,地下室,电梯里等,你仍然能够提交文件,查看历史版本记录,创建项目分支,等。对一些人来说,这好像没多大用处,但当你突然遇到没有网络的环境时,这个将解决你的大麻烦。
所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。如果你把.git目录的体积大小跟.svn比较,你会发现它们差距很大。因为,.git目录是处于你的机器上的一个克隆版的版本库,它拥有中心版本库上所有的东西,例如标签,分支,版本记录等。
分支在SVN中一点不特别,就是版本库中的另外的一个目录。如果你想知道是否合并了一个分支,你需要手工运行像这样的命令svn propget svn:mergeinfo,来确认代码是否被合并。所以,经常会发生有些分支被遗漏的情况。
然而,处理GIT的分支却是相当的简单和有趣。你可以从同一个工作目录下快速的在几个分支间切换。你很容易发现未被合并的分支,你能简单而快捷的合并这些文件。
目前为止这是跟SVN相比GIT缺少的最大的一个特征。你也知道,SVN的版本号实际是任何一个相应时间的源代码快照。我认为它是从CVS进化到SVN的最大的一个突破。因为GIT和SVN从概念上就不同,虽然我不知道GIT里是什么特征与之对应。
有人说,我们可以使用GIT的SHA-1来唯一的标识一个代码快照。这个并不能完全的代替SVN里容易阅读的数字版本号。但,用途应该是相同的。
GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
stackoverlflow里有一个很好的关于GIT内容完整性的讨论 http://stackoverflow.com/questions/964331/git-file-integrity
ssh root@vpsip
登陆之后,我创建一个git版本库,让我们暂时取名为“test”
ls命令之后文件目录为. .. .git
ok,初始化版本库后,让我们来写个c程序。
vim hello.c #include<stdio.h> int main(){ printf("Hello"); return 0; }
看到现在目录下的文件:
但是,现在我们的版本库test中其实还没有hello.c这个文件,这是为什么呢?原来我们需要把对版本库内的更改add到git代码版本库里。
git add .
(说明下,用“.”代表把所有当前的更改添加进去,如果你要添加某一个文件,就把“.”替换成对应文件名)
接下来就是把所有更改“提交”到版本,那么我们就完成了版本库的修改。
git commit -m"输入信息"
输出信息中“100644”对应当前版本的编号。举个例子,要是某一天你手贱不小心把文件提交错了,那么你可以回到任意之前的版本。
git branch
这个命令可以查看你的目前分支,master称为主分支,其他分支可以通过与master的“merge”(合并)操作合并到一起。比如你们团队开发一个社交app,客户说,我下一个版本需要ABCD四个功能,那么,负责ABCD四个功能的四个负责人就去对应开发相应功能的分支。最后,通过merge操作,合并到一起,项目就能如期交付了~~
ok,现在让我们回到Mac OS,现在我需要用到vps上的hello.c代码,那么,我需要从远程版本库里“克隆”一份到我的本地。
cd /desktop/github/ git clone ssh://root@vpsip:/var/web/test 看到执行结果: remote: 对象计数中: 3, 完成. remote: 压缩对象中: 100% (2/2), 完成. remote: Total 3 (delta 0), reused 0 (delta 0) Receiving objects: 100% (3/3), done. Checking connectivity... done. promatoMBP:github pro$
本地也有了!
比如现在我在vps修改了版本库,那么本地Mac OS端不会自动同步远程的修改,这时我们下次需要把远程的代码库拉(pull)下来。近似相当于svn里的update操作。
git pull
当我们要把Mac OS修改的信息更新到远程,那么就推(push)过去。
git push
当本机上提交到vps的branch为vps的当前branch时,vps的git会拒绝更新,个中缘由可以很轻易地猜测出来:当vps上也在编辑时,允许更新会带来混淆。当然,可以通过git reset –hard手动更新。现在的问题是,如何自动检测到提交请求然后允许git reset –hard命令。这里要用到git的钩子方法。
进入vps的版本库test,然后按下列命令执行:
cd .. env -i git reset --hard chmod a+x .git/hooks/post-receive
目的在于将其设置为可以执行,然后vps就会接受本地的push了。
在V2EX上,在stackoverflow上,在面试简历上,把自己的githubID简历贴到个人信息中,对于自己绝对是一个加分项。不要和我聊什么开源中国。。。虽然我没有鄙视国内开源项目的意思,毕竟还是有很多大牛(比如clowwindy的shadowsocks)做出了优秀的开源项目。
而“开源”一词,则是github的核心,它的伟大在于,用git的方式控制代码,用GNU的精神去开源推动IT的发展。
想google code当年也没有想到github的发展会如此迅猛,以致于后来google code被迫关闭。对于我这个Pythoner,像Django,Tornado,Flask,GoAgent,Linux等等优秀的开源项目,给了我极大的学习空间。
让我们再来看看Linus大神在github的表现(毕竟git也是Linus团队的产物)。
我要说那么多在于,在github上,尝试做一些开源项目,尝试去把自己的代码放上去(下载windows或者Mac版),对于自己,绝对会有很大的提升。
(作者:骏宇,转载请注明本文来源 http://www.shadowtrees.com )