计算机基础(二)——Git的底层原理,reverse和reset的区别,rebase作用

目录

1、分区

2、对象

3、对象实例演示

4、branch和tag

5、reset和reverse区别

6、rebase作用

7、rebase再探究竟,rebase和merge区别


这一篇其实不属于计算机基础的,但是随着大家平时工作还有开源一些项目的版本控制的使用,使用叫多的git。
回过头来,有时在思考reverse和rebase区别,回归到底层的一些原理的时候,就有茅塞顿开的感觉了。

1、分区

首先Git有分三个区,工作区,暂存区和版本库。

2、对象

Git当中一共有3种主要的对象:blob,tree,commit


git add 多一个blob文件,repository的一个文件,内容为文件内容
git add 再多一个blob文件
git commit后 会有两个tree 一个commit
tree,存储blob对象和子tree对象,这类型的对象在Git里面代表的就是一个文件夹,而这个对象的内容就是面向它所包含的文件夹和文件的指针。
commit对象,包含了一个面向根目录tree对象的指针,而且还包含了committer的个人信息还有commit的注释。

三个对象之间关系。总结就是
commit 指向 tree 指向 tree 或者 blob

3、对象实例演示

查看对象内容可以参考官方文档,Git - git-cat-file Documentation
git cat-file --batch-check --batch-all-objects
the SHA-1, type, and size of each object is printed on stdout
sha1跟md5类似是一个摘要值,然后就是对象类型,大小
 

#查看git版本
C:\Users>git --version
git version 2.20.1.windows.1

#创建测试目录
D:\>mkdir gittest

D:\>cd gittest

#git 初始化
D:\gittest>git init
Initialized empty Git repository in D:/gittest/.git/

#创建文件index.txt
D:\gittest>echo "version 1" > index.txt

# index.txt加入暂存区
D:\gittest>git add index.txt

# 查看所有对象内容
D:\gittest> git cat-file --batch-check --batch-all-objects
6c58b76a52188643965f3a6704166e8e0424b7fe blob 13

# 查询sha-1对应的文件内容,该对象对应的内容就是index.txt内容
D:\gittest>git cat-file -p 6c58b76a52188643965f3a6704166e8e0424b7fe
"version 1"

# 创建文件index2.txt
D:\gittest>echo "version 2" > index2.txt
# index2.txt加入暂存区
D:\gittest>git add index2.txt
# 查看所有对象内容
D:\gittest> git cat-file --batch-check --batch-all-objects
6c58b76a52188643965f3a6704166e8e0424b7fe blob 13
8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 blob 13

# 查询sha-1对应的文件内容,该对象对应的内容就是index2.txt内容
D:\gittest>git cat-file -p 8231f0fdc862f06b2bd7b7bfd2f42082d3086b71
"version 2"

#创建新文件夹
D:\gittest>mkdir dir

#创建新文件夹中的新文件
D:\gittest>echo "version 1, inside" > ./dir/inside.txt
 
# inside.txt加入暂存区
D:\gittest>git add ./dir/inside.txt

# 查看所有对象内容
D:\gittest> git cat-file --batch-check --batch-all-objects
6c58b76a52188643965f3a6704166e8e0424b7fe blob 13
8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 blob 13
bf97e71de76bcff2bd8aba44710aa5e665eacb99 blob 21

# 查询sha-1对应的文件内容,该对象对应的内容就是inside.txt内容
D:\gittest>git cat-file -p bf97e71de76bcff2bd8aba44710aa5e665eacb99
"version 1, inside"

#提交到本地仓库
D:\gittest>git commit


D:\gittest> git cat-file --batch-check --batch-all-objects
39bdea2300491cc90f47551887bfe9503cd4a9d9 tree 38
6c58b76a52188643965f3a6704166e8e0424b7fe blob 13
8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 blob 13
bf97e71de76bcff2bd8aba44710aa5e665eacb99 blob 21
d5c2b878425995af5ddc5202f7058a1ff372b3f3 tree 105



D:\gittest>git commit
[master (root-commit) 629a4cf] commit 1
 3 files changed, 3 insertions(+)
 create mode 100644 dir/inside.txt
 create mode 100644 index.txt
 create mode 100644 index2.txt

