git 中的概念

git 中的概念

在使用 Git 版本控制的过程中,有些概念我们必须有所了解,这样才能更有效率也更有意义的学下去。

有清楚且正确的概念认知,不但有助于我们学习如何操作 Git 命令,更重要的是,学习 Git 的相关知识也会更加容易上手。

本文的一些概念都是使用英文为主,这是因为在不同文章里可能会存在一些翻译问题,会导致大家有一些理解误差。

repository

我们更多的将其翻译为「仓库」, 我们要使用 Git 进行版本控制,很自然的,我们需要一个「仓库」来储存这些版本信息,这个仓库其实就是用来储存所有版本的一个空间或一个文件夹与一堆文件。

如果有了解过 Git 的人,应该很清楚,建立仓库有很多方法,如果我们要在任意一个文件夹里建立一个 Git 仓库,只要输入以下命令就可以建立完成:

git init

在这里插入图片描述

从上图可以看到,我们在执行了 git init 命令后在 demo 目录下创建了 .git 目录,这个文件夹就是一个 Git 仓库,未来所有版本的变更,都会自动储存在这个文件夹里面。

在这里插入图片描述

working directory

「工作目录」

在上面我们执行了 git init 命令后,这个 demo 文件夹就会自动成为我们的「工作目录」。

所谓「工作目录」的意思,就是我们正在准备开发的项目文件,未来都会在这个目录下进行编辑,无论是新增文件、修改文件、删除文件、文件更名以及所有其他 Git 相关的操作,都会在这个目录下完成,所以才称为「工作目录」。

由于在使用 Git 版本控制时,会遭遇到很多分支的状況,所以「工作目录」很有可能会在不同的分支之间进行切换,有些 Git 命令在执行的时候,会一并更新「工作目录」下的文件。例如当我们使用 git checkout 切换到不同分支时,由于目前分支与想要切换过去的分支的目录结构不太一样,所以很有可能会将我们目前「工作目录」下的文件进行更新,好让目前的「工作目录」下的这些目录与文件,都与另一个要切换过去的分支下的目录与文件一样。

所以,适时的保持「工作目录」的干净,是版本控制过程中的一个基本原则,更尤其是日后要进行合并的时候,这点尤其重要。

staging area

「暂存区」,由于在 git 仓库中「暂存区」其实是一个名为 index 的文件( .git/index ),所以也会被叫做「索引」。

「工作目录」下的每一个文件都只有一种状态:已跟踪未跟踪

已跟踪的文件是指那些被纳入了版本控制的文件,「工作目录」中除已跟踪文件外的其它所有文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有被放入「暂存区」。简而言之,已跟踪的文件就是 Git 已经知道的文件。

在「工作目录」中新增一个文件,这个文件就是未追踪的。

比如我们在「工作目录」中新增一个 index.js 文件,然后通过 git status 查看状态

在这里插入图片描述
这里提示了「工作目录」里存在一个未追踪的文件 index.js.

此时我们可以通过 git add index.js 把 index.js 文件添加进「暂存区」中,在运行 git status 命令,会看到 index.js 文件已被追踪,并处于暂存状态:

在这里插入图片描述

只要在 Changes to be committed 这行下面的,就说明是已暂存状态。 如果此时执行 git commit 命令,那么该文件在我们执行 git add 时的版本将被留存在后续的历史记录中。

修改 index.js 文件的内容后我们再执行 git status 看看状态。

在这里插入图片描述

index.js 文件出现在「暂存区」和非暂存区了,这是因为我们执行 git add 命令后只是把当前版本(文件内容变更后都属于一个新版本)添加进「暂存区」。

如果我们执行 git commit 命令把版本提交出去,版本库中 index.js 的版本就是我们最后一次执行 git add 命令时的那个版本,而不是当前「工作目录」中最新的版本。所以,运行了 git add 之后又作了更改的文件,需要重新运行 git add 把最新版本重新暂存起来。

上图中文件 index.js 出现在 Changes not staged for commit 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到「暂存区」。 要暂存这次更新,就需要再次运行 git add 命令。

