一文搞明白GIT——Git原理解析与常用命令

article/2025/9/11 18:38:21

工作中经常用git,但是不少命令经常使用出现各种各样的问题,也不太理解其中的原理。今天专门总结一下git的原理,理解原理之后想实现什么样的功能直接找相应的命令即可。如有错误和不足,欢迎指正!

一、 工作区

使用git命令之前首先需要明白git的工作区

在这里插入图片描述
版本库:.git目录
工作区:除 .git目录的其他目录和文件
如图所示:git版本库里维护了两个目录树,暂存区目录树和分支目录树(在隐藏的 .git文件中)
在这里插入图片描述

更详细一些的四大工作区:
在这里插入图片描述

  1. Workspace: 工作区,就是你平时存放项目代码的地方
  2. Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
  3. Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
  4. Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换

二、GIT 实现版本管理原理

git会将我们的文件和目录转化成一种叫做”git对象”的东西,然后再对这些”git对象”进行管理,从而实现版本管理的目的,这些git对象存放在git的对象库中。

文件————>块(blob)
目录————>树(tree)
状态————>提交(commit)

blob、tree、commit都是git对象,是三种不同类型的git对象

一个blob就是由一个文件转换而来,blob对象中只会存储文件的数据,而不会存储文件的元数据。

一个tree就是由一个目录转化而来,tree对象中只会存储一层目录的信息,它只存储它的直接文件和直接子目录的信息,但是子目录中的内容它并不会保存。

一个commit就是一个我们所创建的提交,它指向了一个tree,这个tree保存了某一时刻项目根目录中的直接文件信息和直接目录信息,也就是说,这个tree会指向直接文件的blob对象,并且指向直接子目录的tree对象,子目录的tree对象又指向了子目录中直接文件的blob,以及子目录的直接子目录的tree,依此类推。

图解
开始:工作区只有一个根目录,目录下两个文件 f1, f2 现在进行提交操作 git转换成如下对象
在这里插入图片描述的发大发放放

现在修改f2的内容为f22 f1不变,并在根目录下创建子目录dir1,并在dir1新建文件df1
在这里插入图片描述

三、文件的四种状态

结合上节版本控制原理,可知不同状态之前的改变原因
不同的工作区存在的文件对应了不同的状态,入下图所示
在这里插入图片描述

  1. Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
  2. Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified,如果使用git rm移出版本库, 则成为Untracked文件
  3. Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
  4. Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存,文件状态为Modified

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

四、命令实现过程与原理

分支

了解git的各种命令之前,需要先明白git分支的概念。git分支可以说是git普及如此之广的最重要的理由之一。

分支其实就是记录一系列逻辑操作的一条线,这条线记录了我们操作过程和每次操作的内容。如下图所示,每一个节点都是一次commit 节点连起来就形成了分支。

分支有什么作用呢?
1:精准编辑回退

在这里插入图片描述

分支指针和HEAD指针

搞明白git命令的实现过程,就必须先了解指针的概念,很多命令都是用过指针实现的。
指针是什么呢?
指针是版本库中指向分支中某个提交的标识(每个提交都有一个唯一id),记录了我们当前所在的位置。
每个分支都会有一个分支指针,默认指向当前分支的最新提交(注意提交是个tree 有父节点)。
HEAD指针通过指向分支指针指向当前分支的最新提交
(思考一个问题:当我们把控制台或者git bash操作窗口关闭后,再次打开为什么能直接记录到关闭前所在的分支呢?)

在这里插入图片描述

命令实现原理和过程

1. 查看分支提交记录

git log 
下面我们看一下这个命令做了什么。比如说我们现在在test分支上,那就是从分支指针指向的commit树开始,依次**找父节点**,然后将信息展示出来,这就实现了记录的查询操作

在这里插入图片描述

2.查看不同

在这里插入图片描述
git diff
这个命令怎么实现的呢?上文中讲到git的实现原理 ,git会将文件转为git对象,回顾一下:

文件————>块(blob)
目录————>树(tree)
状态————>提交(commit)

现在以比较工作区和暂存区的区别为例:
运行git diff 找到当前最新的提交,从暂存区拿到相应的文件(有目录和文件地址和文件内容)然后和工作区的一行行比较
在这里插入图片描述

