Git原理解析
git add/commit原理
git项目
新建git-demo项目
git init git-demo
vim 1.txt
git status
打开新的终端页面 观察git文件变化
ls -la # a 显示包含隐藏文件的信息
安装tree、watch 工具 观察git目录的变化
brew install tree
brew install watch
如果安装报错, 用brew单独下载依赖包,就避免了找不到依赖版本的错误
brew install ncurses
brew install watch
# 0.5更新一次 git目录信息 以树形结构展示
watch -n .5 tree .git
添加1.txt文件到本地暂存区 发现git目录下多了 ojbects文件
git add 1.txt
# 查看文件类型
git cat-file -t 1cc0
blob
# 查看文件内容
git cat-file -p 1cc0
11111
# 提交文件
git commit -m 'first commit'
提交后发现多了两个文件信息:6790 、bd40
查看6790 可以发现 6790 文件记录着 提交的文件信息
查看bd40 可以发现 bd40 文件记录着 提交的备注和提交作者的信息
commit演示
# 输入和 1.txt一致的文本内容
vim 2.txt
观察git文件 并没有创建新的object
信息 。因为git创建hash值的时候只会比较文件内容,如果内容是一致的,就不会再创建新的
重新创建3.txt 保证文件内容不一致,可以发现git里面新建立了c179的对象信息
提交新的commit 发现git创建了新的文件记录修改的文本和commit信息
# 查看git提交记录
git log
查看提交记录可以发现 git里面记录了每次提交的文件信息 通过指针关联
显示版本提交的文件差异信息 发现be97
的提交版本 存在parent bd40
git show --pretty=raw 60b0
原理总结
通过上面的演示可以发现 git对象存在3个文件信息
commit
: 作者、提交信息、上次提交指针Tree
:一个指向文件名、内容和其他tree的指针Blob
: 原始数据
修改了文件内容后通过Hash算法比较出文件内容被修改, git add会创建一个新的Blob文件,里面记录着修改的文件信息。
git commit 之后会创建新的两个文件信息 Tree 和 commit 。通过指针的方式改变文件的指向。提交或回滚只是修改指针指向的文件信息,这样操作就非常快捷方便 也不用记录大量的未修改的文件信息。
git分支原理
# 创建dev分支
cat .git/refs/heads/master
git switch -c dev
cat .git/refs/heads/dev
# 新的提交记录
vim 4.txt
git add 4.txt
git commit -m '3rd commit'
# 查看提交信息
git log --oneline --graph
* 1da8793 (HEAD -> dev) 3rd commit
* 60b075d (master) seconde commit
* bd40b0f first commit
可以发现新建一个分支的的开销非常小 只是创建了一个新的指针指向了当前的commit 信息。关联的tree文件记录了这个分支下的所有文件 tree结构信息。
而SVN创建分支时会把所有文件都复制一遍 非常消耗性能和内存。
合并分支代码 两个分支指向了同一个commit文件信息 Fast-forward
模式表明两个分支没有任何冲突
git switch master
git merge dev
图解分支合并
合并之前 两个分支指向的commit指针不一致
git merge dev
之后 如果没有发生冲突
no-fast-forward
模式: 如果两个分支修改了同一个文件。 但是没有修改同一行 就会存在同一个指针指向两个不同的文件信息,,然后将master分支的指针移动到3f72b
merge conflicts
: 合并冲突之后 需要修改冲突文件并重新提交之后才会创建新的指针指向分支信息,然后将master分支的指针移动到3f72b