开始了Git的学习,主要参照[廖雪峰的Git教程],好记性不如烂笔头,学习成果形成文档,加油!
1 Git 原理简介
Git是世界上最先进的分布式版本管理系统。
1.1 集中式版本管理系统
集中式版本管理系统的特点是:有一个中央服务器,版本库存储在中央服务器上,程序员干活的时候,要先联网从中央服务器上获取到最新的版本,然后在该版本上干活,干完活之后,再把工作成果推送到服务器。中央服务器就像是一个图书馆,想要改变一本书的内容的话,就需要先从图书馆把书接到,拿回家中修改,改完之后再把修改后的书放回到图书馆。
1.2 分布式式版本管理系统
分布式版本管理系统的特点是:没有“中央服务器”,网络中的每一台电脑上都有一个完整的版本库。这样程序员干活的时候就不需要联网获得版本,因为版本库就在自己的电脑上,程序员A修改了某个文件,程序员B也同样修改了该文件,只要A、B二人将自己的修改推送给对方,那么就能看到对方在该文件上的修改了。
然而,在实际的应用中,很少在两人之间的电脑上推送版本库的修改,这是因为如果两个电脑不在同一个局域网内,或者程序员B没有开机,那么两台电脑就不能互相访问了。因此,在分布式版本管理系统中,要有一台电脑充当”连接枢纽”的作用,它的存在只是为了方便大家相互交流,没有它的话,并不会影响大家工作,只是大家相互之间交流不方便而已。有了这个“枢纽”之后,大家都把自己对版本库的修改推送到这个“枢纽”上,这样就方便了大家的交流。
2 Git初始使用
2.1 个人设置
Git安装完成之后,需要使用git config
命令对其进行初始设置:
序号 | 作用 | 命令 |
---|---|---|
1 | 设置使用者名称 | git config --global user.name "guokonghui" |
2 | 设置使用者邮箱 | git config --global user.email "[email protected]" |
3 | 开启颜色识别 | git config --global color.ui true |
在使用 git config
命令进行配置时,--global
命令表示对这台计算机上所有的 Git 仓库都使用所设置的用户名和邮箱
2.2 创建本地版本库
完成个人设置之后,就可以在自己的电脑上建立本地版本库
序号 | 作用 | 命令 |
---|---|---|
1 | 创建个人目录 | mkdir learngit |
2 | 进入创建的个人目录 | cd learngit |
3 | 将个人目录设置为可以被Git管理的版本库 | git init |
完成第3步设置之后,会在learngit
文件夹下多出一个.git
文件夹,这就表明learngit
文件夹已经成为一个被 Git 管理起来的仓库。
2.3 添加文件到版本库
建立一个readme.txt
文件,内容为:
Git is a version control system.
Git is free software.
将readme.txt
文件放在learngit
目录(或其子目录)下.
序号 | 作用 | 命令 |
---|---|---|
1 | 将文件添加到仓库 | git add readme.txt |
2 | 将添加到仓库的文件提交到仓库 | git commit -m "wrote a readme file" |
-m
参数的作用是,在其后面跟着对本次提交的说明”wrote a readme file”
Git提交文件分为两步的原因是:git commit命令可以一次提交多个文件,如下:
git add 1.txt
git add 2.txt 3.txt
git commit -m “add 3 files”
3 工作区和暂存区
工作区就是learngit
文件夹目录。
工作区中有个文件夹.git
,这个.git
文件夹不算是工作区,而是Git的版本库。
Git版本库中最重要的两个东西:一个是Stage暂存区,另一个是Git自动创建的第一个分支Master以及指向Master的指针HEAD。
git add
的作用就是把文件添加到暂存区Stage
git commit
的作用就是把暂存区Stage中的文件提交到分支Master
这两条命令的执行过程如:
1. 在learngit
文件夹中创建了readme.txt
文件,并添加了内容
2. 执行git add
3. 执行git commit
如此,工作区修改的readme.txt
文件就被传到了Git仓库。
git status
此命令用于查看当前状态,包括当前处于哪个分支、有没有内容需要add,有没有内容需要commit等等
4 管理修改
Git跟踪并管理的是修改,而非文件。比如:新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。
以实验的方式来理解Git跟踪管理的是修改而非文件
- 将readme.txt文件的内容改为:
Git is a version control system.
Git is free software.
Git tracks changes.
- 执行添加 git add
git add readme.txt
这个时候新修改的内容被添加到Stage暂存区
3. 再次修改readme.txt文件
Git is a version control system.
Git is free software.
Git tracks changes of files.
这时候修的修改只是存在于readme.txt
文件中,并没有add到暂存区
4. 执行提交 git commit
git commit -m "git tracks changes"
所以这个时候commit到Master分支的是第一次的修改。
5. 查看状态 git status
这个时候会发现上面第3步中的修改没有被提交,分析上面的操作步骤:
第一次修改——>git add——>第二次修改——> git commit
前面讲了,Git管理的是修改,当用 git add 命令后,在工作区的第一次修改被放入Stage暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以, git commit 只负责把暂存区中的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
这个时候我们可以使用下述命令来查看工作区和版本库中最新版本的区别
git diff HEAD --readme.txt
果然会发现第二次修改没有被提交。如果想要提交第二次修改,需要先将其添加( git add
)到Stage,然后在提交(git commit
)到Master。
5 删除修改
5.1 删除工作区修改
git checkout --filename
可以删除工作区修改,分为两种情况:
- 在工作区文件中做了修改
在工作区文件中做了修改1,并且
git add
到了Stage,又做了修改2,但两次修改还没有git commit
对于第一种情况:
执行git checkout --filename
之后,则抛弃工作区文件的修改,工作区文件回到上次git commit
的状态。
对于第二种情况:
执行git checkout --filename
之后,则抛弃工作区文件的修改2,工作区文件回到修改1git add
的状态。
总结:执行 git checkout --filename
之后,没有git add
的修改在文件中被抛弃,没有git commit
的修改回到该修改git add
的状态。
5.2 删除Stage暂存区修改
序号 | 作用 | 命令 |
---|---|---|
1 | 删除Stage中的修改 | git reset HEAD filename |
2 | 删除掉工作区中对应的修改 | git checkout --filename |
6 版本回退
如果修改已经被git commit
到了某个分支(比如Master
分支),那么如果要撤回本次修改,就只有进行版本回退了
回退到上一个版本
git reset --hard HEAD^
如果想要回退到某个指定版本或者前进到某个指定版本,就需要知道目标版本的commit id
号。
使用git log
命令,可以查看commit日志,即可得到commit id
号。假如目标版本的commit id
为3ed673…,那么采用下面命令即可回到目标版本
git reset --hard 3ed673
如下图所示:有一个名为HEAD
的指针,指向当前版本,版本回退时,只是将HEAD
指针指向目标版本而已。
git log
命令的拓展
序号 | 作用 | 命令 |
---|---|---|
1 | 日志按行排列 | git log --pretty=oneline |
2 | 按行排列且缩写commit id | git log --pretty=oneline --abbrev-commit |
3 | 表格形式,按行排列,缩写 | git log --graph --pretty=oneline --abbrev-commit |
7 删除文件
一般要删除某个文件,直接在目录下删除就可以了。只在文件目录中删除之后,在Git仓库中还有被删文件的commit版本。如果这个时候发现刚刚的文件删错了,那么就需要恢复这个文件:
git checkout --filename
实际上,git checkout --filename
,就是用版本库里面的commit版本替换工作区的版本。
如果真的要删除该文件,则使用
git rm filename
git commit -m “delete filename”