3.撤销修改(版本回退)

git reset commitID
git reset --hard commitId(实现和rollback一样的功能)

“git reset HEAD”命令将最近提交中的内容覆盖到了暂存区
“git reset –hard HEAD”命令将最近提交中的内容覆盖到了暂存区和工作区

撤销操作是怎么实现的呢?这个还是和指针有关。比如从D回退到C,这时候git做了什么呢?其实很简单,只需将指针指向C就好,这时候根据commit树的id去查内容查到的就是C提交时的内容。
在这里插入图片描述

4.合并分支

git merge
git rebase

合并分支应该是非常常用的命令了,下面来解析下合并分支的时候git是如何做的。
首先以git merge 为例

在这里插入图片描述
根据之前分析的原理,其实可以很清楚的理解git做了怎样的事情。
两个分支指针分别指向最新的提交,现在做图示一操作,将new分支合并到base上,运行命令base分支新生成一个commit 节点分别指向new分支的最新commit和base分支的最新commit,然后base分支的分支指针指向新生成的这个commit就完成了合并。

git rabse的变基操作,其实就是复制基准点后的变更文件(注意是复制!!并不是直接改父节点,git所有的操作都不会更改原有的内容,虽然提交信息看着一样,但是commitId是不同的!),然后将父节点指向合并分支的最新提交,达到变基的目的。

在这里插入图片描述

5.其他

其他的命令都可以参考git实现原理去理解实现方式,只有明白了原理,命令理解起来就很简单了。

文档参考:git系列学习


http://chatgpt.dhexx.cn/article/WYiY2Q5t.shtml

相关文章

Git 原理详解及实用指南