# 查看所有对象内容,commit之后多了两个tree和一个commit
D:\gittest> git cat-file --batch-check --batch-all-objects
39bdea2300491cc90f47551887bfe9503cd4a9d9 tree 38
629a4cf0fdb33390ad5774b10244512e3d400407 commit 169
6c58b76a52188643965f3a6704166e8e0424b7fe blob 13
8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 blob 13
bf97e71de76bcff2bd8aba44710aa5e665eacb99 blob 21
d5c2b878425995af5ddc5202f7058a1ff372b3f3 tree 105

#查看一个commit
D:\gittest>git cat-file -p 629a4cf0fdb33390ad5774b10244512e3d400407
tree d5c2b878425995af5ddc5202f7058a1ff372b3f3
author  iaiti<xx@qq.com> 1617247696 +0800
committer  iaiti<xx@qq.com> 1617247696 +0800

# 查看其中一个tree
D:\gittest>git cat-file -p d5c2b878425995af5ddc5202f7058a1ff372b3f3
040000 tree 39bdea2300491cc90f47551887bfe9503cd4a9d9    dir
100644 blob 6c58b76a52188643965f3a6704166e8e0424b7fe    index.txt
100644 blob 8231f0fdc862f06b2bd7b7bfd2f42082d3086b71    index2.txt


# 更改文件内容
D:\gittest>echo "version 2" > index.txt

D:\gittest>git add index.txt

D:\gittest>echo "version 1 new" > index.txt

D:\gittest>git add index.txt

D:\gittest> git cat-file --batch-check --batch-all-objects
0b596a83945ca790976a10bbf005262f1cefe4cc blob 17   		(version 1 new)
39bdea2300491cc90f47551887bfe9503cd4a9d9 tree 38   		(inside.txt)
629a4cf0fdb33390ad5774b10244512e3d400407 commit 169 	(commit)
6c58b76a52188643965f3a6704166e8e0424b7fe blob 13   		(version 1)
8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 blob 13   		(version 2)
bf97e71de76bcff2bd8aba44710aa5e665eacb99 blob 21   		(version 1, inside)
d5c2b878425995af5ddc5202f7058a1ff372b3f3 tree 105  		(dir index.txt  index2.txt)

D:\gittest>git cat-file -p 0b596a83945ca790976a10bbf005262f1cefe4cc
"version 1 new"


#提交第二次
D:\gittest>git cat-file -p beaeb2b94a88d6cf03c096f667859239065d1ba8
tree 4fca214cabbc6f8c6a7243f9ea780b66ee895993
parent 629a4cf0fdb33390ad5774b10244512e3d400407
author iaiti <xx@git.com> 1617247963 +0800 
committer iaiti <git@xx.com> 1617247963 +0800

Commit 2

多次更改和提交两次后,所有对象的对应关系

4、branch和tag

branch 其实就是一个指向某个commit的指针文件,一般被存放在./.git/refs/heads里面,所以branch只是跨commit而已,按照上图所指示出来的,指向的其实就是master分支
head指向最新commit
tag相当于是静态的 branch ,被存储在./.git/refs/tags里面的文件中。它并不跟随HEAD移动。通常用于标记一个特定的commit,例如某个版本的代码,以方便checkout。

5、reset和reverse区别

reset是记录重设,有三种模式

git reset 17cf9ea15f6c63ec04f232c5cd72e0c1b3f657fd
--hard  commit记录重设,但是如果远程仓库已经commit,可以使用git push --force
--mixed commit记录重设,工作区文件修改,暂存区的记录会重置,相当于没到git add阶段,相当于撤销add
--soft   commit记录重设,工作区文件修改和暂存区的记录都会保存

三种模式总结来说就是,相当于做了版本回退,并控制文件是否回退到暂存区前

而reverse,也是回退,但是不是重置commit,而是多出一条commit ,提醒其他的开发者或者公司同事,这里有恢复操作。可以
和reset对比结合看。

问题来了,reverse还有commit,reset的话中间的commit就不见了, 我要回滚怎么操作?

git reflog记录操作,回滚回之前重置的commit记录。

D:\gittest>git ls-files --stage
100644 bf97e71de76bcff2bd8aba44710aa5e665eacb99 0       dir/inside.txt
100644 0b596a83945ca790976a10bbf005262f1cefe4cc 0       index.txt
100644 8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 0       index2.txt
D:\gittest>
D:\gittest>echo "version test index" > index.txt
D:\gittest>
D:\gittest>git ls-files --stage
100644 bf97e71de76bcff2bd8aba44710aa5e665eacb99 0       dir/inside.txt
100644 0b596a83945ca790976a10bbf005262f1cefe4cc 0       index.txt
100644 8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 0       index2.txt

