git原理探索实验1——git的三种对象

2023-11-10

背景知识

git的三个区域

  • working directory
    • 也就是你当前所能操作的那些目录和文件
  • history
    • 你所提交的所有记录,文件历史内容等等。git是个分布式版本管理系统,在你本地有项目的所有历史提交记录;文件历史记录;提交日志等等
  • stage(index)
    • 暂存区域
    • 本质上是个文件,也就是.git/index

git的三类对象及其关系

  • commit对象
    • 用于表示一个提交
    • commit对象之间会组织成一棵树的结构
    • 每一次提交都会产生一个commit对象
    • 除了第一次提交产生的commit对象,其它的commit对象都会有父亲commit对象
    • 如果只是提交操作,则父亲节点只有1个
    • 如果是merge操作,则父亲节点会有2个
    • commit对象包含的信息有
      • parent,父亲提交对象
      • tree, 根目录树对象
      • author,作者
      • committer,提交者
  • tree对象
    • 用于表示一个目录
  • blob对象
    • 用于表示一个文件
    • tree和blob对象可以看成是git内部采用的文件系统对象
    • 其组织结构和文件系统是很像的,很好理解
  • 这些对象都保存在.git/objects/目录下,每一个对象都会生成1个40位的哈希值,前2位作为文件夹,后38位作为文件名
  • 不同名,相同内容的文件,其哈希值相同,其blob对象也是共用的

实验1

$ git init test
Initialized empty Git repository in C:/Users/MilesGO/Desktop/git/test/.git/
$ cd test
$ find .git/objects -type f

此时由于没有任何的提交记录, find .git/objects -type f指令的返回结果为空,这条指令会列出.git/objects目录下的所有文件
接下来在根目录下创建一个README文件,文件内容hello git

$ echo 'hello git' >> README
find .git/objects -type f

返回结果仍然为空,说明在工作区域做出的改变,如果没有提交到暂存区或历史版本库,是不会产生任何的git对象的

git add README
$ find .git/objects -type f
.git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
$ git cat-file -t 8d0e4123
blob
$ git cat-file -p 8d0e4123
hello git

git cat-file -t指令可以查看一个git对象的类型,git cat-file -p指令可以查看一个git对象的内容
我们将README文件添加到暂存区之后,生成了一个blob文件,对应了暂存区中的README,其内容就是我们刚刚添加的hello git
接下来我们将暂存区的README提交

$ git commit -m 'add README'
[master (root-commit) 29c0715] add README
 1 file changed, 1 insertion(+)
 create mode 100644 README

$ find .git/objects -type f
.git/objects/28/324fe5bad6e397de7a37aa7d8c94b6bf176b83
.git/objects/29/c07152991c7b3ee41f9cb5ac1eff1f26610665
.git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f

$ git cat-file -t 28324fe5
tree

$ git cat-file -t 29c07152
commit

可以看到新生成了1个commit对象和一个tree对象,分别查看这两个对象的内容

$ git cat-file -p 29c07152
tree 28324fe5bad6e397de7a37aa7d8c94b6bf176b83
author MilesGO <164173218@qq.com> 1560070361 +0800
committer MilesGO <164173218@qq.com> 1560070361 +0800

add README

commit对象表明了其对应的根目录tree为28324f,也就是刚才新生成的tree对象

$ git cat-file -p 28324f
100644 blob 8d0e41234f24b6da002d962a26c2495ea16a425f    README

这个tree对象中只包含了一个blob对象8d0e41,也就是一开始我们添加的README文件

实验2

在实验1的基础上继续进行
在README文件中添加hello git again,commit后查看git对象情况

$ echo 'hello git again' >> README
$ git add README
$ git commit -m 'modify README'
[master 4a1d754] modify README
 1 file changed, 1 insertion(+)

$ find .git/objects -type f
.git/objects/28/324fe5bad6e397de7a37aa7d8c94b6bf176b83
.git/objects/29/c07152991c7b3ee41f9cb5ac1eff1f26610665
.git/objects/4a/1d75425a4cd5c3e206a4c69415c59802175039
.git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
.git/objects/b9/641c1bd3e89e43cfaebf63305fc0a655635b50
.git/objects/f8/3422c24917dcb2c2f781c08d83ac2fbc363dd2

$ git cat-file -t 4a1d75
commit
$ git cat-file -t b9641c
tree
$ git cat-file -t f83422
blob

分别新增了1个commit,1个tree和1个blob对象