「暂存区」的目的主要用来记录「有哪些文件即将要被提交到下一个 commit 版本中」。如果我们想把某个版本提交到 Git 仓库里,那么我们首先就要把这个文件放入「暂存区」中,之后才能将这个变更版本提交出去。

对于已追踪的文件,在工作一段时间后,它们的状态可能是 unmodified、modified 或 staged。

  • unmodified:未修改的,代表文件第一次被加入,或是文件内容与最后一次 commit 的版本一致的状态。
  • modified:已修改的,代表文件已经被编辑过,或是文件内容与最后一次 commit 的版本不一致的状态。
  • staged:等待被 commit 的,代表下次执行 git commit 会将这些文件全部纳入版本库。

git add 命令

git add 命令,是为了将目前「工作目录」的变更写入到「暂存区」里。

使用 git add -u 则可以仅将「更新」或「删除」的文件变更写入到「暂存区」中。

git add 命令是一个多功能命令,可以:

  • 开始追踪新文件
  • 把修改后的已追踪文件放到「暂存区」
  • 用于合并时把有冲突的文件标记为已解决状态等

git status 命令

主要用来获取 「工作目录」中的文件的最新版本与「暂存区」中的差异。

这些差异中一共有三种不同的分组:

  • Changes to be committed (准备提交的变更):通过 git add 命令添加到「暂存区」中但是暂时未被提交到版本库中的文件
    • 新文件:版本库中不存在该文件,但是「暂存区」存在该文件,前面会有一个 new file 的提示
    • 修改后的文件:版本库中存在该文件,但是版本库中的最新版本与「暂存区」版本不一致,前面会有一个 modified 的提示。
    • 在执行 git commit 后这些文件都会被提交到版本库中。
  • Changes not staged for commit (尚未准备提交的变更):暂时未通过 git add 命令将变更版本放入「暂存区」的文件
    • 修改后的文件:版本库或者「暂存区」中存在该文件,但是版本库或者「暂存区」中的最新版本与「工作目录」中的最新版本不一致,前面会有一个 modified 的提示。
    • 在执行 git commit 后这些变更文件并不会被添加到版本库中。
  • Untracked files (未追踪的变更):
    • 新文件:版本库中不存在,暂存区也不存在。
    • 在执行 git commit 后这些变更文件并不会被添加到版本库中。

objects

对象,Git 的对象分为以下四种类型:

  • 「blob 对象」:「暂存区」的具体文件内容
  • 「tree 对象」:包含「暂存区」的文件的文件夹名及对应的「blob 对象」
  • 「commit 对象」:提交的 commit 信息及 tree(root tree) 对象
  • 「tag 对象」:对应的 commit 对象的 hash 值

上面的几种类型不需要强行硬背,阅读完下面的部分想必大家都能轻易理解。

我们在执行 git init 后,.git/objects 文件夹里只存在 info、pack 两个空文件。

在这里插入图片描述

当我们在根目录下输出下面的命令创建一个 file1.txt 文件,并输入 hello git; 作为内容。

echo hello git; > file1.txt

然后执行 git add . 命令将 file1.txt 文件放入暂存区:

git add .

此时我们看看 objects 文件夹中多了个名为 76 的文件夹

在这里插入图片描述

该文件夹里的存在一个 31bcb57512d5989050a08d7c507c8db7eebf8f 文件

在这里插入图片描述

我们在通过 git add 命令将文件存入「暂存区」时,都会将文件的内容中取出,通过内容产生一组 SHA1 哈希值,然后依照这个 SHA1 哈希值命名一个文件并放入 objects 文件夹中。这个文件就是 「blob 对象」

Git 仓库中的每一个「对象」,都是以「文件内容」进行 SHA1 哈希运算出一个 hash 值,并用这个 hash 值当作对象的名称 (文件名)。我们以 7631bcb57512d5989050a08d7c507c8db7eebf8f 为例,Git 会先拿前两个字元(76)当作目录名,然后把剩下的 hash 值当成文件名 (31bcb57512d5989050a08d7c507c8db7eebf8f),这些对象的实体目录与文件也都是放在 .git\objects 目录下。

