前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >git原理和技巧

git原理和技巧

作者头像
doper
发布2022-09-26 17:48:00
2840
发布2022-09-26 17:48:00
举报

git的原理和技巧

Reference: https://www.bilibili.com/video/av77252063?vd_source=97f888e70961e81952e75ac3b392a67b https://www.lzane.com/slide/git-under-the-hood/#/ https://nanxiao.me/git-object-type-note/

1. git如何存储信息

eg: 在一个目录下创建项目,使用git init初始化,并生成两个文件,使用git add添加到暂存区。

代码语言:javascript
复制
doper@doper  ~/github/project1  git init 
doper@doper  ~/github/project1   master  echo 'this is a' > a.txt 
doper@doper  ~/github/project1   master  echo 'this is b' > b.txt
doper@doper  ~/github/project1   master ✚  ls
a.txt  b.txt
image-20220703161254054
image-20220703161254054

此时使用tree打印项目目录下的./git/objects

image-20220703161412201
image-20220703161412201

使用git cat-file打印文件的信息,其中使用-t参数打印git object类型,使用-p参数打印git object具体内容

git-cat-file - Provide content or type and size information for repository objects

image-20220703161517369
image-20220703161517369

随后使用git commit提交。

image-20220703164541541
image-20220703164541541

再次使用git cat-file查看多出来的两个git object,如下

其中tree object中一次保存了文件权限,objects类型,sha1值(key),文件名

image-20220703164647501
image-20220703164647501

commit object则记录了对应的commit信息

image-20220703164745674
image-20220703164745674

分别为tree对象和commit对象及一些内容


问题1: 什么是git object,即git对象

Git 是一个内容寻址文件系统,听起来很酷。但这是什么意思呢? 这意味着,Git 的核心部分是一个简单的键值对数据库(key-value data store)。 你可以向 Git 仓库中插入任意类型的内容,它会返回一个唯一的键,通过该键可以在任意时刻再次取回该内容。

问题2:git对象有哪些类型

Reference: https://nanxiao.me/git-object-type-note/

  • Blob: git中文件的内容会被存储成blob,这里注意的是只保存内容而不是整个文件,若两个文件有相同内容则只保存一份blob。
img
img
img
img
  • Tree: git中文件夹对应保存为tree对象,他用来解决文件名保存的问题,也允许我们将多个文件组织到一起。所有内容均以树对象和数据对象的形式存储,其中树对象对应了 UNIX 中的目录项,数据对象则大致上对应了 inodes 或文件内容。 一个树对象包含了一条或多条树对象记录(tree entry),每条记录含有一个指向数据对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息。
img
img
img
img
  • Commit: Commit非常简单,只是指向了一个tree,并且包含了作者,提交者,提交信息,和所有的直属parent commit
img
img
img
img

因此我们可以通过这个目录下找到对应的commit信息,即使commit不小心被删除了也能找回来,具体可通过reflog找到对应commit的sha1值,然后创建新的分支或将分支指向这个commit的sha1完成恢复。

具体教程: https://blog.csdn.net/ShiShiLunHui/article/details/122672703

问题3:5b/e7…..,9e/36…..这些目录信息如何得到

其实这些是对git object对象(内容及meta信息)进行sha1进行哈希,得到的key,然后通过这个唯一key找到对应的git object

2. 分支和tag保存在哪

首先HEAD指针明文存储在.git/HEAD

image-20220703170506771
image-20220703170506771

分支则保存在.git/refs/heads

image-20220703170602375
image-20220703170602375
image-20220703170643643
image-20220703170643643

tag保存在.git/refs/tags

image-20220703171241111
image-20220703171241111

然后这些分支文件的内容指向了具体某个commit的SHA1哈希值

因此HEAD,分支,普通的tag都可简单理解为是一个指针,这个指针指向对应的commit类型的git objects。

image-20220703171326282
image-20220703171326282

问题: 为什么文件的权限和名字要保存tree object对象而不是blob object?

因为blob object保存的文件的内容,而若只修改文件名则需要创建新的blob object,而tree object文件大小比较小,而且节约空间

3. git操作对应的变更

img
img
img
img
img
img
img
img

Git的大部分指令就是在操作这三个分区以及这条链。

4. 小技巧

  1. 提交,分支误删除

使用reflog查看,并修改

https://blog.csdn.net/ShiShiLunHui/article/details/122672703

  1. 临时加需求,当前变动暂存

使用git stash命令,先将变动暂存起来,再下次需要时再恢复,但是遇到冲突时需要手动解决冲突

https://www.cnblogs.com/zndxall/archive/2018/09/04/9586088.html

  1. 从git提交历史中删除一个文件
image-20220703175543004
image-20220703175543004

对所有的commit应用该操作,然后再放回原来的commit中,但是这会更改所有git object的sha1哈希值,需要与其他还在使用这个项目的人沟通,不然commit的哈希值不一样会冲突

  1. rebase -i的使用

https://blog.csdn.net/the_power/article/details/104651772/

  1. revert和reset reset是直接撤销回退到上一个commit 而revert是直接创建新的commit,该commit的改动就是撤销本次commit

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3r239pw8hickk

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • git的原理和技巧
  • 1. git如何存储信息
  • 2. 分支和tag保存在哪
  • 3. git操作对应的变更
  • 4. 小技巧
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档