Git 原理详解及实用指南 什么是版本控制系统(VCS) 很多人认为 Git 难以理解的第一个门槛在于:所谓的「Git 是一个分布式版本控制系统」这句话的具体含义不够清楚。其实分布式版本控制系统(Distributed Version Control System - …

图解git原理

用了这么久git,你有没有想过git的原理是什么?为什么git做回退这么快?创建、切换分支也这么快?git的工作区、暂存区、本地仓库、远程仓库都分别对应怎样的实体?打开一个git仓,看看目录下的.git文件夹&#x…

Git 的原理

文章目录 什么是 Git?版本库是由什么构成的版本库(项目文件夹)的构成版本库(对象数据库)的结构提交的组成SHA1 算法 总结 暂存区什么样的文件,不应该上传到版本库中?查看暂存区清空暂存区选择性…

Git学习之git原理

git对象 当我们使用git进行版本管理时,git会将我们的文件和目录结构转化成git方便操作的数据(git对象),然后再对这些git对象进行管理,从而实现版本管理的目的,这些git对象存放在git的对象库中。 我们眼中的文件会被git转化成&qu…

Git 必知必会:原理剖析

作为程序员,最常用的版本管理工具便是 Git。但我相信大多数人和我一样,从没有认真了解过其具体实现的原理。但了解 Git 的原理,能有助于我们工作更好的使用 Git。下面,让我们一起来了解 Git 中的一些概念,以及实现。 一…

git 原理简介

文章目录 关于版本控制分为三种版本控制方案本地版本控制集中化的版本控制分布式版本控制 git基本底层原理git提交流程原理Git的引用(分支)git log原理总结参考链接 关于版本控制 什么是“版本控制”?我为什么要关心它呢? 版本控制是一种记录一个或若干文…

【转】以太坊钱包分析与介绍

林修平在亚太区以太坊社区培训与交流Meetup深圳站上跟我们分享了他对以太坊各种钱包模式的介绍,还分析了Parity多签名钱包安全事件的技术原因。昨日,EthFans得到作者授权,分享他的PPT。鉴于PPT较长,为保证阅读体验,编者…

币久网好像暂停ZEC交易了,各位的ZEC币暂时不要转入币久网了

今天突然发现币久网不能交易ZEC了,然后看到了官方公告,难不成ZEC也是P网的? 各位如果需要其他的钱包地址,比如Windows本地Zcash钱包地址,可以移步去我的其他博文看看 http://blog.csdn.net/squirrel1311/article/detai…

『0001』 - 如何通过 MyEtherWallet 创建钱包以及如何通过 Ethereum Wallet 和 MetaMask 恢复钱包账号

视频教程 来源: 黎跃春区块链博客 学习目标 钱包介绍创建钱包发送和接收以太币恢复钱包如何获取以太币 钱包介绍 Ethereum Wallet 钱包 开启Ethereum智能合约开发(Smart Contract)最快的方式就是Ethereum Wallet,它支持Windows, MacOSX 和 Linux开发…

web3.js链接以太坊并查询钱包u余额

web3.js链接以太坊并查询钱包USDT余额 环境:一、链接以太坊主网:二、创建一个ABI那么该如何获取ABI? 三、查询代码四、输出结果五、整体代码 环境: web3.js版本:6.14.15 不会安装以及使用web3.js的小伙伴看:https://blog.csdn.net/qq_45844443/article/details/124330035 一…

Clickhouse 以太坊分析:基础交易数据清洗

概述 读者可前往我的网站获得更好的阅读体验。 笔者最近遇到了许多关于数据分析的文章,大部分都使用了 Dune 等 SaaS 工具,这些工具往往提供了清洗后的区块链数据和数据库分析工具。对于大部分数据分析师而言,这些工具可以应对一系列复杂的…

DApp创建本地钱包并实现签名转账(BSC,Polygon,ETH)

文章目录 1. 项目准备2. 钱包相关概念3.随机创建一个钱包4.根据助记词导入钱包5.根据keystore导入钱包6.签名转账 1. 项目准备 安装ether.js npm install --save ethers引入ether.js:的三种方法 es3: var ethers require(‘ethers’);es5/es6 const ethers require(‘et…

使用ethers.js开发以太坊Web钱包 - 将私钥保存在客户端

为什么需要 Keystore 文件 通过这篇文章理解开发HD 钱包涉及的 BIP32、BIP44、BIP39,私钥其实就代表了一个账号,最简单的保管账号的方式就是直接把私钥保存起来,如果私钥文件被人盗取,我们的数字资产将洗劫一空。 Keystore 文件就…

CEX暴雷怎么办 一文读懂加密钱包产业现状

你的钱其实并不在你的借记卡里,借记卡只是授权你的银行帐户向银行系统数据库发送交易。同样,你的代币也并不在你的加密钱包里。加密钱包只是持有私有密钥以证明对数字资产的所有权,而这些资产是存储在公共区块链网络上的。私钥能让你对加密钱…

区块链隐私保护文献 An Efficient NIZK Scheme for Privacy-Preserving Transactions over Account-Model Blockchain

读:An Efficient NIZK Scheme for Privacy-Preserving Transactions over Account-Model Blockchain 本文的目的 找到一种适用于轻量级设备及智能合约的高效零知识证明 前人的工作 不能直接迁移UTXO模型的隐私保护方案的原因 在考虑用户余额的隐私时&#xff0…

最新消息,我的Zcash钱包收到鱼池的ZEC打款了

最新消息,我的Zcash钱包收到鱼池的ZEC打款了 有图有真相哈,竟然价值17元啊,哈哈,看到钱途了。。。 如果你们需要测试打款的,可以往我Zcash钱包打款哈 我的Zcash钱包地址:t1PH7xk25VYdJcR5TnkEuEq8jpsiQ…

区块链钱包—BTC Java版离线签名交易

对于离线交易不做过多解释~,说白了就是拿上一笔未发出交易记录进行私钥的签名然后广播到链上。 主要是对区块链离线交易进行utxo上链。 代码参考: https://gitee.com/DHing/signature-transaction UnspentUtxo交易查询参考:https://blog.c…

Zcash钱包(ZEC钱包)官方客户端常见命令实测(一)

一、如何查询链接节点 $ ./src/zcash-cli getpeerinfo 二、如何获取一个 t- 开头的钱包地址 $ ./src/zcash-cli getnewaddress 三、如何获取一个 z- 开头的钱包地址 $ ./src/zcash-cli z_getnewaddress

通过代码生成以太坊助记词、根据钱包地址获取私钥

生成助记词、公私钥 新建一个目录 在目录下执行 npm init (需安装nodejs)nodejs中文官网 安装依赖 (没有yarn的需要安装,直接执行 npm install -g yarn) yarn add bip39 ethereum-hdwallet 在目录下新建js文件 将下…