当前位置: 首页 > news >正文

Git 的深入理解:工作区、暂存区、本地仓库与 .git目录

本文的内容主要是针对git的本地仓库,着重对.git文件夹中的内容进行阐述

学习 Git 时,最容易混淆的一点是:代码文件在哪里?git commit又提交到了哪里?

可以先记住一句话:

你写的代码在工作区里; git commit 之后的版本数据保存在 .git 目录里。

1. Git 仓库的基本结构

假设当前项目目录如下:

git_c_demo/ ├── main.c ├── Makefile ├── .gitignore └── .git/

其中可以分成两类:

main.c / Makefile / .gitignore 工作区文件 .git/ Git 本地仓库数据库

也就是说:

项目目录 = 工作区 + .git 本地仓库数据库

main.cMakefile是你平时直接编辑的文件,属于工作区

.git/是 Git 自动维护的隐藏目录,里面保存提交历史、分支信息、暂存区、远端配置等内容。

不要手动删除或随意修改.git/,否则当前目录可能不再是一个正常的 Git 仓库。


2.git commit提交到了哪里?

当执行:

gitcommit-m"修改 main 输出内容"

时,Git 并不是把代码上传到了 GitHub,而是把当前暂存区里的内容保存到了本地仓库数据库中。

也就是保存到:

.git/objects/

所以:

git commit 是本地操作; git push 才是把本地提交上传到远端仓库,例如 GitHub。

可以理解为:

git add 把修改放入暂存区 git commit 把暂存区内容保存到 .git/objects/ git push 把本地 commit 推送到远端仓库

3..git目录中有哪些重要内容?

可以使用下面命令查看:

ls-al.git

常见内容如下:

文件或目录作用
.git/HEAD记录当前位于哪个分支
.git/config当前仓库配置,例如远端origin地址
.git/index暂存区
.git/objects/保存 Git 对象,包括 commit、tree、blob
.git/refs/heads/保存本地分支指针
.git/refs/remotes/保存远端追踪分支指针
.git/logs/保存 HEAD 和分支移动记录

其中最核心的是:

.git/objects/ 保存真正的版本数据 .git/refs/heads/ 保存分支当前指向哪个 commit .git/HEAD 保存当前所在位置 .git/index 保存暂存区

4. HEAD、branch 和 commit 的关系

查看当前 HEAD:

cat.git/HEAD

可能输出:

ref: refs/heads/main

这表示:

HEAD 当前指向 main 分支

也就是:

HEAD -> main

再查看main分支指向哪个 commit:

cat.git/refs/heads/main

可能输出一串完整的 commit ID:

d498f41234567890abcdef...

这说明:

main 分支本质上是一个指针,里面保存了最新 commit 的 ID。

关系可以理解为:

HEAD -> main -> 某个 commit

也就是说:

HEAD 表示你当前在哪里; main 是当前分支; main 指向某个具体的 commit。

补充一点:有时 Git 会把引用压缩到.git/packed-refs中,这时.git/refs/heads/main可能不一定直接存在。但概念不变,分支本质上仍然是指向 commit 的引用。


5. Git 底层的三类核心对象

Git 保存版本时,主要涉及三类对象:

commit 提交对象 tree 目录对象 blob 文件内容对象

它们的关系是:

commit ↓ tree ↓ blob

可以这样理解:

commit:一次提交记录 tree:这次提交对应的目录结构 blob:具体文件内容

例如一个项目中有:

main.c Makefile .gitignore

一次 commit 大概记录的是:

commit └── tree ├── blob main.c 的内容 ├── blob Makefile 的内容 └── blob .gitignore 的内容

所以,commit 并不是简单保存“一个文件”,而是保存了:

当前项目目录快照 父提交 parent 作者 author 提交者 committer 提交说明 message

6. 查看当前 commit 的底层信息

查看当前提交的完整 ID:

gitrev-parse HEAD

含义:

git rev-parse 解析 Git 引用 HEAD 当前提交

查看 HEAD 指向对象的类型:

gitcat-file-tHEAD

可能输出:

commit

表示 HEAD 指向的是一个 commit 对象。

查看当前 commit 的内容

gitcat-file-pHEAD

含义:

git cat-file 查看 Git 对象 -p pretty-print,以友好格式打印 HEAD 当前提交

输出中可能包含:

tree xxxxxxx parent xxxxxxx author ... committer ... 提交说明

其中:

tree 当前提交对应的目录快照 parent 上一个提交 author 作者 message 提交说明

7. 查看某个 commit 中保存了哪些文件

查看当前提交对应的目录树:

gitls-tree HEAD

含义:

git ls-tree 查看某个提交中的目录结构 HEAD 当前提交

可能输出:

100644 blob xxxxxx .gitignore 100644 blob xxxxxx Makefile 100644 blob xxxxxx main.c

这表示当前 commit 中保存了这些文件。


8. 查看 commit 中的某个文件内容

查看当前提交里的main.c

gitshow HEAD:main.c

含义:

git show 查看 Git 对象或提交内容 HEAD:main.c 当前提交中的 main.c 文件

查看上一次提交中的main.c

gitshow HEAD~1:main.c

含义:

HEAD 当前提交 HEAD~1 当前提交的上一个提交(以此类推,1可替换) :main.c 该提交中的 main.c 文件

这个命令非常适合用来对比历史版本中的文件内容。