D:\gittest>git add index.txt

D:\gittest>git ls-files --stage
100644 bf97e71de76bcff2bd8aba44710aa5e665eacb99 0       dir/inside.txt
100644 be06e3be42f6a2955d61750c86646b7869177f47 0       index.txt
100644 8231f0fdc862f06b2bd7b7bfd2f42082d3086b71 0       index2.txt
D:\gittest>


D:\gittest>echo "version test index" > index.txt

D:\gittest>git add index.txt

git commit -m comit3

D:\gittest>git log
commit b3a0d90be0da1862b4c82fb6beafffaf4113148e (HEAD -> master)
Author: <E8><94><A1><E5><9D><A4><E6><89><BF> <xx.com>
Date:   Thu Apr 29 19:51:51 2021 +0800

    Revert "comit3"

    This reverts commit 6fccca25df481aa1d53ad60075bb37d5e87d8593.

commit 6fccca25df481aa1d53ad60075bb37d5e87d8593
Author: <E8><94><A1><E5><9D><A4><E6><89><BF> <xx.com>
Date:   Thu Apr 29 19:51:21 2021 +0800

    comit3

6、rebase作用

变基,Git - git-rebase Documentation 可以查看相关指令信息,

git rebase -i  [startpoint]  [endpoint] 给用户交互界面进行操作

挑选变基的commit

git rebase -i 674c40b

然后移除多余的commit信息,s的话是合并前面的提交

从这里可以看到,变基可以合并我前面提交无用的记录。让整个提交的历史更加的简洁,之前有网友举例,vue作者尤雨溪就有这样的处理。

rebase分支不要使用在公共分支上。

7、rebase再探究竟,rebase和merge区别

除了合并提交信息,让其更简洁外,是不是还有其他作用,都是合并,那和merge区别是什么,需要这样思考。

假如我有一条功能分支比较久没同步线上代码,或者主分支其实多人合作合并频繁的时候,按照平时的操作都是拉一条分支,然后将master merge到自己分支

结果是这样的


而变基能让自己的一条分支形成直线,不受其他的干扰。

总结来说,merge是当前开发分支领先于要合并的分支,那就merge过去,比如开发功能和测试完毕想合并到线上,就是用merge。

如果当前分支许久没拉下来,落后master的,就用rebase,就只把当前的内容合并到自己分支上,而不用理会是什么分支合并过来的。master主分支才需要查看谁合了什么上去。

git resetrebasegit版本控制中的两个重要命令,用于管理代码提交和修改历史。 git reset命令用于将当前分支的HEAD指针移动到指定的提交,同时可选择性地修改工作目录和暂存区的文件状态。它有三种常用的模式: 1. Soft Reset:使用`git reset --soft <commit>`可以将HEAD指针移动到指定提交,但不修改工作目录和暂存区的文件。这意味着之前的提交会被撤销,但相应的更改会保留在暂存区,可以重新提交。 2. Mixed Reset:使用`git reset --mixed <commit>`是默认的reset模式,它将HEAD指针移动到指定提交,并且重置暂存区,但不修改工作目录的文件。这意味着之前的提交和相应的更改都会被撤销,并且文件状态会回到最近一次提交的状态。 3. Hard Reset:使用`git reset --hard <commit>`会彻底重置当前分支的HEAD指针、暂存区和工作目录到指定提交。这意味着之前的提交和相应的更改都会被彻底删除,请谨慎使用。 git rebase命令用于在当前分支上应用另一个分支上的提交,并将其追加到当前分支的提交历史中。它可以实现分支合并的效果,但是与git merge命令不同,rebase会修改提交历史,使得分支合并后的提交看起来更加线性和整洁。 使用`git rebase <branch>`可以将当前分支的提交应用到指定的分支上,也可以使用交互式(rebase -i)的方式对提交进行修改、合并或删除。 需要注意的是,使用git resetrebase命令都会修改提交历史,所以在公共分支上使用时要谨慎,以免影响其他开发者的工作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iaiti

赏顿早餐钱~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值