git 原理学习笔记

本文详细介绍了git的工作流程,从初始化仓库到git add生成blob对象,再到git commit创建tree和commit对象,以及git gc的差异化压缩和对象清理。通过git prune删除未被引用的垃圾对象,确保仓库高效运行。同时,讨论了如何从pack文件中解压对象回objects目录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

git init 代码仓库的初始化

git init 初始化之前文件目录没有内容,初始化之后可以看到多了个.git 文件夹,目录结构如下,可以使用 watch -n 1 -p find . 每一秒刷新一次当前目录下文件:

.
./.git
./.git/config
./.git/objects
./.git/objects/pack
./.git/objects/info
./.git/HEAD
./.git/info
./.git/info/exclude
./.git/description
./.git/hooks
./.git/hooks/commit-msg.sample
./.git/hooks/pre-rebase.sample
./.git/hooks/pre-commit.sample
./.git/hooks/applypatch-msg.sample
./.git/hooks/fsmonitor-watchman.sample
./.git/hooks/pre-receive.sample
./.git/hooks/prepare-commit-msg.sample
./.git/hooks/post-update.sample
./.git/hooks/pre-merge-commit.sample
./.git/hooks/pre-applypatch.sample
./.git/hooks/pre-push.sample
./.git/hooks/update.sample
./.git/refs
./.git/refs/heads
./.git/refs/tags

查看 .git/config 文件,默认没有 commit 的 user 信息,默认是读取电脑配置的 cat ~/.gitconfig 的 user 信息

 % cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true

git config user.name "perri"
git config user.email "fromperri@gmail.com"
可以单独设置本地的用户名和邮箱信息
git config -l #查看本地的配置信息:

 % git config -l
credential.helper=osxkeychain
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
user.name=perri
user.email=fromperri@gmail.com

git add 生成 blob Object

是自动压缩的成
待补充

git commit 生成 tree Object,commit Object

待补充

git 压缩 gc

每一次修改然后commit ,导致生成无数过压缩过的 blob 对象,但是对象的差异很小,导致浪费空间,使用 git gc 进行差异化压缩后,文件压缩到 .git/objects/pack 文件夹下,.git/objects/… 下的文件夹也消失了,只剩下 .git/objects。

% du -h .git/objects
8.0K	.git/objects/pack
8.0K	.git/objects/info
 16K	.git/objects

% tree .git/objects
.git/objects
├── info
│   ├── commit-graph
│   └── packs
└── pack
    ├── pack-e5484c07b6610675d88236739669dbaf4205e80d.idx   #内容小,存储压缩索引
    └── pack-e5484c07b6610675d88236739669dbaf4205e80d.pack #内容大,存储压缩对象

tree .git/objects 查看目录树形结构
du -h .git/objects 查看文件夹的大小
ls -lh 查看文件目录及大小
git verify-pack -v 查看 pack 内容

 % git verify-pack -v .git/objects/pack/pack-e5484c07b6610675d88236739669dbaf4205e80d.pack
41abcf3e96532c29cdfaf7af95fd147599afca12 commit 140 105 12
1d60b70ed8125fdfde9934ac0942548a25477971 blob   4 13 117
670d22a7bdea85619070e078f6118049110dfb35 tree   37 47 130
non delta: 3 objects
.git/objects/pack/pack-e5484c07b6610675d88236739669dbaf4205e80d.pack: ok

当本地和远程进行交换时候,就是压缩过后的,git clone 下来,会只有一个 pack 文件夹,没有 object

git unpack-objects 从 pack 解压到 objects

已经在 pack 文件夹的对象是不能被解压出来的,需要解压的话,先把这个文件 pack-e5484c07b6610675d88236739669dbaf4205e80d.pack 移到别的位置 .git/pack,在
将 .git/pack 解压

% git unpack-objects < .git/pack
zsh: no such file or directory: .git/pack
aratek@aratekdeMacBook-Air 0925git % git unpack-objects < .git/pack-e5484c07b6610675d88236739669dbaf4205e80d.pack
Unpacking objects: 100% (3/3), done.

解压完查看目录 tree .git/objects ,看到 objects 被解压出来了

 % tree .git/objects
.git/objects
├── 1d
│   └── 60b70ed8125fdfde9934ac0942548a25477971
├── 41
│   └── abcf3e96532c29cdfaf7af95fd147599afca12
├── 67
│   └── 0d22a7bdea85619070e078f6118049110dfb35
├── info
│   ├── commit-graph
│   └── packs
└── pack
    └── pack-e5484c07b6610675d88236739669dbaf4205e80d.idx

git 垃圾对象的清理 git prune

git gc 压缩时候不带上垃圾对象(未被引用的对象)

git prune 删除垃圾对象
git fsck 查看当前仓库垃圾对象
如果是在新分支 commit 后不合并就直接将分支删除,该分支 commit 的东西不会被当成垃圾对象删除,当想删除这部分对象,需要执行

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
-c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
-c gc.pruneExpire=now gc “$@”
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值