9. 工作区文件和 commit 中的文件有什么区别?

执行:

catmain.c

看到的是:

工作区当前的 main.c

执行:

gitshow HEAD:main.c

看到的是:

最近一次 commit 中保存的 main.c

当工作区干净时,它们通常一样。

但如果你修改了main.c还没有提交:

cat main.c 显示工作区的新内容 git show HEAD:main.c 显示最近一次 commit 中的旧内容

这说明:

工作区文件 ≠ Git 已提交版本

Git 管理的不是“当前文件本身”,而是文件在不同提交中的历史快照。


10. 推荐的观察实验

可以通过一个小实验理解工作区和本地仓库的区别。

先查看当前状态:

gitstatus

查看工作区文件:

catmain.c

查看当前 commit 中保存的文件:

gitshow HEAD:main.c

此时如果工作区干净,两者内容应该一致。

然后修改main.c,但不要git add,也不要git commit

nanomain.c

修改后执行:

catmain.cgitshow HEAD:main.cgitdiff

你会发现:

cat main.c 显示你刚修改后的工作区内容 git show HEAD:main.c 显示最近一次 commit 中保存的内容 git diff 显示工作区和 Git 记录之间的差异

最后撤销修改:

gitrestore main.c

含义:

git restore main.c 把 main.c 从最近一次提交状态恢复回来,丢弃工作区修改

11. 常用查看命令总结

命令作用
ls -al .git查看.git仓库数据库目录
cat .git/HEAD查看 HEAD 当前指向哪个分支
cat .git/refs/heads/main查看 main 分支指向的 commit ID
git rev-parse HEAD查看当前提交的完整 commit ID
git cat-file -t HEAD查看 HEAD 指向对象的类型
git cat-file -p HEAD查看当前 commit 对象内容
git ls-tree HEAD查看当前提交保存的目录结构
git show HEAD:main.c查看当前提交中的main.c
git show HEAD~1:main.c查看上一次提交中的main.c
git log --oneline --graph --decorate --all查看提交历史、分支和 HEAD 关系

12. 最终总结

Git 的本质可以概括为:

Git 是一个保存在 .git 目录中的本地版本数据库。

你的代码文件在工作区中,例如:

main.c Makefile .gitignore

Git 的版本数据保存在:

.git/

执行:

gitadd

是把工作区修改放入暂存区。

执行:

gitcommit

是把暂存区内容保存为一个新的 commit 对象,存入:

.git/objects/

当前分支,例如main,会指向最新的 commit。

HEAD表示你当前所在的位置,通常指向某个分支。

所以完整关系可以理解为:

工作区文件 ↓ git add 暂存区 .git/index ↓ git commit 本地仓库 .git/objects ↑ 分支引用 .git/refs/heads/main ↑ HEAD
总结
Git 不是简单保存文件夹副本; Git 是通过 commit、tree、blob 对象保存项目历史快照; 分支只是指向 commit 的轻量级指针; HEAD 表示当前所在位置; git commit 只是提交到本地 .git,并不会自动上传到 GitHub。
http://www.jsqmd.com/news/1126654/

相关文章:

  • OpenCV实战:从零搭建环境到实现人脸识别项目
  • 前端 AI 对话的流式魔法:逐字显示是怎么做到的
  • AI入行指南:从技能评估到项目实战的完整路径
  • 2025年Linux提权实战:从内核漏洞到容器逃逸的攻防体系
  • LTC6904与PIC18LF2458构建高精度可编程方波发生器
  • AD74413R与PIC18F2525的高精度信号采集与输出方案
  • 用 AI Shell 开发智能待办事项应用
  • 工业4-20mA电流环检测与MSP432信号处理设计
  • IS31FL3731与PIC18F66K40驱动LED矩阵实战指南
  • AMD Ryzen终极调试指南:使用ZenStatesDebugTool完全掌控处理器性能
  • AMD Ryzen处理器终极调试指南:3步掌握SMU调试工具核心功能
  • format string 0 题解
  • Boss-Key老板键:3分钟掌握一键隐藏窗口的终极技巧
  • 深入掌控AMD Ryzen处理器:SMU Debug Tool终极使用指南
  • AD74413R与PIC18LF4550的硬件协同设计与优化实践
  • IS31FL3731与PIC18F2680的LED矩阵驱动优化实践
  • SPI扩展IO方案:MC74HC165A与TM4C129ENCPDT实战
  • microLog 后端开发指南
  • AMD Ryzen处理器深度调校工具:解锁隐藏性能的完整指南
  • TPAFE0808与PIC24FV16KA301的多通道信号采集系统设计
  • Boto3生产实践指南:AWS自动化运维的Python核心工具
  • WarcraftHelper完整指南:魔兽争霸3现代系统兼容性终极解决方案
  • 招聘测评考试系统选型参考指南
  • PCF8591 ADC/DAC模块与PIC18F67K40的工业应用实战
  • OneDragon:让重复操作智能退场的绝区零自动化引擎
  • 入门摄影买什么相机好?
  • 5分钟精通AMD Ryzen调试:SMUDebugTool终极指南
  • Python路径优先级问题解决方案核心原因
  • 【OpenHarmony/HarmonyOs 】数学学习 App 隐私保护实践:禁止 AI 识图、最小权限与精细化权限管控
  • 手机号逆向查询QQ号:Python3实现的完整技术解析与实战应用