Skip to main content

Git 底层深入浅析 - 目录篇

前言

为什么要写这个呢?因为一直以来就想学习更多Git的相关知识,然后也因为某次演讲和公司大佬的分享,所以我想把我学习到的和理解的分享给大家。如果你也想一起学习Git,那就来和我一起学习吧!! Let's Go 😁

Note: 这个不太适合初学者,如果你想学习基础知识,请移步 Git 官网 以及你必须知道的Git命令

前置知识

  • 三个关键词: 本地仓库 (local), 暂存区 (index or stage), 远程 (remote)

要了解Git底层工作机制,就要先了解它是什么?它有什么?我们先来了解一下.git目录都有什么吧。

.git目录

cd .git
ls -al

_git.png

  • 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下的某文件

git-HEAD.png

git-HEAD-sourcetree.png

  • refs:存储指向各个分支的指针(SHA-1标识)文件, 包括分支和标签的引用

    git-refs.png

heads

git-refs-heads.png

remotes

git-refs-remotes.png

tags

git-tag-add.png

git-refs-tags.png

  • 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 rebasegit 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操作完成时触发,常用于服务侧同步、通知

git-hooks.png

.sample 拓展名是为了防止它们默认被执行,安装一个钩子只需要去掉 .sample拓展名即可。

相关使用,husky commitlint

参考

自定义你的工作流

Git-钩子

  • 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.

参考资料

Git - Wiki

Git 官网

A Visual Git Reference

Git 资料学习