Github入门2 - 底层的3种对象与3个区域

[原文链接:Link] 转载请注明原作者


🔖Git学习路线

  • 三个对象,三个区域,此外还有三个状态
    (并且通过它们来了解 git 系统的CURD操作)
🏔️3 Git Objects
  • Blob => Tree => Commit (极其重要)
🏔️3 Git Areas
  • Working Directory => Stage \ Index => Commit History
  • Working Area => Staging Area => Git Directory \ Repository (Repo)
  • 本地工作区 => 暂存区 => 历史记录区 \ 版本库

(以上所有叫法均可。但如上三个区域不包含本地文件工作目录,它和 git 的三个区域相互独立,是个沙箱环境)

  • 👌三区域关系图
    三区域关系
    2020年新版 git 已将撤销功能重命名为“$ git restore”
    而不是 “$ git checkout” 和 “$ git reset”
    详情见本文第四章
🏔️3 Git Status
  • unmodified (clear), modifiedstagedcommitted
  • 未修改 (干净的)已修改已暂存已提交
    (主要是后三个状态常常被关注,clear 代表自上次 commit 后未做其它更改)
🏔️2 File Status

上部分中,4个状态仅属于 git 部分,是 git 对象的状态,而非本地工作目录(File Directory) 的文件状态。
在本地目录中,每个文件仅可有两种状态之一,已跟踪 tracked未跟踪 untracked

  • 其中,已跟踪的本地文件才可以具有 Git 上述的状态之一
  • 查看文件跟踪状态的指令:
    • $ git status

如图,表示一个文件在 git 系统中的生命周期。 (Reference: Link)
文件生命周期


  • 额外内容
  • .git 目录结构 (由 $ git init 创建,该目录中的文件不要手动更改或删除。要在 Git Bash 让 git 自己去处理,不然极易崩溃)
    • hooks:
    • info:
    • logs:
    • objects: 存对象 (hash-object) 的数据库 (也就是版本库,本地Repo)
    • refs:
    • COMMIT_EDITMSG:
    • config:
    • description:
    • FETCH_HEAD:
    • HEAD:
    • index: 当前暂存区内容

🍻Git 三大对象:

