git部分实现原理

可以参考这篇文章
重点记一下.git的一些重要目录和文件, 比如logs,refs, objects, HEAD和index,理解它们的作用
git部分实现原理_第1张图片

文件对象存储

git是一个键值对类型的对象存储系统,存储的是文件对象blob, 目录树tree, 提交记录commit,还有commit的引用,比如tag

无论是提交到暂存区,还是提交到版本库,都是存储文件对象到.git/objects中

提交到暂存区,index文件会列出提交文件的blobs的hash
提交到版本库,.git/objects/下会新增commit文件,记录tree和其他提交信息;同时也会新增tree和blobs文件,tree会记录blobs的信息,commit文件的信息会记录到git log中。

提问:听说git是增量式存储,这是怎么实现的?
大体思想就是把文件划分为n个小块,再通过hash判断哪个小块有修改

显然,每个版本都要记录tree,但并不是每个版本都要复制所有blob

tree对象是一种简化后的目录,文件对象的目录结构也是借助tree维持的

引用

tag记录时,会在.git/refs/tags中新增tag文件,文件内容指向了commit记录

head引用
每次提交时,head引用指向当前分支的最新提交记录
切换分支和合并分支时,head引用也会自动修改
它的实现是一个.git/HEAD文件,指向了.git/refs/heads中一个引用

引用,也就是一个指向commit记录的文件,tag和HEAD,以及分支都是引用
分支引用。分支也是用引用+日志实现的,比如master分支对应 .git/refs/heads/master引用, heads目录表示可以切换的本地分支, 比如新建分支b, 那么会对应一个.git/refs/heads/b引用

git reset命令,就是将head指向一个引用的提交内容,并覆盖暂存暂存区或工作区
git reset --mixed <引用>只覆盖暂存区
git reset --hard <引用>覆盖暂存工作区和暂存区
git reset --soft <引用>只修改head指针

git checkout检出命令

  • 用于切换分支,其实是修改head引用,并将head指向提交内容覆盖暂存区和工作区
  • 用于恢复文件 其实是把index的内容对应的内容覆盖工作区
    git checkout --README
    git checkout . //将index内容覆盖全部工作区

git merge <分支引用>新增一个提交,新提交有两个parent,不修改原来的提交日志
git rebase <分支引用>将指定分支的所有提交取消(修改提交日志),并重新提交到当前分支上

关于版本控制系统的理解差不多就这样了,关键还是在使用上,要记住,想要浪一下的时候,先保存,再创建和切换分支,在新分支上可以随意动手脚

其他命令

git config … #配置
git config --list #读取配置

git status #查看工作区和暂存区状态
git diff <引用> --<文件> #对比工作区文件和引用对应的文件
git rm <文件> #从暂存区中删除文件

git remote add <远程引用> <网址> #添加远程引用
git push <本地引用> <远程引用> #推送给远程引用

git log --pretty=oneline

git tag -a v1.0 [commit id] -m “version 0.1 released”
git merge <分支引用> #合并分支和当前分支

你可能感兴趣的:(git,git,实现)