集中式VS分布式
就目前而言,普遍应用中的版本控制工具大体可以分成两类:集中式版本控制系统和分布式版本控制系统,前者的代表是SVN,后者的代表就是Git了。记得哥刚出道那会还是遍地SVN,吃Git这只螃蟹的人还是少数,新的事物,传播和接受都需要一点时间。但是很快,凭借自身强大的优势,同时借着Github这个强大的开源代码管理平台的扩张,Git迅速崛起为最流行的分布式版本控制系统。
Git能超越SVN,凭借的是哪些优势呢?那就要分析下这两个系统的区别:
集中式版本控制系统
关键词就是“集中”,所有代码库都只保存在一个中心服务器上,作为每个终端的数据源。开发的时候大家都从这同一源位置拉取代码,开发完成将代码提交到远程版本库中,同时会生成一个最新的版本号。源码库就这么一个,要是不小心出了点故障,那大家都没得玩了,这是集中式系统在安全性上一个重要问题。
另外,开发的时候都是直接跟远程源码库对话,新添加的内容或者修改的文件,要么放在本地,要么就提交到中心版本库。但是在实际开发中经常是这样的情景:一个需求要开发好几天,我可能会分几个模块开发,每开发完一个模块就想提到远程库去做个标记,作为阶段性成果,但是又怕这部分还不完整可能还包含BUG的代码影响到别人,或者压根就不想让这些半成品让别人看见。这个时候类SVN的集中式版本控制系统就没什么好办法了。
上个简单的图说明下:
分布式管理系统
既然集中不好那就分散呗,确实,分布式系统与集中式系统最核心的区别就是去中心化,每个人的电脑上都是一个完整的版本库。不用担心中心服务器出故障怎么办,代码管理在本地就可以完成。当然一般为了协作和维护方便,都会指定一个中心服务器,可要知道,这并非必须的。
一个分布式管理系统看起来应该是这样的:
Git相较于SVN的优势还有很多,比如强大的分支管理等,后续会慢慢补充,但上面所述部分是它们根本的不同之处。
图解 try Git
本文的标题是Git初识,内容主要针对Git初学者,我本人也是在学习中,这里主要记录自己的学习过程和心得,有错漏的地方还请大家多多指正~
Git官网上提供了一个在线模拟Git操作的网站:tryGit(https://try.github.io/levels/1/challenges/1)。对于了解Git操作流程,学习它的核心命令很有帮助,我本人非常喜欢,于是利用空闲时间制作了一个图解教程,希望对学习Git的同学有所帮助。
上图先(画的糙,大家将就着看):
名称释义
首先介绍下图中几个仓库/文件目录的含义:
working directory:很好理解,本地的文件目录,存放本地仓库代码的地方。
staging area:这个单从字面翻译就很有意思:“部队从一个战场转往另一个战场的集结地” ,嗯,这只是一个临时的集合场所而已!
local repository: 本地仓库,这是Git区别于SVN的关键所在,我们大部分操作都只需要在本地仓库进行就可以了。
remote repository: 远程仓库,其实它与本地仓库没有本质区别,只是为了方便大家协作开发而共同认定的一个中心库。
git init
$ cd ~/<working directory>
$ git init
创建本地仓库,将当前工作目录纳入Git管辖,会在当前目录下生成一个隐藏的.git文件夹,这个目录是Git来跟踪管理版本库的,不要瞎动。
git clone
$ git clone <远程版本库的地址>
该命令会在本地主机生成一个目录,与远程主机的版本库同名。可以指定不同的目录名:
$ git clone <远程版本库的地址> <自定义目录名>
git add
$ git add a.txt
将a.txt 提交到暂存区(staging area),提交到暂存区的文件会被标示上staged状态,相当于军队集合的时候你是在列状态一样~
add 命令有几个令人困惑的地方在这里说明下:
首先,这个命令与SVN里的add命令意思差异较大,用过SVN的同学应该知道,SVN中的add是将文件纳入SVN管理的意思,而Git里add就是将文件暂时保存一下。
其次,add命令本身就容易给人造成误解,如果不习惯可以改成stage命令,他们是等价的,还好理解一些。
git commit
$ git commit a.txt
将缓存区的内容提提交到本地仓库
git push
$ git push <远程主机名> <本地分支名>:<远程分支名>
$ git push origin master:master
将本地仓库master分支的代码推送到远程origin主机上的master分支
git pull
$ git pull <远程主机名> <远程分支名>:<本地分支名>
$ git pull origin track:track
从远程origin主机的track分支拉取代码到本地仓库的track分支
pull 命令可以分解成两个部分,首先是从origin主机拉取代码到本地仓库(fetch),紧接着将拉取的代码与本机目录上得代码进行自动合并(auto merge)。因此我们可以用fetch + merge的方式来代替pull命令,且后者是更值得推荐的,因为自动合并有时会出现问题,报错也没有手动merge的报错直观。
git checkout
$ git checkout -- test.jsp
将工作空间里test.jsp(该文件此时还没有被add)的改动撤销
此外checkout命令还可以用来切换分支:
$ git checkout master //切换到master分支
git reset
$ git reset --hard <commit ID> //将本地代码回退到指定的某次commit,目录和缓存区的修改都被丢弃
$ git reset --soft <commit ID> //将HEAD指向<commit ID>所在位置,本地的修改(即<commit ID>位置之前的修改)回退到缓存区
$ git reset --mixed <commit ID> //将HEAD指向<commit ID>所在位置,本地的修改(即<commit ID>位置之前的修改)回退到工作目录
以上 hard/soft/mixed 是reset命令常用的三模式,默认是mixed。除此之外还有merge和keep两种模式,但是不常用,感兴趣的可以去了解下。
git branch
$ git branch <自定义分支名> //新建一个分支
$ git branch -d <自定义分支名> //删除新建的分支
切换到新分支用 checkout 命令即可
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。