✨blob 对象
  • 🔑核心:就是个 hash-objectk-v 键值对数据库

  • 🔒代表: 单文件的一个版本,及内容

  • 📝存放:file的hash(作为数据库的key),存压缩的内容(作为数据库的value)

  • 作用区域:本地工作区

  • ➖缺陷:

    • 只有blob对象的话,仅通过它们无法知道项目总体轮廓(文件间关联) (引出 tree 对象
    • 只通过hash来确定key,数据不足,无法确定版本的先后顺序 (引出 commit 对象
  • 🔧指令控制:

    • 🧼在工作区(且在objects目录中)创建blob对象(-w)
      $ echo "test content v1" > ./file.txt
      $ git hash-object -w ./file.txt

    • 通过linux管道(pipeline)指令,在工作区直接创建blob对象(不常用):
      $ echo 'test content' | git hash-object -w --stdin
      (–stdin = STarDand INput from command)

    • 仅查看对象 hash (SHA1) 值:
      $ git hash-object ./file.txt

  • ➕补充:

    • (⚠️) 特性:blob对象不像SVN那样存差异或增量数据,而是压缩后存储全部数据。每次新增一个hash,数据库都会增大。

    • (⚠️) 自己修改完文件,若不输入 $ git hash-object -w ./file.txt, Git是不会知道你版本有更新的。当然,这个功能被 $ git add ./file.txt 封装了,但它还包含了其他功能,后续说明 [Link]。

    • (❌) 若想查看hash-object中的value,在linux命令中调用cat指令,如:

      $ cat ./.git/objects/d6/5490dsn2ud3b2uf87f2b

        该指令只能看到被压缩后的value (加密文件内容) 
      
    • (✔️) 所以若想查看解压后(解码后)的object content,需要使用如下命令:

      $ git cat-file -p d65490dsn2ud3b2uf87f2b

    • (✔️) 若想查看一个object的类型 (是blob,tree,还是commit类),则使用如下命令:

      $ git cat-file -t d65490dsn2ud3b2uf87f2b

      *(其中hash值并不需要写全部,也可以匹配到)*
      
✨tree 对象
  • 🔑核心:用指针来关联各个相关objects (blobs, or sub-trees) 的key (SHA-1 hash),从而构建一个版本的轮廓

  • 🔒代表: 该项目的一个版本 也就是项目的轮廓,或快照

  • 📝存放:存tree的hash,存file的index

  • 作用区域:暂存区

  • ➖缺陷:仅存下了项目轮廓及文件关系,单不知是谁,什么时候,因为什么,种的树(引出 commit 对象

  • ➕补充:

    • tree 对象可以指向(含有)另一个tree对象(sub-tree),或者说另一个目录。
  • 🔧指令控制:

    • 🧼查看暂存区状态

      $ git ls-files -s “s” stands for “Stage Index” Area

    • 🧼更新暂存区数据

      $ git update-index --add --cacheinfo 100644 560a3d89bf36ea10794402f6664740c284d4ae3b ./test.txt

      其中:

      • 100644 = 普通文件类型
      • 100755 = 可执行文件
      • 120000 = 符号链接

      此外,tree不同于blob在工作区的持续添加,暂存区的内容若已存在则直接覆写,如:

      $ git update-index --add --cacheinfo 100644 e1d551f2a5c0d06def7edde8ffe66c6e06f8ca6d ./test.txt

      它只会更改上述中同一条text.txt记录的hash值。

    • 🧼将暂存区内容写为一个 Tree 对象

      $ git write-tree

      (且存入 objects 目录中,并返回 tree 对象的 hash)

    • 🧼查看 Tree 对象内容

      $ git cat-file -p 5f5087577ca62d5dbed59ffcaf5f4ad7bd5e1b3e

    • 🧼读取一个 sub-tree 到暂存区

      $ git read-tree 5f5087577ca62d5dbed59ffcaf5f4ad7bd5e1b3e

      (从hash key读取一个 tree)

    • 🧼从暂存区删除一个对象 (unstage)
      $ git rm --cached test.txt

✨commit 对象
  • 🔒代表: 对 tree 进行封装, 加入几条额外描述信息而已

  • 📝存放:谁,什么时候,因为什么,是第几次,种了哪个树

  • 🔧指令控制:

    • 🧼初次创建提交对象

      $ git commit-tree 5f50875 -m "first commit"

      $ echo "first commit" | git commit-tree 5f50875

      (它也会存入 objects 目录中,并返回 commit对象的 hash)

    • 🧼非初次创建提交对象 [ 需指定父级commit对象 (-p) ]

      $ git commit-tree 5f50875 -m "new commit" -p 77ca62d5d

    • 🧼查看 commit 对象内容

      $ git cat-file -p d592d5dbed59ffcaf5f4ad7bd5effcafe

      (一般是一个 tree 的 hash 带上 作者信息)


🔮Git高层命令 add 与 commit 的底层拆解

🎀 git add
  • $ git add ./test.txt 其实只是组合了如下两条底层命令!!(上述三个对象的底层控制指令而已)
    • $ git hash-object -w ./test.txt
    • $ git update-index --add --cacheinfo 100644 e1d551f2a5c0d06def7edde8ffe66c6e06f8ca6d ./test.txt

add 后,文件直接进入暂存区!从而等commit,注意这里是个组合拳!

但该操作会覆盖暂存区的旧内容!

🎀 git commit
  • $ git commit -m "new commit" 其实只是组合了如下两条底层命令!!(同理,也是个组合拳)
    • $ git write-tree
    • $ git commit-tree <当前暂存区commit对象的hash> -m "new commit" -p <父commit的hash若存在>

commit 后,文件变回 tracked 的 unmodified 状态,等待下一个版本的修改

该操作不会删除暂存区内容!

🎀 git commit -a
  • $ git commit -a -m "new commit" 其实只是组合了如下命令!!
    • $ git add <全部本地变动了但未被保存到暂存区的files> (未被跟踪的不被包括在内)
    • $ git commit -m "new commit"

🔮其他高层命令

🎀 git init
  • 也算高层命令,初始化./.git/ 目录
🎀 git status
  • 用于检查 file 区域与 git 区域的更新

!!建议在每一次commit前输入一次来检查!!

🎀 git diff
  • 用于检查 file 区域与 git 区域的更新(status的详情版,具体到文件内容)
  • 单独检查那些更新还没被暂存:
    • $ git diff
  • 检查暂存区待提交内容:
    • $ git diff --cached$ git diff --staged
🎀 git rm
  • 多样化的删除操作(一般用不上)
    • 删除文件,并更新暂存区(也是底层两条命令的组合拳)
      • $ git rm ./test.txt
    • 不删除文件,只在暂存区删除记录
      • $ git rm --cached test.txt
🎀 git mv
  • 用于文件改名,并置入暂存区
  • $ git mv ./README.txt ./README.md 相当于如下三条命令的组合拳!
    • $ mv ./README.txt ./README.md
    • $ git rm README.txt
    • $ git add README.md
🎀 git log
  • 用于查看 commit 历史记录 (这功能一般都被 IDEA 软件给实现完了)
    • $ git log
    • $ git log --oneline 简洁显示
    • $ git log --pretty=oneline 另一种简洁显示而已

🔀Git额外笔记

  • Project snapshot is a Tree

  • File is a Blob from Tree

  • Blob is a “key-value” or “hash-object” data

  • Commit is an encapsulated Tree with author information

  • Tree can have sub-tree

  • “ls” stands for “List”

  • “cd” stands for “Change Directory”


💫Git换行格式 (Line Endings)

  • LF: Line Feed (Windows 默认换行机制)
    • LF样例: \n
  • CRLF: Carriage Return Line Feed 包含回车的换行机制 (linux & git 默认换行机制)
    • CRLF样例: \r\n

😄 望这篇笔记能对你也有所帮助,若是喜欢,也不妨点一下收藏,万分感谢。

如有错误,也尽请指出。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值