GIT核心命令和底层原理。

文章目录

  • 一、GIT体系介绍
    • 1.1 代码管理工具:SVN、CVS、GIT
    • 1.2 存储方式
    • 1.3 使用方式区别
    • 1.4 版本管理模式区别
  • 二、核心命令
    • 2.1 安装git 客户端安装
      • 2.1.1 Windows
      • 2.2.2 linux
    • 2.2 认识GIT的基本使用
      • 2.2.1 基本配置
      • 2.2.2 git 项目创建与克隆
      • 2.3 文件提交与推送
      • 2.4 分支管理
          • 创建分支:
          • 查看分支:
          • 删除分支:
          • 切换分支:
          • 解决冲突:
      • 2.5 远程仓库管理
      • 2.6 tag 管理
      • 2.7 日志管理(打印提交日志)
    • 2.7 管理修改
        • 命令解释`git checkout -- file`
        • 命令解释`git reset HEAD 文件`:撤回`git add`操作
        • 命令解释`git reset --hard hash值` 结合`git reflog`可去任何地方:回退`commit`版本
  • 三、git 底层原理
    • 3.1 GIT存储对像(hashMap)
      • 模拟演示git 版写入与回滚过程
    • 3.2 GIT树对像
    • 3.3 git提交对象
    • 3.4 GIT引用
    • 3.4 GITGC

GIT核心命令和底层原理。_第1张图片

一、GIT体系介绍

1.1 代码管理工具:SVN、CVS、GIT

GIT和SVN有什么区别:

  1. 存储方式不一样
  2. 使用方式不一样
  3. 管理模式不一样

1.2 存储方式

