一、什么是Git?
定义:Git是分布式版本控制系统。
1.1什么是版本控制
我们可以回想以下,在我们上学毕业要写论文或是准备一份演讲稿的时候,都会用文件去保存和管理一些文档之类的东西,当我们对一个文档进行了无数次的修改,同时为了区分保存,也绞尽脑汁想了了很多有乐趣的名字,就像下图这样!
以上是使用文件或文件夹进行版本管理,以上方式有缺点:
- 多个文件,保留所有版本时,需要将多个文件保存在本地
- 协同操作,多人协同操作时,需要将文件发来发去...
- 容易丢失,被删除意味着永远失去(有人会说,可以选择网盘,孺子可教也,但是能确定网盘安全么?!或是没网你也能下载?)
为了解决上述问题,应运而生了版本管理工具:
- VSS-- Visual Source Safe 【已经摒弃不用】
此工具是Microsoft提供的,是使用的相当普遍的工具之一,他可以与VS.net进行无缝集成,成为了独立开发人员和小型开发团队所适合的工具,基本上Window平台上开发的中小型企业,当规模较大后,其性能通常是无法忍受的,对分支与并行开发支持的比较有限。 - CVS--Concurrent Versions System
此工具是一个开源工具,与后面提到的SVN是同一个厂家:Collab.Net提供的。CVS是源于unix的版本控制工具,对于CVS的安装和使用最好对unix的系统有所了解能更容易学习,CVS的服务器管理需要进行各种命令行操作。目前,CVS的客户端有winCVS的图形化界面,服务器端也有CVSNT的版本,易用性正在提高。 - SVN --CollabNet Subversion 【集中式版本控制系统;服务端有所有版本;客户端只有一个版本】
此工具是在CVS 的基础上,由CollabNet提供开发的,也是开源工具,应用比较广泛。他修正cvs的一些局限性,适用范围同cvs,目前有一些基于SVN的第三方工具,如TortoiseSVN,是其客户端程序,使用的也相当广泛。在权限管理,分支合并等方面做的很出色,他可以与Apache集成在一起进行用户认证。不过在权限管理方面目前还没有个很好用的界面化工具,SVNManger对于已经使用SVN进行配置的项目来说,基本上是无法应用的,但对于从头开始的项目是可以的,功能比较强大,但是搭建svnManger比较麻烦。是一个跨平台的软件,支持大多数常见的操作系统。作为一个开源的版本控制系统,Subversion 管理着随时间改变的数据。 这些数据放置在一个中央资料档案库中。 这个档案库很像一个普通的文件服务器, 不过它会记住每一次文件的变动。 这样你就可以把档案恢复到旧的版本, 或是浏览文件的变动历史。Subversion 是一个通用的系统, 可用来管理任何类型的文件, 其中包括了程序源码。 - BitKeeper
是由BitMover公司提供的,BitKeeper自称是“分布式”可扩缩SCM系统。不是采用C/S结构,而是采用P2P结构来实现的,同样支持变更任务,所有变更集的操作都是原子的,与svn,cvs一致。 - GIT
Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理.Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Torvalds 开始着手开发 Git 是为了作为一种过渡方案来替代 BitKeeper,后者之前一直是 Linux 内核开发人员在全球使用的主要源代码工具。开放源码社区中的有些人觉得 BitKeeper 的许可证并不适合开放源码社区的工作,因此 Torvalds 决定着手研究许可证更为灵活的版本控制系统。尽管最初 Git 的开发是为了辅助 Linux 内核开发的过程,但是我们已经发现在很多其他自由软件项目中也使用了 Git。例如 最近就迁移到 Git 上来了,很多 Freedesktop 的项目也迁移到了 Git 上。
版本管理工具都一般包含客户端和服务端,他们的共同点是:
- 客户端(用户):本地编写内容,向服务端获取或提交内容
- 服务端(网盘):保存所有版本的文件
集中式版本控制系统 VS 分布式版本控制系统
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以每次都要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。每次提交之前,都需要先查看别人有没有修改过,如果SVN文档被修改了,你就需要先更新别人修改过的文件更新到自己的电脑上,再把自己更改的上传!如果未更新而直接提交的话就会因为库内文件比对不一致的问题而报错!!!中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。
那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
当然,Git的优势不单是不必联网这么简单,后面我们还会看到Git极其强大的分支管理,把SVN等远远抛在了后面。分布式版本控制系统除了Git外,还有很对不同的软件。这些分布式版本控制系统各有特点,但最快、最简单也最流行的依然是Git!
二、Git安装(windows下)
1、我们需要在官网上下载Windows版的Git:msysgit;官方下载地址:http://msysgit.github.io,安装选定要安装的目录(路径杜绝中文),剩下的按照默认安装即可!奉上网上搜到的GIt安装教程!大家参考着安装!可能会有版本诧异但大体无妨!
2、安装完成后,在开始菜单里找到“Git”->“Git Bash”,弹出一个类似命令行的窗口;或是在CMD命令提示符下,输入git回车可以看到很多提示,就说明Git安装成功!
3、安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "zh_book" $ git config --global user.email "zh_book@live.com" zh_book与zh_book@live.com是我测试用的用户名和Email地址,大家执行时请换成自己的。
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config
命令的--global
参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
三、创建版本库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
所以,创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录:
$ mkdir learngit $ cd learngit $ pwd pwd命令用于显示当前目录。
当然,并不是非要创建一个空目录才能进行git相关的操作,也可以是某个要管理的程序目录下,右击选择 git bash here 打开git的ide窗口操作模式,然后通过git init命令把这个目录变成Git可以管理的仓库:
$ git init
注意:执行初始化命令后,会生成一个.Git文件夹(默认为隐藏的),用于保存git相关所有信息,这个目录是Git来跟踪管理版本库的,没事一般不要随便修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
四、把文件添加到版本库
既然我们初始化了版本库,那就可以使用git来管理当前文件夹下所有文件,具体操作命令请往下看。
1、查看工作区状态及修改详细:
$ git status //查看工作区状态 $ git diff //若git status提示有文件被修改,则可执行此命令查看修改的内容
注意:执行git status命令会看到两部分,上边是文件提交的暂存区,下边是文件所在的工作区;在当前工作区,而没有提交到暂存区的文件颜色是红色的,提交到暂存区的文件是绿色的,如果工作台面是干净的话,证明所有文件已提交到仓库!
2、用命令git add告诉Git,把文件(文件夹)添加到仓库:(可以反复执行多次) --把文件修改添加到暂存区;
语法:git add 文件名 例如:我在当前git仓库的文件下创建一个readme.txt文件,里边写一些内容,然后把这个添加到暂存区 $ git add readme.txt 也可以执行$ git add . 把当前文件下的所有文件都提交到暂存区
注意点:
千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。建议你下载Notepadz++代替记事本,不但功能强大,而且免费!
3、用命令 git commit 告诉Git,把文件提交到仓库:【语法:git commit -m '自定义提交信息'】
$ git commit -m "first file readme.txt"
--把暂存区的所有内容提交到当前分支(仓库)
简单解释一下git commit
命令,-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。git commit
命令执行成功后会告诉你,1个文件被改动(我们新添加的readme.txt文件),插入了两行内容(readme.txt有两行内容)。为什么Git添加文件需要add
,commit
一共两步呢?因为commit
可以一次提交很多文件,所以你可以多次add
不同的文件。
4、其他操作命令:
git ls-tree head 查看版本(分支)中所有的文件 git ls-files -s 查看暂存区和版本中所有文件的详细信息 git ls-files 仅查看所有的文件名
五、版本回退
在上边我们既然学会了往版本库中提交文件的方法,何不防多提交几次熟练下操作!现在有个问题,我想回到你上一次提交的版本状态下,怎么办?别急咱慢慢说!
1、我们可以先看看这几次提交的历史记录,使用 git log命令!
git log
命令显示从最近到最远所有的提交日志,如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline
参数,以显示精简信息!
同时 Git 提供了一个命令git reflog
用来记录你的每一次命令!
$ git log //显示所有操作日志 $ git log --pretty=oneline //显示精简信息 $ git reflog //查看所有的命令历史
此处需要说一下:在查看日志的时候,我们发现每次提交的版本都会对应的有一大串数字和字母组成的很长的一段,这个是当前的版本号!它是一个SHA1计算出来的一个非常大的数字,用十六进制表示且唯一。每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使用可视化工具查看Git历史,就可以更清楚地看到提交历史的时间线。
2、回退版本:
首先,Git必须知道当前版本是哪个版本。在Git中,用HEAD
表示当前版本,也就是最新的提交的版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。如果我们要回退到上一个版本,就可以使用git reset
命令:
$ git reset --hard HEAD^
但是这个命令虽然可以回到上一次版本,但是如果是要回到多个之前的版本,就有些不现实。我们上边说过有他的版本号且唯一,为什么不用查到的版本号呢?这个多方便!
例如:我上一个版本号是:92dea56e57466115efab904a5f1d9adc361111e8 回滚命令:git reset --hard 92dea56e57466115efab904a5f1d9adc361111e8
所以,我们可以使用命令:git reset --hard 版本唯一ID 回退到指定的版本,可以是之后的版本。然后我们就可以查看下工作区的文件,会很神奇的发现回到了上一次的版本。荣们可以通过 git log 查看会发现最新的那个版本记录已经不见了!突然之间,我跟你提了个要求,我想再回到之初最新的那个版本上,你怎么做?是不是傻眼了,上一个版本的记录都没有了!还怎么回去?哪儿有卖后悔药的?
别担心,还真有卖后悔药的,身边最近的,git就提供了一个方法!上边不是说过有个 git reflog 方法可以查看所有操作命令记录,我们可以通过这条命令查到所有操作的首位都有一段字母或数字混合的一段,他就是你相关操作执行所产生的相对应的唯一版本号,找到你要回滚的版本,执行命令:git reset --head 该版本号,等执行完成查看会发现,又回到之前最新的那个版本!!
注意点:Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD
指针,当你回退版本的时候,Git仅仅是把HEAD从指向当前版本改为指向上一个版本,然后顺便把工作区的文件更新了。所以你让HEAD
指向哪个版本号,你就把当前版本定位在哪。
六、工作区与暂存区
工作区(Working Directory):就是你在电脑里能看到的目录(也就是你安装Git时初始化的目录),比如我的wheekygit文件夹就是一个工作区
版本库(Repository):工作区有一个隐藏目录“.git”,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
七、撤销和修改
1、使用git checkout命令丢弃工作区的修改,比如我误修改的CCheckBox源文件,现需要撤消,代码如下:
语法:git checkout 文件名 -----> git checkout readme.txt
命令git checkout -- file 意思就是,把file文件在工作区的修改全部撤销,这里有两种情况:
一种是file自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是file已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
2、当已将文件添加到暂存区但未提交到版本库时,可使用git reset HEAD file命令把暂存区的修改撤销掉(unstage),重新放回工作区,然后再执行上面的命令:
$ git reset HEAD ZControls/CCheckBox.cs //放回工作区 $ git checkout -- ZControls/CCheckBox.cs //撤消修改
3、若已经提交了不合适的修改到版本库时,想要撤销本次提交,可使用git reset --hard Head^命令来退回到上一版本,不过前提是没有推送到远程库。
八、删除文件
1、确实要从版本库中删除该文件,那就用命令git rm删掉,并且执行git commit命令:
$ git rm test.txt $ git commit -m "remove test.txt"
2.若误删除了文件,因为版本库里还有,所以可以使用git checkout命令把误删的文件恢复到最新版本:
$ git checkout -- test.txt
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
命令git rm
用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。