$ git cat-file -p 4a1d75
tree b9641c1bd3e89e43cfaebf63305fc0a655635b50
parent 29c07152991c7b3ee41f9cb5ac1eff1f26610665
author MilesGO <164173218@qq.com> 1560070808 +0800
committer MilesGO <164173218@qq.com> 1560070808 +0800

modify README

新的提交必然需要生成1个新的提交对象,其tree根目录对象为b9641c,也是新生成的,其parent对象为29c071,也就是第一次提交生成的提交对象

$ 100644 blob f83422c24917dcb2c2f781c08d83ac2fbc363dd2    README
$ git cat-file -p b9641c

新生成的tree对象中,包含1条blob对象的信息

$ git cat-file -p f83422
hello git
hello git again

该blob对象也就是我们刚才修改后提交的README
到此为止,一共有2个commit对象,2个tree对象,2个blob对象

实验3

创建src目录,在src目录下添加main.cpp,添加一些内容

$ mkdir src
$ echo 'hello world' >> src/main.cpp
$ git add --a
$ git commit -m 'add src/main.cpp'
[master 12c2c80] add src/main.cpp
 1 file changed, 1 insertion(+)
 create mode 100644 src/main.cpp

$ find .git/objects -type f
.git/objects/12/c2c80788dcd74a1cd739157c0a1011514d36b2
.git/objects/28/324fe5bad6e397de7a37aa7d8c94b6bf176b83
.git/objects/29/c07152991c7b3ee41f9cb5ac1eff1f26610665
.git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad
.git/objects/3f/68ce3f72d2ee5bec285180c6fb0aa3a7eee4ff
.git/objects/4a/1d75425a4cd5c3e206a4c69415c59802175039
.git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
.git/objects/b9/641c1bd3e89e43cfaebf63305fc0a655635b50
.git/objects/c5/fb7c2c039f5f48bf89f922267016e8702bead8
.git/objects/f8/3422c24917dcb2c2f781c08d83ac2fbc363dd2

新添加的对象有

12c2c8
3b18e5
3f68ce
c5fb7c

查看这些新添加的对象

$ git cat-file -t 12c2c8
commit
$ git cat-file -p 12c2c8
tree 3f68ce3f72d2ee5bec285180c6fb0aa3a7eee4ff
parent 4a1d75425a4cd5c3e206a4c69415c59802175039
author MilesGO <164173218@qq.com> 1560071508 +0800
committer MilesGO <164173218@qq.com> 1560071508 +0800

add src/main.cpp

$ git cat-file -t 3b18e5
blob
$ git cat-file -p 3b18e5
hello world

$ git cat-file -t 3f68ce
tree
$ git cat-file -p 3f68ce
100644 blob f83422c24917dcb2c2f781c08d83ac2fbc363dd2    README
040000 tree c5fb7c2c039f5f48bf89f922267016e8702bead8    src

$ git cat-file -t c5fb7c
tree
$ git cat-file -p c5fb7c
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    main.cpp

实验4

不同文件名,相同文件内容

$ echo 'hello world' >> main2.cpp
$ git add main2.cpp
$ git commit -m 'add main2.cpp'
[master 314b549] add main2.cpp
 1 file changed, 1 insertion(+)
 create mode 100644 main2.cpp

在这种情况下,会新增哪些git对象呢?

$ find .git/objects -type f
.git/objects/12/c2c80788dcd74a1cd739157c0a1011514d36b2
.git/objects/28/324fe5bad6e397de7a37aa7d8c94b6bf176b83
.git/objects/29/c07152991c7b3ee41f9cb5ac1eff1f26610665
.git/objects/31/4b5494eb06a9963f4e6f97075f2354c8a15f13
.git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad
.git/objects/3e/c767e93a78c0ef5c4685eace73192bf6bc6848
.git/objects/3f/68ce3f72d2ee5bec285180c6fb0aa3a7eee4ff
.git/objects/4a/1d75425a4cd5c3e206a4c69415c59802175039
.git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
.git/objects/b9/641c1bd3e89e43cfaebf63305fc0a655635b50
.git/objects/c5/fb7c2c039f5f48bf89f922267016e8702bead8
.git/objects/f8/3422c24917dcb2c2f781c08d83ac2fbc363dd2

其中314b54和3ec767是新增的