此时我们打开这个文件,可以发现里边是乱码,这是因为文件内容都是通过 zlib 算法进行压缩过的,这样不但可以有效的提升文件存取效率,在日后进行封装(pack)的时候也可以利用差异压缩(delta compression)演算法来节省空间。他会自动找出相似的 blobs,并自动计算出 blob 之间的变化差异,再将这些差异储存在一个名为 packfile 的文件中,这样就可以大幅节省磁盘空间的耗用)。

在这里插入图片描述

使用 node 解压

如果我们想读取里边的内容,可以使用 node 中的 zlib 库进行解压。

const zlib = require("zlib");
const fs = require("fs");
const path = require("path");

const file = fs.readFileSync(path.resolve(__dirname, "./31bcb57512d5989050a08d7c507c8db7eebf8f"));
zlib.unzip(file, function (err, buffer) {
  if (!err) {
    console.log(buffer.toString());
  }
});

在这里插入图片描述

可以看到解压出来的内容并非原来的文本内容,而是多了 blob 12 这几个字符( Git 的处理),其中 blob 就是标识这个文件类型,12 就是文件的大小。

使用 git cat-file 指令读取

Git 也提供了一个命令来读取这些对象的内容:

git cat-file -p [hashname]

在这里插入图片描述
此时读取的文件内容是不包含类型及文件大小的,我们可以使用 -t 标识来读取这个文件对象类型:

在这里插入图片描述

使用 -s 标识来读取文件大小:

在这里插入图片描述

在把文件放入「暂存区」后,我们通过 commit 命令进行提交:

在这里插入图片描述

解析一下上面的信息:

  • master:当前 commit 的分支
  • root-commit:当前分支的首次 commit,第二次的 commit 会以此作为 parent 来构建链式 commit,实现版本回退。
  • bbada81:当前 commit 的 hash 值,我们可以通过这个 hash 来获取到对应 「commit 对象」的信息
  • 1st commit:当前 commit 的信息
  • 1 file changed, 1 insertion(+):当前 commit 版本与之前版本对比后的文件变动描述
  • create mode 10064 file1.txt:新增了一个 10064 权限的文件,文件名为 file1.txt。(10064就是 Git 内部的文件权限标识,代表普通文件,可读可写。)

执行了 commit 命令后在 objects 文件夹上新增了一个 bb 文件夹,这个文件里有两个文件。

在这里插入图片描述

通过上面的 commit 消息可以看到 bbada81 开头的就是「commit 对象」,也就是 ada81… 这个文件。

通过 git cat-file 看看这个文件对象类型及内容:

在这里插入图片描述
在这里插入图片描述

可以看到在「commit 对象」里存在以下信息:

  • tree bbb2b3dbc…: 这个就是「tree 对象」,我们可以把它理解成目录,用于 Git 在版本库里组织文件结构,这样就可以保证代码仓库里跟「工作目录」里的结构是一样的。
  • author:仓库作者信息
  • committer:当前 commit 的作者信息
  • 1st commit:当前 commit 的信息

在 objects 文件夹中也存在一个 bb/b2b3dbc… 文件。

通过 git cat-file 看看「tree 对象」类型及内容:

在这里插入图片描述
在这里插入图片描述
在上图中可以看到这个「tree 对象」里包含了一个「blob 对象」的索引以及文件名,这个「tree 对象」就相当于「工作目录」的根目录,根目录下存在一个 file1.txt 文件(也就是「blob 对象」),这样一个「commit 对象」其实就对应了当前提交的「工作目录」的版本。

为了更好的理解「tree 对象」,我们在「工作目录」创建一个 folder1 文件夹

执行 git status 查看状态时会发现提示 nothing to commit,这是因为 Git 是以文件内容进行对比的,文件夹并不会纳入对比。

在 folder1 文件夹下新建一个 file2.txt 文件,内容依旧是 hello git;。此时通过 git status 就可以看到 Git 检测到了「工作目录」存在未追踪的文件。

