Git 底层深入浅析 - 目录篇
前言
为什么要写这个呢?因为一直以来就想学习更多Git
的相关知识,然后也因为某次演讲和公司大佬的分享,所以我想把我学习到的和理解的分享给大家。如果你也想一起学习Git
,那就来和我一起学习吧!! Let's Go
😁
Note: 这个不太适合初学者,如果你想学习基础知识,请移步 Git 官网 以及你必须知道的Git
命令
前置知识
- 三个关键词: 本地仓库
(local)
, 暂存区(index or stage)
, 远程(remote)
要了解Git
底层工作机制,就要先了解它是什么?它有什么?我们先来了解一下.git
目录都有什么吧。
.git
目录
cd .git
ls -al
info
: 目录包含一个全局性排除(global exclude)
文件,用以放置那些不希望被记录在.gitignore
文件中的忽略模式(ignored patterns)
description
: 文件仅供GitWeb
程序使用,我们无需关心index
:stage
又称暂存区, 是一个索引config
:存放各种设置文档, 包含项目特有的配置选项。
cat .git/config
包括默认remote
, branch
, 个人账户等信息
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:Rain120/study-notes.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "note-template"]
remote = origin
merge = refs/heads/note-template
可以通过一下命令来查看 or
配置你的 git
信息
# 系统配置
git config --system --list
# 全局配置
git config --global --list
# 当前仓库
git config --local --list
# 打开编辑器来修改指定的配置文件; --system, --global or repository (默认)
git config -e / --edit
详见
git config --help
HEAD
:指向当前所在分支(current branch)
的指针文件路径(Hash)
,一般指向refs
下的某文件
refs
:存储指向各个分支的指针(SHA-1标识)
文件, 包括分支和标签的引用
heads
remotes
tags
hooks
:包含客户端或服务端的钩子脚本(hooks scripts)
Git Hooks
是定制化的脚本程序, 它能在特定事件发生之前或之后执行特定脚本代码功能。它分为客户端hooks
(Client-Side Hooks)
和服务端hooks
(Server-Side Hooks)
。
Client-Side Hooks
pre-commit
: 执行git commit
命令时触发,常用于代码格式化prepare-commit-msg
:commit message
编辑器启动前default commit message
创建后触发,常用于生成默认的标准化的提交说明commit-msg
: 在git commit -m message
后触发,常用于校验commit message
是否标准post-commit
: 整个git commit
完成后触发,常用于邮件通知、提醒applypatch-msg
: 执行git am
命令时触发,常用于检查命令提取出来的提交信息是否符合特定格式pre-applypatch
:git am
提取出补丁并应用于当前分支后,准备提交前触发,常用于执行测试用例或检查缓冲区代码post-applypatch
:git -am
提交后触发,常用于通知、或补丁邮件回复(此钩子不能停止git am
过程)pre-rebase
: 执行git rebase
命令时触发post-rewrite
: 执行会替换commit
的命令时触发,比如git rebase
或git commit --amend
post-checkout
: 执行git checkout
命令成功后触发,可用于生成特定文档,处理大二进制文件等post-merge
: 成功完成一次merge
行为后触发pre-push
: 执行git push
命令时触发,可用于执行测试用例pre-auto-gc
: 执行垃圾回收前触发
Server-Side Hooks
pre-receive
: 当服务端收到一个push
操作请求时触发,可用于检测push
的内容update
: 与pre-receive相似,但当一次push
想更新多个分支时,pre-receive
只执行一次,而此钩子会为每一分支都执行一次post-receive
: 当整个push
操作完成时触发,常用于服务侧同步、通知
.sample
拓展名是为了防止它们默认被执行,安装一个钩子只需要去掉.sample
拓展名即可。
相关使用,husky
commitlint
参考
logs
:存储日志的文件夹git log
能够让我们清晰的知道我们or
其他人具体每次提交都做了什么,以及精确定位到每一次代码修改。
# 最近 n 条日志
git log -n
git reflog
# log 提交时间、作者格式化
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
objects
:存放git
对象
Git
的底层存储从本质上讲是基于本地文件系统实现的 键值对型的数据库, key
对应对象内容的 hash
值, value
对应 git objects
。
git objects
分为 3
类:
commit
: 对象存储git
中的提交信息.tree
: 对象存储git
仓库中的文件元数据信息, 包括文件名及目录结构信息等.blob
: 对应的是git
仓库中的文件内容.
我们将在下节更详细的讲述 git objects.