$ git cat-file -t 314b54
commit
$ git cat-file -p 314b54
tree 3ec767e93a78c0ef5c4685eace73192bf6bc6848
parent 12c2c80788dcd74a1cd739157c0a1011514d36b2
author MilesGO <164173218@qq.com> 1560072040 +0800
committer MilesGO <164173218@qq.com> 1560072040 +0800

add main2.cpp

$ git cat-file -t 3ec767
tree

$ git cat-file -p 3ec767
100644 blob f83422c24917dcb2c2f781c08d83ac2fbc363dd2    README
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    main2.cpp
040000 tree c5fb7c2c039f5f48bf89f922267016e8702bead8    src

$ git cat-file -p c5fb7c
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad    main.cpp

main2.cpp和src/main.cpp共用了同一个blob对象

git ls-files --stage可以看到暂存区所有文件及其对应的blob文件

$ git ls-files --stage
100644 f83422c24917dcb2c2f781c08d83ac2fbc363dd2 0       README
100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0       main2.cpp
100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0       src/main.cpp

从这里也可以看到main2.cpp和src/main.cpp共用了同一个blob对象

转载于:https://www.cnblogs.com/milesgo517/p/10993618.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

git原理探索实验1——git的三种对象 的相关文章

  • PHP Github Pull 脚本错误“权限被拒绝(公钥)”

    我已经设置了一个 PHP 脚本来执行 GitHub 拉取 这包含在我的 Github 文件夹中 home mysite public html github github pull php 我的服务器已经有 SSH 公钥 就像我执行git
  • 仅使用 git 存储未暂存的更改(不是 --keep-index)

    首先 我确实知道 keep index 这不是我想要的 因为它仍然隐藏着all更改 但将暂存的更改保留在工作树中 如果可能的话 我只想存储未暂存的文件 而无需再次添加所有更改git stash patch 如果您想存储索引 已暂存的内容 和
  • 使用 git 合并两个截然不同的分支?

    我有我的master分支和我的verydifferentbranch它们有相同的祖先 大约 300 次提交前 现在verydifferentbranch功能完整我想把它放在master下面branch 进行变基会导致每个补丁都有很多合并冲突
  • 如果 git 凭证管理器显示令牌,它如何安全

    I have credential helper manager core 这是 Windows 凭据管理器的新助手 我不明白如果你可以让 git 显示你的凭据 它如何安全git credential fill 重现步骤 通过执行命令确认凭
  • 如何存储和计算版本控制历史记录?

    考虑这个简单的 python 代码 它演示了一个非常简单的字典版本控制设计 def build current history current for action key value in history assert action in
  • 使用 Homebrew 安装 Git 时出现问题 [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Homebrew 升级 Git 时出现问题 https stackoverflow com questions 12362021 problems upgrading git with home
  • 无法让 TeamCity 使用默认私钥向 GitHub 进行身份验证

    我正在尝试让 TeamCity 构建我的私人 GitHub 存储库 当我显式设置密钥文件的路径时 我能够成功让我的 VCS 根通过连接测试 然而 尽管进行了大量的谷歌搜索 当我使用 默认私钥 选项时 我无法让它工作 我明白了com jcra
  • Jenkins 多分支:更改 Groovy 的工作描述

    我在詹金斯的多分支项目工作正常 但我想修改job描述 默认情况下为 完整项目名称 xxxx 以更有意义 我可以使用以下命令轻松更改构建描述currentBuild当我的变量Jenkinfile已执行 但我不知道如何修改父作业描述 我的用例是
  • 如何仅隐藏一些未提交的更改?

    我正在对 Git 存储库进行重大更改 并意识到某些更改需要向后移植到错误修复分支 我不想签入我的所有更改master因为它们还没有经过充分的测试和准备 但我确实想提取其中一些更改并将它们提交到错误修复分支 然后按原样返回到 master 我
  • Xcode - 使用 SSH 身份验证添加存储库时出现身份验证失败错误

    我正在尝试通过 Xcode gt 设置 gt 帐户添加存储库 但我被困在正确的地址上 我们的存储库地址非常简单 my domain com port project name 通过 SSH 密钥进行身份验证 有人可以帮助我了解这里发生了什么
  • 回购:找不到命令?

    我是 git 和 repo 的新手 我使用的是window 7 所以我使用cygwin 我已经从 cygwin 安装程序安装了 git 之后我尝试在 cygwin 中使用以下命令进行存储 repo init u git android gi
  • 包括来自raw.github.com的js

    我有一个 github com 演示页面 链接到https raw github com master file js https raw github com master file js这样我就不需要总是复制 js文件转移到gh pag
  • 无法使用 Git Bash 对 Visual Studio Team Services 进行身份验证

    由于身份验证失败 我无法对 Visual Studio Team Services VSTS 上的远程存储库运行任何命令 我可以通过 Visual Studio 进行拉取等操作 但只能通过 Visual Studio 不通过 Git Bas
  • Git 合并删除文件

    这是第二次发生这种情况 当我进行合并时 我后来意识到正在合并的分支中的一些文件不再位于正在合并的分支中 最新的例子是我们有一个功能分支 我一直在合并主开发分支中的更改 合并后我们丢失了很多文件 并且它们现在不存在于功能分支中 为什么会出现这
  • 中止 `git stash apply` [重复]

    这个问题在这里已经有答案了 我很遗憾应用了存储 错误的分支 我如何撤消此操作并将我的存储返回到我的存储列表 以便稍后将其应用到正确的分支 如果你还没有承诺 你应该能够git stash再次 可能与git reset HEAD first A
  • 将存储库移至另一台计算机

    我已将存储库从计算机 A 移至计算机 B 我已验证等待推送的提交仍在 B 上 但整个存储库 每个文件 均未暂存 我不想添加它们并将它们作为提交推送 因为从复制存储库到粘贴它 我没有更改每个文件 当我移动存储库时 它只有等待推送的提交 而不是
  • 使用 Git 部署时压缩 JS/CSS 文件

    我对 git 有点陌生 另外 这是我第一个自动化部署过程的项目 到目前为止 能够做到这一点真是太幸福了git push dev并上传文件 复制配置文件等 现在 当我推送到我的开发服务器时 我想缩小 JS CSS 文件 我正在考虑在服务器上安
  • 使用 Git 处理 subversion:忽略对跟踪文件的修改

    我目前正在使用 subversion 存储库 但我正在使用 git 在我的计算机上本地工作 它使工作变得更加容易 但也使 subversion 存储库中发生的一些不良行为变得非常明显 这给我带来了问题 拉取代码后 有一个有点复杂的本地构建过
  • 为什么 git 无法识别我的本地存储库?

    我刚刚回到一个我已经使用 Git 大约 6 个月的项目 看到了这个 cd d DEVELOP BlenderAe My repo root git status fatal not a git repository or any of th
  • 我可以将我的heroku git repo导入bitbucket吗?如何?

    我的笔记本电脑坏了 我需要从另一台计算机上编码 我正在使用 Heroku 我想将最新版本的代码从 Heroku 获取到另一台机器 据我了解 强烈建议使用 GitHub 或 BitBucket 获取适当的远程存储库 我决定尝试一下 BitBu

随机推荐

  • 邮件发送原理和实现

    邮件发送 拓展 MIME 多用途互联网邮件扩展类型 就是附件 1 准备工作 获取QQ邮箱权限 测试代码 package com jyw import com sun mail util MailSSLSocketFactory import
  • wifi名称可以有空格吗_是真的吗?WiFi名称后面带“5G”,网速会更快?

    要想体验快到飞起的千兆网速 感受全屋覆盖的满分信号 移动全千兆 你值得拥有 千兆5G 无论是旅途中紧急处理工作 文件 图片秒传秒下 还是在外时与家人视频问候 无卡顿低延迟 用千兆5G 网速始终快人一步 千兆宽带 品质生活从品质宽带开始 用千
  • AcWing--756. 蛇形矩阵

    输入两个整数 n 和 m 输出一个 n 行 m 列的矩阵 将数字 1 到 n m 按照回字蛇形填充至矩阵中 具体矩阵形式可参考样例 输入格式 输入共一行 包含两个整数 n 和 m 输出格式 输出满足要求的矩阵 矩阵占 n 行 每行包含 m
  • Linux——使用第三方库链接的方式——动态式

    回顾上文 122条消息 Linux使用第三方库链接的使用方式 静态式 橙予清的zzz 的博客 CSDN博客https blog csdn net weixin 69283129 article details 131414804 spm 1
  • 【qiankun】微前端在项目中的具体使用

    1 安装qiankun npm install qiankun save 2 主应用中注册和配置qiankun 在主应用的入口文件main ts中 引入qiankun的注册方法 import registerMicroApps start
  • java/php/net/python健身房管理系统设计

    本系统带文档lw万字以上 答辩PPT 查重 如果这个题目不合适 可以去我上传的资源里面找题目 找不到的话 评论留下题目 或者站内私信我 有时间看到机会给您发 系统设计 4 1 系统体系结构 健身房管理系统的结构图4 1所示
  • mysql localhost值_jdbc:mysql://localhost:3306/mysql这句话中localhost具体指什么的localhost?能修改么?在哪里配置的?...

    展开全部 jdbc mysql 是指JDBC连接方式 localhost 是指你的本机地址 3306 SQL数据库的端口 jdbc 就是你要连接的32313133353236313431303231363533e59b9ee7ad94313
  • Mysql 8.0修改密码

    1 mysql u root p 原来的密码 进入数据库中 2 show databases 3 use mysql 4 使用下面的语句修改密码 ALTER USER root localhost IDENTIFIED WITH mysql
  • 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接

    驱动程序无法通过使用安全套接字层 SSL 加密与 SQL Server 建立安全连接 错误 The server selected protocol version TLS10 is not accepted by client prefe
  • STM32初始化结构体变量时成员排序的问题

    平台 STM32F103RCT6 MDK 笔者在调试时发现 结构体不同类型成员的定义顺序对于程序运行过程中的取值可能会产生很大的BUG 开始时定义 输入参数结构体 typedef struct u8 TempRange 温度最大值 floa
  • 日期格式‘YYYY-MM-DD’中的BUG

    1 日期格式 先来看一下日期格式主要有下面三种 US style Euro style RFC 3389 Layout Format string Example US style Dec 29 2019 MM DD YYYY 12 29
  • yolo格式数据转换为coco格式

    只需要有图片和yolo格式的标签就可以转换为coco格式的标签 第一步 将yolo格式的标签 classId xCenter yCenter w h转换为coco格式 classId xMin yMim xMax yMax格式 coco的i
  • 【产品设计】电商后台系统设计--订单管理

    电商后台产品 涉及众多模块 而以商品 订单 库存 为核心模块 模块之间存在大量交互 订单较为重要 它记录了所有的交易数据 对电商公司来讲 最核心最难做的有三部分 商品 订单 库存 商品与店铺 营销 评价等相关 订单与会员 营销 支付 库存
  • C# WPF MVVM设计模式下ComboBox的数据源更新的一个问题

    C WPF MVVM设计模式下ComboBox的数据源问题 问题的出现 解决 问题的出现 我在设计一个基于C MVVM 的WPF应用 当我对MainWindow的一个ComboBox进行数据绑定时候 发现当数据源更新后 前台的ComboBo
  • BSN武汉链对接说明

    项目说明 我们项目需要把ETH合约功能迁移到国内链上来 然后基于开发成本等多方面考虑 最终选择了BSN 武汉链接入 相关的BSN文档 BSN 文档地址 对接说明 1 创建BSN帐号 注册并登录bsn官网 网址 BSN官网 点击开放联盟链 g
  • 【Qt】控件探幽——QLineEdit

    注1 本系列文章使用的Qt版本为Qt 6 3 1 注2 本系列文章常规情况下不会直接贴出源码供复制 都以图片形式展示 所有代码 自己动手写一写 记忆更深刻 本文目录 QLineEdit探幽 1 设置数据 获取数据 2 只读 readOnly
  • 2023年华为od机试Java【人气最高的店铺】

    题目 某城市有m个商店和n位市民 现在要举行一场活动 通过投票来选出最受欢迎的商店 每位市民只能投一票 他们将根据自己的喜好为指定的商店投票 然而 1号商店有一个特殊的优势 它可以给每位市民发放补贴 使他们改变投票意向 投票给1号商店 请你
  • 超级计算机是几近制,进制

    进制也就是进位计数制 是人为定义的带进位的计数方法 有不带进位的计数方法 比如原始的结绳计数法 唱票时常用的 正 字计数法 以及类似的tally mark计数 对于任何一种进制 X进制 就表示每一位置上的数运算时都是逢X进一位 十进制是逢十
  • 第 5 章 HBase 优化

    5 1 RowKey 设计 一条数据的唯一标识就是 rowkey 那么这条数据存储于哪个分区 取决于 rowkey 处于 哪个一个预分区的区间内 设计 rowkey的主要目的 就是让数据均匀的分布于所有的 region 中 在一定程度上防止
  • git原理探索实验1——git的三种对象

    背景知识 git的三个区域 working directory 也就是你当前所能操作的那些目录和文件 history 你所提交的所有记录 文件历史内容等等 git是个分布式版本管理系统 在你本地有项目的所有历史提交记录 文件历史记录 提交日