GIT把内容按元数据方式存储类似k/v数据库,而SVN是按文件(新版svn已改成元数据存储)
GIT核心命令和底层原理。_第2张图片
GIT核心命令和底层原理。_第3张图片
git hash-object -w 文件 将文件夹写入到数据库中(本地数据库.git/object
git cat-file -p Hash值 在数据库(hashmap)中根据hash值查找文件内容

保存到数据库但是还没有保存到暂存区中(类似C语言中的指针)
GIT核心命令和底层原理。_第4张图片
GIT核心命令和底层原理。_第5张图片
git add 文件 只是让本地指针跟踪到到了该文件,但是还没有写入到版本中
一旦git commit 文件 -m message 就会在文件中的refs/heads中写入该此提交(保存的是key(hash值))

GIT核心命令和底层原理。_第6张图片
SVN没用过,不清楚,听说是cp readme.md readme.md.version1的保存方式

1.3 使用方式区别

从本地把文件推送远程服务,SVN只需要commint 而GIT需要 add、commint、push 三个步骤

  • SVN基本使用过程
    GIT核心命令和底层原理。_第7张图片

  • Git基本使用过程
    GIT核心命令和底层原理。_第8张图片

git add 文件是添加到暂存区
git rm --cached 文件是从暂存区删除

//待考证 只要不push,代码都可以找回,并修改,一旦push到远程仓库就可能控制不了远程的文件了(没有权限)

1.4 版本管理模式区别

git 是一个分布式的版本管理系统,而要SVN是一个远程集中式的管理系统

集中式
GIT核心命令和底层原理。_第9张图片

分布式

GIT核心命令和底层原理。_第10张图片

二、核心命令

2.1 安装git 客户端安装

2.1.1 Windows

官方客户端
其它客户端

2.2.2 linux

$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
或者
sudo apt-get install git-core

因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。

注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

2.2 认识GIT的基本使用

2.2.1 基本配置

$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

2.2.2 git 项目创建与克隆

GIT核心命令和底层原理。_第11张图片
或者
GIT核心命令和底层原理。_第12张图片
克隆:
git clone 项目地址
GIT核心命令和底层原理。_第13张图片

2.3 文件提交与推送

完整模拟从项目添加到push 过程

  • 创建项目
  • 初始化git仓库
  • 提交文件
  • 远程关联
  • push 至远程仓库
  • 过程:init/clone add commit remote push

本地初始化GIT 仓库:

  • 基于远程仓库克隆至本地
    git clone

  • 当前目录初始化为git 本地仓库
    git init

  • 基于mvn 模板创建项目
    mvn archetype:generate

  • 将本地仓库和yuanchengck进行关联
    git remote add origin https://XX

GIT核心命令和底层原理。_第14张图片
GIT核心命令和底层原理。_第15张图片

本地添加

  • 添加指定文件至暂存区
    git add

  • 添加指定目录至暂存区
    git add

  • 添加所有
    git add -A

    git add .

  • 将指定目录及子目录移除出暂存区
    git rm --cached 文件/-r
    git rm --cached文件或者git rm --cache -r 移除还没有提交所有的文件

  • 添加勿略配置文件.gitignore

本地提交

  • 提交至本地仓库
    git commit file -m '提交评论'

  • 快捷提交至本地仓库, 提交所有 -am或者.(.代表本目录下的所有内容)
    git commit -am '快添加与提交'

  • 查看本地仓库状态
    git status
    GIT核心命令和底层原理。_第16张图片
    GIT核心命令和底层原理。_第17张图片
    远程推送

  • 设置远程分支并推送
    git push --set-upstream origin master

命令解释git push推送命令,第一次推送需要设置推送的远程分支,后面不改远程分支就不需要了。--set-upstream设置远程分支,master远程分支名称
GIT核心命令和底层原理。_第18张图片
推送不成功,说明本仓库的内容和远程仓库中的内容不一致。需要git pull

GIT核心命令和底层原理。_第19张图片
GIT核心命令和底层原理。_第20张图片
GIT核心命令和底层原理。_第21张图片
还不如直接git clone 项目地址
GIT核心命令和底层原理。_第22张图片
不用初始化,直接。
另外:
我们提交代码,有时有编译时生成的修改项并不想提交,因为每次编译都会生成不一样的东西,我们可以进行过滤,步骤如下:

  1. 在工程根目录下新建 .gitignore文件

     	vim .gitignore
    

    此处默认使用linux指令新建,需要会vim编辑器的基本用发(我也是不久前刚系统的学习了一下 )
    当然如果是其他的文本编辑器也行,如notepad++

  2. 在生成的.gitignore文件中输入你不想上传的文件,我的如下:

     *.iml
     .gradle
     /local.properties
     /.idea/workspace.xml
     /build
    

    设置完之后,下次上传之后这些目录的修改就不在版本控制范围之内了

2.4 分支管理

git branch 查看分支:-a所有分支 -av 详细信息 -avv远程仓库和本地仓库的关系
GIT核心命令和底层原理。_第23张图片

创建分支:
基于当前分支  创建一个新分支
基于远程分支  创建一个新分支
基于一个提交  创建一个新分支
基于Tag 创建一个新分支

基于当前分支
在这里插入图片描述
基于远程分支
在这里插入图片描述
基于一个提交
在这里插入图片描述

查看分支:

GIT核心命令和底层原理。_第24张图片

删除分支:

在这里插入图片描述
GIT核心命令和底层原理。_第25张图片

切换分支:

GIT核心命令和底层原理。_第26张图片

解决冲突:

GIT核心命令和底层原理。_第27张图片
当前分支一样,证明没有冲突。
本地分支修改:不push
GIT核心命令和底层原理。_第28张图片
远程修改:
在这里插入图片描述

文件冲突:
GIT核心命令和底层原理。_第29张图片
本地提交:本地分支改变,远程分支远程修改,导致不一致。
不能push
GIT核心命令和底层原理。_第30张图片
能pull
GIT核心命令和底层原理。_第31张图片
查看状态:
GIT核心命令和底层原理。_第32张图片
提示两边都修改了,需要merge。

在这里插入图片描述
在这里插入图片描述
修改为:
在这里插入图片描述
GIT核心命令和底层原理。_第33张图片
GIT核心命令和底层原理。_第34张图片
#基于当前分支新建分支
git branch
#基于提交新建分支
git branch
$ git branch -d {dev}
#切换分支
git checkout
#合并分支
git merge
#解决冲突,如果因冲突导致自动合并失败,此时 status 为mergeing 状态.
#需要手动修改后重新提交(commit)

2.5 远程仓库管理

  • 查看远程配置
    git remote [-v]
    在这里插入图片描述

  • 添加远程地址
    git remote add origin http:xxx.xxx
    GIT核心命令和底层原理。_第35张图片

  • 删除远程地址
    git remote remove origin
    在这里插入图片描述

  • 上传新分支至远程(与本地建立关联)
    git push --set-upstream origin master
    在这里插入图片描述

  • 将本地分支与远程建立关联
    git branch --track --set-upstream-to=origin/test test

2.6 tag 管理

跟分支类似,不过tag是只读的。

  • 查看当前
    git tag
    在这里插入图片描述
  • 创建分支
    git tag
    基于当前分支创建tag
    在这里插入图片描述
    基于tag创建tag
    GIT核心命令和底层原理。_第36张图片
    基于提交创建tag
    GIT核心命令和底层原理。_第37张图片
  • 删除分支
    git tag -d
    GIT核心命令和底层原理。_第38张图片

2.7 日志管理(打印提交日志)

  • 查看当前分支下所有提交日志
    git log
    GIT核心命令和底层原理。_第39张图片

  • 查看当前分支下所有提交日志
    git log {branch}
    GIT核心命令和底层原理。_第40张图片

  • 单行显示日志
    git log --oneline
    GIT核心命令和底层原理。_第41张图片

  • 比较两个分支的区别
    git log master..experiment
    后一个有多少提交没有提交到前一个
    git log master..test : test有多少提交没有提交到master
    git log test..master : master有多少提交没有提交到test
    GIT核心命令和底层原理。_第42张图片
    合并分支:合并以后无差别
    GIT核心命令和底层原理。_第43张图片

  • 以图表的方式显示提交合并网络
    git log --pretty=format:'%h %s' --graph
    GIT核心命令和底层原理。_第44张图片

  • git show 分支名:最后一次提交的详细的内容
    GIT核心命令和底层原理。_第45张图片

  • 查看文件:显示本地文件和本地仓库内部的不同
    git status命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,README.MF被修改过了,但还没有准备提交的修改。

    虽然Git告诉我们readme.txt被修改了,但如果能看看具体修改了什么内容,自然是很好的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的readme.txt,所以,需要用git diff这个命令看看:
    GIT核心命令和底层原理。_第46张图片

2.7 管理修改

  • 第一次修改 -> git add -> 第二次修改 -> git commit

  • Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

  • 提交后,用git diff HEAD -- 文件命令可以查看工作区和版本库里面最新版本的区别

  • 那怎么提交第二次修改呢?你可以继续git addgit commit,也可以别着急提交第一次修改,先git add第二次修改,再git commit,就相当于把两次修改合并后一块提交了:

  • 步骤:第一次修改 -> git add -> 第二次修改 -> git add -> git commit
    总结:每次提交都要先git add 然后在git commit

命令解释git checkout -- file

  • git checkout -- file可以丢弃工作区的修改:
    $ git checkout -- README.MF
    把本地的内容修改了,想恢复到上一次提交的内容,此时还没有添加到暂存区,没有执行git add命令。此时恢复的是上一次提交的暂存区的文件内容。
    GIT核心命令和底层原理。_第47张图片

命令解释git reset HEAD 文件:撤回git add操作

  • git reset HEAD : 回退到暂存区
    若本地文件修改了,不小心git add,就使用该命令,作用撤销git add
    若本地文件还想变回原来的文件(上一次提交的内容),则执行git checkout -- file
    若不想放弃修改,则就在本地文件继续修改,修改好了在git add即可
    GIT核心命令和底层原理。_第48张图片
    GIT核心命令和底层原理。_第49张图片

命令解释git reset --hard hash值 结合git reflog可去任何地方:回退commit版本

可以去到之前任意一个执行过的git commit的地方
GIT核心命令和底层原理。_第50张图片
GIT核心命令和底层原理。_第51张图片

  • git relog 记录每一次命令
    在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。Git提供了一个命令git reflog用来记录你的每一次命令:
    在这里插入图片描述
    GIT核心命令和底层原理。_第52张图片

  • git diff HEAD file
    查看文件修改情况
    GIT核心命令和底层原理。_第53张图片
    解释:绿色代表加入到暂存区还没有提交,红色代表还没有添加到暂存区
    简单说就是没有执行git add是红色,执行git add是绿色
    +:号代表添加的内容
    -:代表删除的内容
    黑白色的内容就是代表此时本地仓库(最后一次提交)里面的内容
    GIT核心命令和底层原理。_第54张图片
    GIT核心命令和底层原理。_第55张图片

三、git 底层原理

3.1 GIT存储对像(hashMap)

Git 是一个内容寻址文件系统,其核心部分是一个简单的键值对数据库(key-value data store),你可以向数据库中插入任意内容,它会返回一个用于取回该值的hash 键。

  • git 键值库中插入数据
    根据内容生成hash值,内容一样hash值一样。同一个操作系统的值一样的,window和Ubuntu不一样,亲自测试。
    echo 'luban is good man' | git hash-object -w --stdin
    79362d07cf264f8078b489a47132afbc73f87b9a
    在这里插入图片描述

  • 基于键获取指定内容
    git cat-file -p 79362d07cf264f8078b489a47132afbc73f87b9a
    在这里插入图片描述
    Git基于该功能 把每个文件的版本中内容都保存在数据库中,当要进行版本回滚的时候就通过其中一个键将期取回并替换。

模拟演示git 版写入与回滚过程

  • 查找所有的git 对像
    find .git/objects/ -type f
    在这里插入图片描述

  • 写入版本1
    echo 'version1' > README.MF; git hash-object -w README.MF;
    5bdcfc19f119febc749eef9a9551bc335cb965e2
    在这里插入图片描述

  • 写入版本2
    echo 'version2' > README.MF; git hash-object -w README.MF;
    df7af2c382e49245443687973ceb711b2b74cb4a
    在这里插入图片描述

  • 写入版本3
    echo 'version3' > README.MF; git hash-object -w README.MF;
    777d3c2b51e73cc9177c34d14d9b6079b7c3ae7d
    在这里插入图片描述

  • 回滚指定版本
    git cat-file -p df7af2c382e49245443687973ceb711b2b74cb4a> README.MF
    只是查了该hash值的内容,没有写入文件,顾问兼内容不败你
    在这里插入图片描述
    所以我们平常用的 git add 其实就是把修改之后的内容 插入到键值库中。当我们执行 git add README.MF 等同于执行了 git hash-object -w README.MF把文件写到数据库中。

我们解决了存储的问题,但其只能存储内容同并没有存储文件名,如果要进行回滚 怎么知道哪个内容对应哪个文件呢?接下要讲的就是树对象,它解决了文件名存储的问题 。

  • 所有指针(所有hash值)
    GIT核心命令和底层原理。_第56张图片
    在这里插入图片描述
  • 版本回滚:
    将hash值存储在README.MF文件中,实现版本回滚
    GIT核心命令和底层原理。_第57张图片

3.2 GIT树对像

树对像解决了文件名的问题,它的目的将多个文件名组织在一起,其内包含多个文件名称与其对应的Key和其它树对像的用引用,可以理解成操作系统当中的文件夹,一个文件夹包含多个文件和多个其它文件夹。

  • 查看对象类型
    git cat-file -t hash值
    在这里插入图片描述
    每一个分支当中都关联了一个树对像,他存储了当前分支下所有的文件名及对应的 key.

3.3 git提交对象

GIT核心命令和底层原理。_第58张图片
三次版本所以有三个节点
GIT核心命令和底层原理。_第59张图片

  • 少了写入数据库命令
    git hash-object -w hello.txt
    git hash-object -w hello.txt
    git hash-object -w hello.txt
    git hash-object -w hello.txt
    git hash-object -w hello.txt
    git hash-object -w hello.txt
    git hash-object -w hello.txt
    git hash-object -w hello.txt

所以这个节点在object里面没有值
GIT核心命令和底层原理。_第60张图片

  • 执行git add添加到暂存区,其实就是写入到object(数据库中Key/Value)里面去。
    git add hello.txt
    GIT核心命令和底层原理。_第61张图片
    多了一行。

GIT核心命令和底层原理。_第62张图片
已经写入了数据库中,不会重复写入数据库。
GIT核心命令和底层原理。_第63张图片
增加两个对象,一个提交对象,一个树对像。

GIT核心命令和底层原理。_第64张图片
一次提交即为当前版本的一个快照,该快照就是通过提交对像保存,其存储的内容为:一个顶级树对象、上一次提交的对像啥希、提交者用户名及邮箱、提交时间戳、提交评论。

  • 查看分支树
    git cat-file -p master^{tree}
    在这里插入图片描述
  • 查看提交生成的对象(重要)
    git cat-file -p hash值
    GIT核心命令和底层原理。_第65张图片
  • 查看树对像
    GIT核心命令和底层原理。_第66张图片
    在这里插入图片描述
    在这里插入图片描述
    通过上面的知识,我们可以推测出从修改一个文件到提交的过程总共生成了三个对像:
    一个内容对象 ==> 存储了文件内容
    一个树对像 ==> 存储了文件名及内容对像的key
    一个提交对像 ==> 存储了树对像的key 及提交评论。
    GIT核心命令和底层原理。_第67张图片
    GIT核心命令和底层原理。_第68张图片
     演示文件提交过程
  • 两次提交对象,我们选取第一个画图
    GIT核心命令和底层原理。_第69张图片
    在这里插入图片描述
  • tree是树对像,本对象是此次提交的内容
    在这里插入图片描述
  • parent是上次提交的树对像
    GIT核心命令和底层原理。_第70张图片
    GIT核心命令和底层原理。_第71张图片
    GIT核心命令和底层原理。_第72张图片

GIT核心命令和底层原理。_第73张图片

  • 在src下创建新文件,查看变化
    GIT核心命令和底层原理。_第74张图片
    GIT核心命令和底层原理。_第75张图片
  • 只显示一个parent
    GIT核心命令和底层原理。_第76张图片
  • 红颜色代表变化,黑色代表不变
    GIT核心命令和底层原理。_第77张图片

3.4 GIT引用

当我们执行 git branch {branchName}时创建了一个分支,其本质就是在git 基于指定提交创建了一个引用文件,保存在 .git\refs\heads\下。

  • 演示分支的创建
    git branch dev
    cat.git\refs\heads\dev

  • git 总共 有三种类型的引用:

  1. 分支引用
  2. 远程分支引用
  3. 标签引用(只读不写)
    GIT核心命令和底层原理。_第78张图片

3.4 GITGC

GC清理无用的引用并打包后删除

  • 创建一个本地仓库test, 创建一个readme.md文件并提交
    GIT核心命令和底层原理。_第79张图片
  • 查看对象
    GIT核心命令和底层原理。_第80张图片
  • 创建分支dec,切换分支dec创建文件并提交
    GIT核心命令和底层原理。_第81张图片
  • 查看对象和日志
    GIT核心命令和底层原理。_第82张图片
  • 切换分支master, 并删除分支dec
    GIT核心命令和底层原理。_第83张图片
  • git gc 后查看对象
    在这里插入图片描述
    tag和branch都是一个引用,文件内部存储的是hash的key。
    tag是只能读(不能操作在该对象树下的所有文件),branch是可以修改的。

你可能感兴趣的:(Git,git)