网站首页 > 技术文章 正文
通过本章节的学习,你会了解 git commit 命令背后发生的故事,以及 Git 中 tree 对象的形成原理!
一、git commit 作用
暂存区保留本次变动的文件信息,等到修改了差不多了,就要把这些信息写入本地版本库,这就相当于生成了当前项目的一个快照(snapshot),这个时候就可以使用 git commit 命令将暂存区内容添加到本地版本库中。
#查看当前文件的状态
git status
#首次commit提交
git commit -m "first commit"
经过上图对比可知,执行 git commit 命令后,会增加以下5个目录与6个文件:
- 目录:logs/、logs/refs、logs/refs/heads、objects/c3、objects/f7
- 文件:refs/heads/master、c3/b8bb102afeca86037d5b5dd89ceeb0090eae9d、f7/9198eb134e834622714656af02af5cb47d0282、logs/refs/heads/master、logs/HEAD、COMMIT_EDITMSG
以上目录或文件中,logs 目录是用来记录操作信息的,refs/heads 存储的内容是所在分支最新的 commit,COMMIT_EDITMSG 存储最后一次提交的 message。
#HEAD文件总是指向当前所在分支
cat .git/HEAD
# master 文件存储的内容是所在分支最新的 commit
cat .git/refs/heads/master
# 查看该 Git 对象的类型
git cat-file -t f79198eb
# 查看该 Git 对象存储的内容
git cat-file -p f79198eb
我们知道 .git/HEAD 总是指向当前所在分支,而且 HEAD 的值引用的是 .git/refs/heads/master 中存储的内容,但该文件存储的是一个 40 位的哈希值。通过对应的命令可知,这一串的哈希值是一个 commit 对象,且该对象存储的内容包含了tree对象、提交时间以及提交者的相关信息。
二、git commit 命令解析
由上可知,使用 git commit 会将暂存区的内容提交到本地版本库。那 git commit命令背后究竟都做了什么?
经查询得知,git commit 底层对应着两个命令:
- git write-tree:保存目录结构对象。
- git commit-tree:将目录树对象写入版本历史。
(1)git write-tree
上篇文章中保存 blob 对象的时候,只是保存单个文件,并没有记录文件之间的目录关系(哪个文件在哪里)。
#将当前的目录结构生成 Git 对象,保存在 .git/objects 目录里,对象名是哈希值
git write-tree 7fd5222177e8ffadda6437dc9cfa0630a2777673
#查看该Git对象的类型,为tree类型,表示目录结构
git cat-file -t 7fd5222177e8ffadda6437dc9cfa0630a2777673
#查看该Git对象的内容
git cat-file -p 7fd5222177e8ffadda6437dc9cfa0630a2777673
注:所谓快照,就是保存当前的目录结构,以及每个文件对应的二进制对象。
(2)、git commit-tree
#将目录结构与一些元数据一起写入版本历史
echo "first commit" | git commit-tree 1e537aea8ee1f19012f944d9d62470a8f216fd2b
#查看本次快照对象的类型,为 commit 类型
git cat-file -t 21bc287ae7597df0190d4caf26de6180448eeec5
#查看本次快照的内容
git cat-file -p 21bc287ae7597df0190d4caf26de6180448eeec5
输出结果的第一行是本次快照对应的目录树对象(tree),第二行和第三行是作者和提交人信息,最后是提交说明。
总结:
截止目前,我们一共接触到了三个 Git 对象:blob 对象、tree 对象和 commit 对象。那这三者之间有什么关系呢?可参考以下图示:
Git 提供了 git commit 命令,简化提交操作。保存进暂存区以后,只要 git commit 一个命令,就同时提交目录结构和说明,生成快照。
下篇文章内容预告
在开发软件时,可能有多人同时为同一个软件开发功能或修复 Bug,使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。几乎每一种版本控制系统都以某种形式支持分支,Git 也不例外。通过本文的学习,你会了解到 Git 分支的基本概念,分支的类型,正式进入协同开发的领域。
猜你喜欢
- 2025-01-31 Git教程 - Git 命令与操作(git基本操作命令)
- 2025-01-31 因难用饱受诟病,Git十年忠实用户:问题不在工具,在使用者
- 2025-01-31 20个 Git 命令玩转版本控制(git版本控制管理 pdf)
- 2025-01-31 同步GIT仓库的操作 -- fetch命令(git fork 同步)
- 2025-01-31 学习 Git,看这一篇就够了(git要学多久)
- 2025-01-31 idea如何更改git用户(idea修改gitlab账户)
- 2025-01-31 Git常用操作(持续更新)(git常用操作详解)
- 2025-01-31 最全的GitOps工具选型,30+款工具随你挑
- 2025-01-31 赶紧收藏这些Git命令,有了这些你就可以遨游github了!
- 2025-01-31 如何在GitLab上回退指定版本的代码?GitLab回退指定版本问题分析
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)