Git学习笔记
这篇Git学习笔记主要是参照廖雪峰的Git教程边学边写的。廖雪峰大神的Git教程写的非常好,简单易懂,适合新手学习。
廖雪峰的官方网站:http://www.liaoxuefeng.com/
一、Git简介
1、Git是什么?
Git是世界上最好用的分布式版本控制系统,它是“Linux之父” linus用C语言花了两周时间开发的又一个伟大的开源软件,当时主要用于Linux源码管理。2008年,GitHub网站上线之后,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。Git迅速成为最流行的分布式版本控制系统。
2、集中式vs分布式
集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
Linus一直痛恨的CVS及SVN都是集中式的版本控制系统。
分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,你在自己的电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
集中式版本控制系统 分布式版本控制系统
二、安装Git
1、Linux系统
Git诞生于Linux平台并率先服务于Linux内核,因此Linux系统自带Git,我们可以使用系统默认的版本,也可以使用源码安装最新版本。
CentOS6.6 Git版本 Ubuntu16.04 Git版本
2、Windows系统
windows版本下载地址:https://git-scm.com/download/win 下载安装之后貌似是图形化界面的,由于我这里采用Ubuntu系统练习,所以win版本就不研究了。
三、Git初始化
在安装完成之后,还需要做最后一步配置:
git config --global user.name "Your Name" git config --global user.email "email@example.com"
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config
命令的--global
参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
git init 创建版本库 (目录不存在会自动创建)
从上图中初始化信息中可以看到,git init命令在工作区中创建了隐藏目录.git,这个隐藏目录就是Git的版本库(里面的东西不能随便乱改)。
把文件添加到版本库
编写一个readme.txt
文件,内容如下:
Git is a version control system. Git is free software.
readme.txt文件一定要放到learngit
目录下(子目录也可以),因为这是一个Git仓库,放到其他地方Git就找不到了。
1、git add 把文件添加到仓库
2、git commit 把文件提交到仓库:
git commit命令,-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
返回的输出信息中,master是这次提交的分支,且是该分支的第一个提交(root-commit,后面再次提交就没有这个提示了), 提交的id为 e09b1a6 .
四、时光穿梭机
1、前奏
修改readme.txt文件的内容:
Git is a distributed version control system.
Git is free software.
现在运行 git status命令查看结果:
git status
命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。
如果想要查看修改了什么内容,可以使用 git diff
git diff
顾名思义就是查看difference,显示的格式正是Unix通用的diff格式,可以从上面的命令输出看到,我们在第一行添加了一个“distributed”单词。
修改之后还要提交到仓库:
2、版本回退
当文件经过多次修改之后,我们可能记不住改了哪些内容,这时可以使用 git log命令查看:
git log
命令显示从最近到最远的提交日志,我们可以看到4次提交,最近的一次是append GPL
,上一次是add distributed
,最早的一次是wrote a readme file
。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline
参数:
把readme.txt回退到上一个版本,也就是“add distributed”的那个版本:
git reset --hard HEAD^ 回退到上一个版本
git reset --hard c7bb35ce 回退到指定版本
在Git中,用HEAD
表示当前版本,也就是最新的提交,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD
指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL!
Git提供了一个命令git reflog
用来记录每一次操作:
3、工作区和暂存区
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
工作区(Working Directory):
我们在电脑里能看到的目录,比如我的learngit
文件夹就是一个工作区。
版本库(Repository)
工作区有一个隐藏目录.git
,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master
分支,所以,现在,git commit
就是往master
分支上提交更改。
4、管理修改
之所以说Git比其他版本控制系统设计得优秀,是因为Git跟踪并管理的是修改,而非文件。
比如说你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。
每次修改文件,如果不add
到暂存区,就不会加入到commit
中。
5、撤销修改
撤销修改用git checkout -- file
这里分为两种情况:
一种是readme.txt
自修改后还没有被放到暂存区,现在,撤销修改就回到和工作区一模一样的状态;
一种是readme.txt
已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit
或git add
时的状态。
git checkout -- file
命令中的--
很重要,没有--
,就变成了“切换到另一个分支”的命令,在下面的分支管理中会再次遇到git checkout
命令。
如果文件已经add到暂存区但还没有commit,我们可以用命令git reset HEAD file
把暂存区的修改撤销掉(unstage),重新放回工作区。然后再用git checkout撤销修改。git reset
命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD
时,表示最新的版本。
总结撤销修改的几种情况:
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file
,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
6、删除文件
在Git中,删除也是一个修改操作,如果你用rm把文件删了,git知道你删了文件,工作区和版本库就不一致了,git status
命令会立刻告诉你哪些文件被删除了:
现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm
删掉,并且git commit
:
现在,文件就从版本库中被删除了。
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
git checkout -- test.txt
git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
五、远程仓库
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。而且每台机器的版本库其实都是一样的,并没有主次之分。
下面以github作为远程仓库练习操作。
首先注册GitHub账号。由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:
1、创建SSH Key
ssh-keygen -t rsa -C "youremail@example.com" # 邮件名为github注册的邮箱帐号
2、第2步:登陆GitHub,打开“Settings”页面:
然后,点“SSH and GPG Keys”,填上任意Title,在Key文本框里粘贴id_rsa.pub
文件的内容,添加完成之后就可以看到已经添加的Key。
友情提示,在GitHub上免费托管的Git仓库,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放进去。
添加远程库
在github创建一个learngit仓库,与本地仓库进行远程同步。
目前,在GitHub上的这个learngit
仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
现在,我们根据GitHub的提示,在本地的learngit
仓库下运行命令:
添加后,远程库的名字就是origin
,这是Git默认的叫法,也可以改成别的,但是origin
这个名字一看就知道是远程库。
下一步,就可以把本地库的所有内容推送到远程库上:
把本地库的内容推送到远程,用git push
命令,实际上是把当前分支master
推送到远程。
由于远程库是空的,我们第一次推送master
分支时,加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令。
推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样:
从现在起,只要本地作了提交,就可以通过命令:
git push origin master
把本地master
分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!
分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!
从远程库克隆
这节我们先创建远程库,然后,从远程库克隆到本地。
1、首先在github创建一个新的仓库gitskills:
2、现在,远程库已经准备好了,下一步是用命令git clone
克隆一个本地库: