一、GIT体系概述:
大家公司是用什么工具来管理代码版本?SVN、CVS、GIT
GIT和SVN有什么区别呢?
GIT 与 svn 主要区别:
存储方式不一样
使用方式不一样
管理方式不一样
存储方式区别:GIT把内容按元数据方式存储类似k/v数据库,而SVN是按文件存储的(新版SVN已改成元数据存储)
GIT内部是有一个key/value的数据库,可以理解为一个Map,内容提交到数据库中时就会返回一个key,key是唯一的。
git init demo 创建一个git项目
cd demo 进入项目
echo "test demo" >> README.MF
git hash-object -w README.MF 把文件提交到数据库中 会返回一个key
git cat-file -p [key] 查看文件的内容
回滚的话就可以通过key把值取出来进行回滚
使用方式区别:从本地把文件推送远程服务,SVN只需要commit,而GIT需要add,commit,push三个步骤
SVN基本使用过程
从图中可以看出无论是谁开发的代码都是直接commit就提交到了SVN
GIT基本使用过程
git要提交内容的话,先要把修改的代码add进暂存区,然后commit到本地仓库,然后在push到远程仓库
版本管理模式区别git是一个分布式的版本管理系统,而SVN是一个远程集中式的版本管理系统
集中式:
当远程仓库服务挂掉了之后,本地项目就不能做任何操作了
分布式:
从图片中可以看出每个项目里都有一个本地的git仓库,因此当远程git服务挂掉之后,不会影响到本地的项目,仍然可以提交创建切换分支
本地仓库很明显是可以和我们的远程仓库做关联的,有四种传输协议支持与远程仓库进行连接(传输协议会在下一篇文章进行详细的讲解),如果网络和服务是正常的,本地仓库就可以推送拉取代码,并且git还支持本地仓库关联多个远程仓库
现在大家可以思考一下,为什么要关联多个远程仓库呢?
现在假设我们的团队有100人,而一个仓库的人员最多只能有50人,因此需要分两个仓库去供开发人员使用,如果git只能关联一个仓库,那么推送的时候就只有一个仓库开发人员能够拉取到代码
二、GIT核心命令使用
安装git 客户端安装官方客户端: httpsd://git-scm.com/downloads其它客户端:https://tortoisegit.org/download/
认识git的基本使用
git项目创建与克隆
文件提交与推送
完整模拟从项目添加到push的过程
创建项目
初始化git仓库
提交文件
远程关联
push至远程仓库
本地初始化GIT仓库:git clone
git init
mvn archetype:generate 基于mvn 模板创建项目本地添加git add
git add
git add -a 或者git add . 添加所有
git rm --cached target -r 将指定目录及子目录移除暂存区
.gitignore 添加忽略配置文件本地提交git commit -m '提交评论' 提交至本地仓库
git commit -am '快添加与提交' 快捷提交至本地仓库推送至远程git push origin <分支名称>
分支管理git branch [-avv] 查看本地分支
git branch
git branch
git checkout
git merge
如果因冲突导致自动合并失败,此时status为mergeing状态
需要手动修改后重新commit
远程仓库管理git remote [-v] 查看远程配置
git remote add origin http:xxx.xxx 添加远程地址
git remote remove origin http:xxx.xxx 删除远程地址
git branch --track --set-upstream-to = origin/test test 本地分支与远程分支建立关联
tag管理git tag 查看当前
git tag
git tag -d
日志管理git log 查看当前分支下所有提交日志
git log
git log --oneline 单行显示日志
git log master..experiment 比较两个版本的区别
三、git底层原理
GIT存储对象
GIT树对象
GIT提交对象
GIT引用
GIT存储对象(HashMap)Git 是一个内容寻址文件系统,其核心部分是一个简单的键值对数据库(key-value data store),你可以向数据库中插入任意内容,它会返回一个用于取回该值的hash 键。
echo 'luban is good man' | git hash-object -w --stdin GIT键值库中插入数据git cat-file -p 79362d07cf264f8078b489a47132afbc73f87b9a 基于键获取指定内容find .git/objects/ -type f 查找文件夹下所有的文件 在.git/objects文件夹下就是查找所有的git对象
向数据库中提交同样的代码返回的key是相同的
从图片可以看出插入到键值库的代码最后会变为git对象存储在.git/objects文件夹下模拟演示git 版写入与回滚过程find .git/objects/ -type f 查找所有的git 对像echo 'version1' > README.MF; git hash-object -w README.MF; 写入版本1echo 'version2' > README.MF; git hash-object -w README.MF; 写入版本2echo 'version3' > README.MF; git hash-object -w README.MF; 写入版本3git cat-file -p c11e96db44f7f3bc4c608aa7d7cd9ba4ab25066e > README.MF 回滚指定版本
Git基于该功能 把每个文件的版本中内容都保存在数据库中,当要进行版本回滚的时候就通过其中一个键将期取回并替换
我们平常用的 git add 其实就是把修改之后的内容 插入到键值库中。当我们执行 git add README.MF 等同于执行了 git hash-object -w README.MF 把文件写到数据库中。
我们解决了存储的问题,但其只能存储内容却并没有存储文件名,如果要进行回滚 怎么知道哪个内容对应哪个文件呢?接下来我们要说的就是树对象,它解决了文件名存储的问题 ,使我们知道存储的对象对应的是哪个文件的内容。
GIT树对象树对像解决了文件名的问题,它的目的是将多个文件名组织在一起,其内包含多个文件名称与其对应的Key和其它树对像的引用,可以理解成操作系统当中的文件夹,一个文件夹包含多个文件和多个其它文件夹。git add . 把所有修改的文件插入到键值库内,每个文件生成一个git对象存储在.git/objects下git commit -m 'first commit' 在.git/objects下会生成两个对象,一个提交对象,一个树对象git cat-file -p master^{tree} 查看树对象内容
前两个字段是文件的类型,第三个字段是key,第四个字段是生成这个git对象的文件名
提交后如果要回滚的话就是根据树对象中的文件名找到对应的key,在根据key找到对应的内容,进行回滚
上面只在项目根目录下创建了两个文件,没有文件夹包裹,所以树对象内类型只有blob,如果有文件夹包裹的话,提交之后会有一个顶级树对象,里面会包含文件名与对应的key,还会包含文件夹名与对应的子树对象的key,类似于一个链表,不过存储的并不是对象,而是对象的key与对应的文件名或文件夹名
还记得之前说的,commit之后会生成两个对象吗,一个树对象,一个提交对象,接下来我们就来看一下提交对象
GIT提交对象一次提交即为当前版本的一个快照,该快照就是通过提交对像保存,其存储的内容为:一个顶级树对象、上一次提交的对像啥希、提交者用户名及邮箱、提交时间戳、提交评论。
怎么查看提交对象的key是哪个呢?git log master 查看提交日志
第一个就是最近一次提交对象的key
里面的内容有顶级树对象的key,以及parent对象的key,也就是上一个提交对象的key
通过上面的知识,我们可以推测出从修改一个文件到提交的过程总共生成了三个对像:
一个内容对象 ==> 存储了文件内容
一个树对像 ==> 存储了文件名及内容对像的key
一个提交对像 ==> 存储了树对像的key 及提交评论。下面请大家思考一个问题:
当我们在main文件夹下新增一个文件并提交,会生成几个对象,都有哪些对象会重新生成?
首先提交一定会生成一个commit对象,新增的文件对象,由于main树对象的内容里会引用新生成文件的key等信息,所以main对象也会重新生成,导致main树对象的key改变,那么引用了这个key的src树对象也会改变,同理顶级树对象也会改变。总共生成五个对象。
现在这种项目回滚就不像单文件回滚看起来那么简单了,想要回滚到指定版本时,会先和当前版本比较顶级树对象,如果key改变了就会往下遍历,查找具体改变的文件,如上面两张图,luban.txt和README.MF没有改变所以不会回滚这两个文件,找到改变的文件,替换内容就回滚完成了
GIT引用其实像分支和tag就是git引用,当创建一个分支或者tag,就是在.git/refs/heads和tags文件夹下创建了一个文件,里面包含的是最近一次提交key,回滚操作就是把里面的key换成回滚到的版本的提交对象的key
git 总共有三种类型的引用:
分支引用
远程分支引用
标签引用