史上最浅显易懂的 Git 教程
写在前面
讲道理,这次不是标题党。没错,就是这么猖狂。我为什么敢这么说?看完就懂了,彩蛋在文末。
Git 简介
Git 是目前世界最先进的分布式版本控制系统(没有之一)。那什么是版本控制?简单来说就是能记录文件的每次改动。那为什么有分布式一说?这里就要先说集中式版本控制系统了。
- 集中式版本控制系统
版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的东西推送给中央服务器。然而集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网还好,带宽够大,速度够快。但是在互联网上,遇到网速很慢的话,就很尴尬了。
- 分布式版本控制系统
分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在自己的电脑上。既然每个人电脑上都有一个完整的版本库,那么多个人怎么协作呢?比如说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。和集中式版本控制系统相比,分布式版本控制系统的安全性更高,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那么复制一份就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。当然,Git 的优势不单是不必联网这么简单,后面我们还会看到Git及其强大的分支管理,把SVN(一种集中式版本控制系统)等远远抛在身后。
安装 Git
现在 Git 可以在 Linux、Unix、Mac、Windows 这几大平台上正常运行了。
这里我在 Win 上操作示范。
官网下载 : https://git-for-windows.github.io
网盘下载 : http://pan.baidu.com/s/1mhB40fm
安装完之后,鼠标右键会自动添加两个 Git GUI Here 和 Git bash Here。点击 Git GUI Here 后输入命令 git 可以看到参数信息,即说明安装成功。
安装之后,还需要最后一步设置,在命令行输入 :
|
|
因为 Git 是分布式版本控制系统,所以每个机器都必须自报家门 : 你的名字和邮箱。这里需要注意 git config 命令的 –global 参数,表示你这台机器所有的 Git 仓库都会使用这个配置,当然,你也可以对某个仓库指定不同的用户名和Email地址。
创建版本库
- 创建版本库
版本库又名仓库,Repository 。可以简单地理解为一个目录,这个目录里面的所有东西都可以被 Git 管理起来,每个文件的修改、删除,Git 都能跟踪,以便在任何时刻都可以追踪历史,或者再将某个时刻还原。
右键点击 Git GUI Here 可以 点击 Creat New Repository 新建一个仓库。这里最好确保目录名不要包含中文。然后就是把这个目录变成Git 可以管理的仓库。
|
|
瞬间 Git 就把仓库创建好了,而且告诉你是一个空仓库。ls -ah 可以看到当前目录下多一个 .git 目录。
|
|
- 把文件添加到版本库
这里首先在明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如 TXT,网页,所有的程序代码等等,Git 也不例外。版本控制系统可以告诉你每次的改动,比如在第五行添加一个单词 “Omooo” ,在第八行删除一个单词“Test”。而图片这些二进制文件,虽然也能由版本控制系统管理,但是没法追踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从 100KB 改成了 200KB,但是改了啥,版本控制系统不知道,也没法知道。
不幸的是,微软的Word格式是二进制格式。因此版本控制系统没法跟踪Word文件的改动,前面我们举得例子只是为了演示,如果要真的使用版本控制系统,就要以纯文本方式编写文件。
因为文本是有编码的,比如中文常有的GBK编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
特别注意 :
千万不要使用 Windows 自带的记事本编辑任何文本文件。原因是微软开发记事本的团队在保存UTF-8编码的文件时候,会默认在文件开头添加 0xefbbbf (十六进制)的字符。建议使用Notepad++代替记事本。记得把Notepad++的默认编码设置为UTF-8 without BOM即可。
然后我们在桌面写一个 TXT 文件,因为我的仓库文件夹是放在桌面上的,所以我就把写的这个 TXT 文件也放在桌面上了。
第一步 : 用命令 git add 告诉 GIt ,把文件添加到仓库
第二步 : 用命令 git commit 告诉 Git ,把文件提交到仓库
|
|
简单解释下 git commit 命令,-m 后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的。
执行完命令之后,可以看到 Git 给我返回了信息,一个文件被改动,插入了一行内容。
当然,可以一次提交多个文件,这也就解释了要用到两步。如下 :
|
|
时光穿梭机
我们已经成功提交了一个readme.txt文件,现在我们修改readme.txt文件,修改(加一行内容)里面的内容。在运行 git status :
|
|
git status 命令可以让我们时刻掌握仓库当前的状态,上面的返回信息告诉我们,readme.txt被修改了,但是还没有提交改动。
虽然 Git 告诉我们文件被修改了,但是并没有告诉我们具体修改了什么内容,可以使用 git diff 命令查看修改了什么。
|
|
可以看到我们在第二行添加了字符串 “Omooo”,红色竖杠是我们换行的标志 。也就是说,减号是之前的版本,加号是修改之后的版本。
知道修改什么了,在提交仓库就放心多了。第一步 : git add readme.txt 在执行第二步之前使用命令 git status 看看当前仓库的状态。它会给我们反馈我们将要提交readme.txt,然后就可以放心的执行第二步了。
|
|
版本回退
现在我们已经学会了修改文件并提交到GIt版本库,我们再练习一下,在往readme.txt文件里添加第三行”love”,然后提交。
就像这样,我们不断对文件进行修改,然后不断提交修改。我们不可能每次都记住修改了什么,可以用 git log 命令查看我们提交修改的记录。
|
|
可以看到我们做了三次提交。嫌输出信息太多眼花缭乱,可以加上 –pretty=oneline 参数。
|
|
前面一段很长的字符串其实是 commit id (版本号)。是由SHA1计算出来的一个非常大的数字,用十六进制表示。为什么需要这么一大串数字呢?因为 Git 是分布式的版本控制系统,如果大家都用1,2,3等等还做为版本号,就产生冲突了。
然而有时候,我们想要回到以前的版本,怎么办呢?这里我们回到 add Omooo 那个版本。
首先,Git 必须知道当前版本是哪个版本,在 Git 中,用HEAD 表示当前版本,也就是最新提交的版本。上一个版本就是 HEAD^,上上个版本就是HEAD^^,当然往上100个版本写一百个^说不过去,所以写成了HEAD~100。
现在我们可以使用 git reset 命令还回到上一个版本。
|
|
这时候,readme.txt文件里面的内容已经修改为上个版本的内容了。在使用git log 可以看到我们最新的那个 add love 版本已经不存在了。
|
|
可是又怎么再回到那个add love版本呢?办法其实还是有的,只有上面的命令行窗口还没关闭,你就可以往上找呀找呀,找到那个 add love 的 commit id 的是fe980ea……,版本号没必要写全,Git会自动帮你找。使用命令 git reset –hard fe980ea 就可以回到那个 add love 版本了。
|
|
蛤蛤,我胡汉三又回来了。
Git 的版本回退速度很快的,因为Git 在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅只是把HEAD重定向了。
然而当命令窗口关闭了怎么办?或者说回退到某个版本后关掉了电脑,但是第二天又想恢复到新版本怎么办?找不到新版本的 commit id 怎么办?
在 Git 中,总有后悔药可吃的。Git 提供了一个命令 git reflog 用来记录你的每一次命令。
|
|
工作区和暂存区
Git 和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
- 工作区(Working Directory)
就是在电脑里能看到的目录。
- 版本库(Repository)
工作区有一个隐藏目录 .git ,这个就是 Git 的版本库。
Git 的版本库里面存了很多东西,其中最重要的就是 stage(或者叫 index) 的暂存区了,还有 Git 为我们自动创建的第一个分支 master,以及指向 master 的一个指针 HEAD 。
前面讲了我们把文件添加到Git版本仓库的时候,是分两步执行的:
第一步是用 git add 把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用 git commit 提交更改,实际上就是把暂存区所有的内容提交到当前分支。
管理修改
为什么 Git 比其他版本控制系统设计的优秀,是因为 Git 跟踪并管理的是修改,而非文件。
撤销修改
在准备提交之前,我们可以使用命令 git checkout – file 来把文件在工作区的修改全部撤销。
|
|
文件果然又复原了。
如果修改之后还 git add 到暂存区了,我们可以使用命令 git reser HEAD file 吧暂存区的修改撤销掉,然后在丢弃工作区的修改。
删除文件
我们先添加一个新文件 test.txt 到仓库中。然后使用 rm 命令 :
|
|
这时候 Git 要知道你要删除文件了,git status 命令也会告诉你要删除哪些文件了。现在有两个选择 :
- 确定要删除这个文件。 git rm 删掉后 git commit 提交。
- 删错了,可以使用命令 git checkout – test.txt 恢复到最新版本。
远程仓库
到目前为止,我们已经掌握了如何在 Git 仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了。
可是有用过集中式版本控制系统 SVN 的小伙伴们可能会站出来说,这些功能在 SVN 里面早就有了,没看出来 Git 有什么特别的地方。
没错,如果只是在一个仓库里管理文件历史,Git 和 SVN 这没有什么区别。但是,从本章开始,我们将介绍 Git 的史诗级爆炸功能。
Git 是分布式版本控制系统,同一个 Git 仓库,可以分布到不同的机器上。 那么怎么分布呢?最早,肯定只有一台机器和一个原始的版本库。此后,别的机器可以克隆这个原始库,而且每台机器的版本库其实是一样的,并没有主次之分。
你肯定会想,至少需要两台机器才能玩远程仓库不是吗?但是我只有一台,怎么玩?
其实一台电脑也是可以克隆多个版本库的,只有不在同一个目录下。不过,现实生活中是不会有人这么傻在一台机器上搞几个远程库玩,因为一台机器搞几个远程库是没有意义的,而且硬盘挂了会导致所有的库都挂掉。
实际情况下是这样的,找一台电脑充当服务器的角色,每天二十四小时开机,其他每个人都从这个服务器仓库克隆一份到自己的电脑上,并把各自的提交推送到服务器仓=仓库里,也能从服务器中拉取别人的提交。
完全可以自己搭建一个运行 Git 的服务器,不过现阶段,为了学 Git 先搭一个服务器绝对是小题大做。好在这个世界上有个叫 GitHub 的网站,他就是提供 Git 仓库托管服务的,所以只要注册一个 Github 账号,就可以免费获得 Git 远程仓库。
再继续阅读后续内容前,请自行注册 Github 账号。由于我们本地 Git仓库和 Github 仓库之间的传递是通过 SSH 加密的,所以,需要一点设置:
- 创建 SSH Key。在用户主目录下,看看有没有 ssh 目录,如果有,在看看这个目录下有没有 id_rsa 和 id_rsa.pub 这两个文件,如果有了,可以直接跳过下一步。如果没有,打开 Git Bash,创建 SSH Key:
|
|
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个 Key 也不是用于军事目的,所以也无需设置密码。
如果一切顺利的话,可以在用户主目录下找到 .ssh 目录,里面有 id_rsa 和 id_rsa.pub 两个文件,其中,id_rsa 是私钥,不能泄露出去,id_rsa.pub 是公钥,可以放心的告诉别人。
- 登录 Github ,打开 ”Account setting“,”SSH Keys“ 页面:
然后点 “Add SSH Key”,填上任意的 Title,在 Key 文本框里黏贴 id_rsa.pub 文件的内容。
最后想说
如果你看到这了,说明你耐心不错,我也是闲的无聊写的这篇博文。当然,我可没有那么厉害,所有的一切都是参考廖雪峰写的Git教程。他是在 MAC 演示的,我是从 Win 上演示的,实际上差别很小。最开始写的时候,其实就是想认真系统学一遍 Git 教程,自己动手做一遍肯定印象深刻。那为什么不继续写了呢?说出来你可能不信,六合彩中了一百万。
开个玩笑,实际上我物理机上早就装了 Github。但是为了害怕万一操作傻逼,所以就在虚拟机上进行演示了。写到远程仓库那一章,发现要注册 Github并且配置,就很烦了。当然,码了那么多字也很烦了,所以决定不再写了,想看的小伙伴可以点击 Here。