git提交到指定文件夹_Git学习(二)

本文深入探讨了Git如何保存数据,包括blob、树和提交对象,以及Git中的三棵树(HEAD、Index和Working Directory)的概念。此外,还详细介绍了Git分支的创建、切换、合并,包括快进合并、简单三方合并和有冲突的三方合并。通过实例解析了Git对象关系和工作流程,帮助理解Git的内部机制。
摘要由CSDN通过智能技术生成

b355491fdd15df8d5be2fe5e09a1b24e.png

内容概要

  1. Git保存数据的方式(Git对象)
  2. Git中三颗树含义及其操纵方式
  3. Git中分支的创建、删除与合并

参考文献

  1. Git Pro
  2. git cat-file error

1. Git保存数据的方式

我们稍微回顾一下基本的Git工作流程:

  1. 在工作目录中修改文件。
  2. 暂存文件(git add),将文件的快照放入暂存区域。
  3. 提交更新(git commit),找到暂存区域的文件,将快照永久存储到Git版本库。

当使用git add进行暂存操作时,Git会为每一个文件计算校验和(SHA-1哈希算法),然后把当前版本的文件快照保存到blob对象中并放置于Git版本库。(校验和为40位16进制数,前两位用作目录名,剩余的38位用作blob对象的文件名)。当使用git commit进行提交操作时,Git会先计算每一个子目录的校验和,然后在Git版本库中创建一个树对象,记录目录结构和blob对象索引,随后创建一个提交对象,包含指向前述对象的指针和所有提交信息。

blob对象、树对象、提交对象统称为Git对象,所有的Git对象都保存在.git/objects/ 文件夹下。

1.1 blob对象(blob object)

我们先使用git add命令创建blob对象

$ git init git-object-study
$ cd init git-object-study
$ vim hello.h
$ vim main.cpp
$ mkdir doc
$ vim doc/README.md
$ git add .

看一下.git/objects/ 文件夹下有哪些文件

$ find .git/objects -type f
.git/objects/2b/f944bf1fd5bf37bddb0a78c3a486f00260979a # main.cpp
.git/objects/d1/e804d25075a20c19e9f0ae4cf6c86b9a976c3a # hello.h
.git/objects/3a/3a9fd64de1d335ecedfcc2197d3eff85d35d55 # README.md

我们可以用git cat-file命令从Git那里取回数据。指定-p 选项可指示该命令自动判断内容的类型,并为我们显示格式友好的内容。指定-t 选项可以让Git告诉我们存储对象的类型

$ git cat-file -t  2bf944bf1fd5bf37bddb0a78c3a486f00260979a
blob
$ git cat-file -p  2bf944bf1fd5bf37bddb0a78c3a486f00260979a
#include"hello.h"

int main(){
    Greeting();
}
$ git cat-file -t  d1e804d25075a20c19e9f0ae4cf6c86b9a976c3a
blob
$ git cat-file -p  d1e804d25075a20c19e9f0ae4cf6c86b9a976c3a
#include<cstdio>

void Greeting(){
    std::printf("Hello Worldn");
}
$ git cat-file -t  3a3a9fd64de1d335ecedfcc2197d3eff85d35d55
blob
$ git cat-file -p  3a3a9fd64de1d335ecedfcc2197d3eff85d35d55
Git Object Study

到这里我们可以看出,Git可以看成是一个简单的键值对数据库,你可以像数据库插入任意内容(Git对象),它会返回一个键值(SHA-1哈希值),通过该键值可以在任意时刻再次检索该内容。

1.2 树对象(tree object)

然而,记住文件的每一个版本对应的SHA-1值并不现实;另一个问题是,目前文件名并没有被保存,我们仅仅保存了文件内容。我们接下来要探讨树对象,它能解决文件名保存的问题,也允许我们将多个文件组织到一起。

我们用git commit创建树对象和随后要探讨的提交对象

$ git commit -m 'version 1'

看一下现在有哪些Git对象

$ find .git/objects -type f
.git/objects/2b/f944bf1fd5bf37bddb0a78c3a486f00260979a
.git/objects/d1/e804d25075a20c19e9f0ae4cf6c86b9a976c3a
.git/objects/3a/3a9fd64de1d335ecedfcc2197d3eff85d35d55
.git/objects/d9/844a9f371e199dea906d384480e341a860d706
.git/objects/f0/c809f7840fb2e95306623bcc014814679f8602
.git/objects/bc/2639af17952ea4671b7e858312b5d96daa1a16

对比之前,可以看出多了三个Git对象,我们找出其中的树对象

$ git cat-file -t d9844a9f371e199dea906d384480e341a860d706
tree
$ git cat-file -t f0c809f7840fb2e95306623bcc014814679f8602
tree
$ git cat-file -t bc2639af17952ea4671b7e858312b5d96daa1a16
commit

看一下树对象的结构

$ git cat-file -p d9844a9f371e199dea906d384480e341a860d706
040000 tree f0c809f7840fb2e95306623bcc014814679f8602    doc
100644 blob d1e804d25075a20c19e9f0ae4cf6c86b9a976c3a    hello.h
100644 blob 2bf944bf1fd5bf37bddb0a78c3a486f00260979a    main.cpp
$ git cat-file -p f0c809f7840fb2e95306623bcc014814679f8602
100644 blob 3a3a9fd64de1d335ecedfcc2197d3eff85d35d55    README.md

输出的每一条记录包含了相应的文件模式、类型、文件名信息。这里的文件模式参考了常见的UNIX文件模式,100644表征普通文件,040000表征目录。从概念上讲,Git内部像这样存储树对象:

859abb2f11d345bb9795dca8e74f632c.png

我们还可以有更方便的方式查看项目所对应

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值