在这里插入图片描述
通过 git add . 把文件放入「暂存区」后,由于 file2.txt 与 file1.txt 的内容是相同的(hash 值也一样),因此在 objects 文件夹中并不会生成新的「blob 对象」,之后我们把文件提交出去。

在这里插入图片描述

此时在 objects 目录下生成了3个文件夹:02、55、c9(根据上图的 commit 信息可知,c9 文件夹里的 d4676… 文件就是「commit 对象」)。

在这里插入图片描述
在这里插入图片描述

解析一下上图中「commit 对象」:

  • tree 5505…:「tree 对象」,前面说过可以把它理解成一个目录,在这里我们把它认为是根目录,就是当前代码版本的根目录。
  • parent bbada…:记录上一次 commit 的 hash 值,这样就通过 git reset HEAD^ 回退到上一次的版本。

通过 cat-file 查看一下 5505… 这个「tree 对象」的内容:

在这里插入图片描述

里面有一个「blob 对象」hash值、名称,以及一个「tree 对象」hash值、名称,我们现在盲猜都可以知道 02fe… 这个「tree 对象」里边的内容就是 file2.txt 文件对应的「blob 对象」hash值、名称。

在这里插入图片描述

整理一下当前的「commit 对象」,可以看到跟我们「工作目录」的结构是一样的。

在这里插入图片描述
在这里插入图片描述

此时 objects 中各对象的引用关系如下图所示:

在这里插入图片描述

对于 blob、tree、commit 这三个对象,我们应该都非常理解了吧,还剩最后一个「tag 对象」,这个文件在 .git/refs/tag 文件夹中,文件名就是 tag 名,文件内容就是在生成 tag 时「commit 对象」的 hash 值。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这四个对象的关系如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/323999.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python学习】Python学习14-函数

目录 【Python学习】Python学习14-函数 前言自定义函数创建语法自定义函数与调用参数传递参考 文章所属专区 Python学习 前言 本章节主要说明Python的函数。函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。 函数能提高应…

FFmpeg 入门

1. 编译 参考文档:FFmpeg编译和集成(FFmpeg开发基础知识),重点注意这句话: 在MSYS2 Packages可以查到云仓库有哪些包,直接安装可节约大量时间。 注意:这个路径可自定义 吐槽 在看到这篇文章之前,花了大…

系列二、Spring Security中的核心类

一、Spring Security中的核心类 1.1、自动配置类 UserDetailsServiceAutoConfiguration 1.2、密码加密器 1.2.1、概述 Spring Security 提供了多种密码加密方案,官方推荐使用 BCryptPasswordEncoder,BCryptPasswordEncoder 使用 BCrypt 强哈希函数&a…

深入浅出关于go web的请求路由

文章目录 前言一、是否一定要用框架来使用路由?二、httprouter2.1 httprouter介绍2.2 httprouter原理2.3 路由冲突情况 三、gin中的路由总结 前言 最近重新接触Go语言以及对应框架,想借此机会深入下对应部分。 并分享一下最近学的过程很喜欢的一句话&am…

(Java企业 / 公司项目)JMeter接口压测使用(保姆式手把手教会)

一. JMeter简介认识(重点是下面的使用方法) JMeter是一个开源的Java应用程序,由Apache软件基金会开发和维护,可用于性能测试、压力测试、接口测试等。 1. 原理 JMeter的基本原理是模拟多用户并发访问应用程序,通过发…

ECMAScript

ECMAScript 是 JavaScript 语言的国际标准化规范。它定义了 JavaScript 的语法、类型、语句、关键字、保留字、操作符、对象等核心语言特性,为 JavaScript 的实现提供了一致性和标准化的指南。 1.概念介绍 1.1.背景和历史 起源:ECMAScript 起源于 199…

腾讯云服务器怎么买?两种购买方式更省钱

腾讯云服务器购买流程很简单,有两种购买方式,直接在官方活动上购买比较划算,在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵,但是自定义购买云服务器CPU内存带宽配置选择范围广,活动上购买只能选择固定的活动…

手机视频转换gif怎么操作?一个小妙招教你手机在线制gif

在现代社会gif动图已经是一种非常流行的图片格式了。可以通过视频转换gif的方式将自己的想法和创意制作成gif动图与好友进行分享斗图。那么,当我们想要在手机上完成视频转换成gif动图是应该怎么办呢?通过使用手机端的gif动图制作(https://www…

Windows系统缺失api-ms-win-crt-runtime-l1-1-0.dll的修复方法

“在Windows操作系统环境下,用户经常遇到丢失api-ms-win-crt-runtime-l1-1-0.dll文件的问题,这一现象引发了广泛的关注与困扰。该dll文件作为Microsoft Visual C Redistributable Package的重要组成部分,对于系统内许多应用程序的正常运行起着…

Github项目推荐-clone-voice

项目地址 GitHub - jianchang512/clone-voice 项目简述 一个声音ai工具。基于python编写。作用是音色复用。下面是官方说明:“这是一个声音克隆工具,可使用任何人类音色,将一段文字合成为使用该音色说话的声音,或者将一个声音使…

SpringCloud Nacos服务注册中心和配置中心

一、什么是Nacos? 官方介绍是这样的: Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您实现动态服务发现、服务配置管理、服务及流量管理。 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Na…

matlab|基于VMD-SSA-LSTM的多维时序光伏功率预测

目录 1 主要内容 变分模态分解(VMD) 麻雀搜索算法SSA 长短期记忆网络LSTM 2 部分代码 3 程序结果 4 下载链接 1 主要内容 之前分享了预测的程序基于LSTM的负荷和可再生能源出力预测【核心部分复现】,该程序预测效果比较好,并且结构比较清晰&#…

记一个有关 Vuetify 组件遇到的一些问题

Vuetify 官网地址 所有Vuetify 组件 — Vuetify 1、Combobox使用对象数组 Combobox 组合框 — Vuetify items数据使用对象数组时&#xff0c;默认选中的是整个对象&#xff0c;要对数据进行处理 <v-comboboxv-model"defaultInfo.variableKey":rules"rules…

Zabbix的多场景应用

1 zabbix更多用法 1.1 自动注册方式 zabbix自动发现 zabbix server服务端主动发现zappix agent客户端 1&#xff09;在【配置】-【自动发现】创建 发现规则&#xff0c;设置 IP范围 检查的键值system.uname 2&#xff09;在【配置】-【动作】-【发现动作】创建 动作&#x…

【2024】OAK智能深度相机校准教程

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是Ash…

深入理解 go chan

go 里面&#xff0c;在实际程序运行的过程中&#xff0c;往往会有很多协程在执行&#xff0c;通过启动多个协程的方式&#xff0c;我们可以更高效地利用系统资源。 而不同协程之间往往需要进行通信&#xff0c;不同于以往多线程程序的那种通信方式&#xff0c;在 go 里面是通过…

MySQL的单表查询

单表查询的素材&#xff1a; 一、单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 floa…

全网最细RocketMQ源码四:消息存储

看完上一章之后&#xff0c;有没有很好奇&#xff0c;生产者发送完消息之后&#xff0c;server是如何存储&#xff0c;这一章节就来学习 入口 SendMessageProcessor.processRequest private CompletableFuture<RemotingCommand> asyncSendMessage(ChannelHandlerCont…

tensorflow报错: DNN library is no found

错误描述 如上图在执行程序的时候&#xff0c;会出现 DNN library is no found 的报错 解决办法 这个错误基本上说明你安装的 cudnn有问题&#xff0c;或者没有安装这个工具。 首先检测一下你是否安装了 cudnn 进入CUDA_HOME下&#xff0c;也就是进入你的cuda的驱动的安装目…

Excel地址

解题思路&#xff1a; 根据题中歪歪和笨笨的话可以有两种解法。 1.输入的数为多大&#xff0c;则循环1多少次&#xff0c;当值为27时就要进行进位操作。这时要分情况讨论。 当集合中元素为一个时&#xff0c;如26&#xff0c;则需要变为1 1&#xff0c;集合元素个数加一。 当…