常州市网站建设_网站建设公司_HTTPS_seo优化
2026/1/19 21:29:11 网站建设 项目流程

文章目录

  • Git仓库基本结构
  • Git 提交的基础操作
  • Git 版本库的底层存储结构
  • Git 提交的完整逻辑链路
  • Git 提交的完整逻辑链路
  • 常见误区总结
  • 结语

上一篇博客我们创建了一个Git仓库,这篇博客我们就来一起讨论Git的添加与修改命令及其具体原理。

上一篇博客传送门:Git的从零全平台安装配置与 Unity 项目配置

Git仓库基本结构

我们在这之前来讲一个糖猫米雪儿的故事吧:

米雪儿把欧泊的战斗数据文件拖进了战斗数据管理的Git仓库文件夹,就一溜烟找小熊玩耍去了。

隔天信黑着脸来找她要昨天的战斗记录,翻遍仓库却一无所获。米雪儿叉着腰,气鼓鼓地甩甩尾巴:“才不是我的问题喵!我明明把数据拖进仓库文件夹里了,肯定是你电脑出毛病啦~”

话音刚落,信的脸色更沉,一个闪身就消失在了原地留下一句 “自己守B吧”。于是米雪儿一人在B点凌乱~事后去找心夏问为什么回这样?

心夏揉了揉米雪儿的脑袋,温柔又耐心地解释:“Git仓库就像一个带‘登记台账’的专属档案柜——你把文件拖进柜子(仓库文件夹),只是把文件放在了档案柜的工作区,却没在台账上登记‘这份文件归档案柜管理’(执行git add + git commit)。这些没登记的文件,就像游离在档案柜规则外的‘无主文件’:Git既不会追踪它的修改,也不会把它同步到远端仓库,信那边自然查不到啦。真正的Git仓库(版本库),认的是台账上登记过的文件,可不是单纯放在柜子里的文件哦。”

米雪儿的错误就是误以为把文件放到工作区,文件就会被Git管理了,但是实际上文件被Git管理要把文件放到版本库中,我们可以用 Git 仓库的物理结构来理解。

Git 仓库文件夹里,除了隐藏的.git文件夹之外,其余可见的部分都是工作区—— 这是我们日常操作文件的区域,但在工作区里对文件的增删改,并不会自动被 Git 记录和管理。只有通过git add + git commit这两步操作,文件的修改才会被存入版本库(也就是.git隐藏文件夹),真正纳入 Git 的版本管控。

注意:.git 文件夹是 Git 的核心文件目录,git文件一定不能我们手动修改,会导致我们当前的本地仓库直接爆炸!

Git之所以能实现精准的版本控制,核心是通过版本库内部不同区域的分工协作,把文件的每一次修改都“追踪”并“固化”下来。版本库(.git目录)内部主要包含三个关键功能区域,它们各司其职,共同完成版本的维护:

1. 对象库(objects 图中绿色):存储所有修改的“原始数据”
对象库是Git版本控制的“数据仓库”,工作区中每一次文件修改,都会被封装成一个独立的Git对象存储在这里

  • 这些对象记录的是文件修改的具体内容(而非完整文件),是版本控制的最小数据单元;
  • 维护好这些对象,就等同于保留了文件从创建到当前的所有修改轨迹,这是Git实现版本追溯的基础。

2. 暂存区(stage/index 图中蓝色):待提交修改的“临时索引”
暂存区是工作区和分支之间的“中转站”,我们常用的git add .命令,本质就是把工作区中所有修改的文件,“登记”到暂存区中。

  • 暂存区并不会存储Git对象本身,而是以树状结构存储对象库中修改对象的索引(引用)
  • 这种“存索引不存数据”的设计,让暂存区非常轻量,既可以临时存放多个待提交的修改,也能灵活调整要提交的内容。

3. 分支(图中master):已确认版本的“正式索引”
分支是Git版本的“最终载体”,git commit命令的核心作用,就是把暂存区中已确认的修改,正式“提交”到当前分支(如master)下。

  • 和暂存区类似,分支同样是树状结构的索引目录,存储的是对象库中修改对象的索引;
  • 版本库中有一个特殊的指针HEAD(图中橙色),它始终指向当前活跃的分支,通过这个指针,Git就能顺着分支的索引树,找到对象库中所有相关的Git对象,最终还原出对应版本的完整文件。

    简单说就是:
    Git 版本控制的核心是 “数据(对象库)+ 索引(暂存区 / 分支)” 的分层设计,数据存内容,索引管关联,git add 是 “把修改从工作区登记到暂存区(更新索引)”,git commit 是 “把暂存区的索引固化到分支”,通过HEAD 指针进行版本追溯的关键,通过它能顺着分支→暂存区→对象库的链路,还原任意版本的文件。

Git 提交的基础操作

1. 查看文件状态
在执行git add之前,建议先通过git status查看文件处于哪个区域,这是避免操作失误的关键。

# 完整格式展示文件状态gitstatus# 精简格式展示(更易读,推荐新手使用)gitstatus -s
  • 状态解读
    • 红色文件:处于工作区,未执行git add
    • 绿色文件:处于暂存区,已执行git add未执行git commit
    • 无相关文件:所有修改已提交到版本库。

2. 暂存文件:git add
git add的作用是将工作区的文件变更添加到暂存区(Index),这是提交前的必要步骤。

gitadd[文件名]# 添加当前目录及子目录的所有变更文件(新增、修改、删除)gitadd.# 添加整个仓库的所有变更文件(推荐跨目录操作时使用)gitadd-A

注意:暂存区是工作区和版本库之间的“中转站”,只有进入暂存区的变更,才能被提交到版本库。git add .git add -A的区别——前者只处理当前目录及子目录,后者处理整个仓库的所有变更。比如在子目录执行git add .,不会追踪上级目录的文件修改。

3. 提交变更:git commit
git commit会将暂存区的所有变更打包,生成一个提交对象(Commit Object)并写入版本库,同时更新当前分支的指针。

# -m 后跟随提交说明,必须清晰描述本次提交的内容gitcommit -m"修复登录页表单验证bug"# 若忘记加 -m,会进入 vim 编辑器,输入说明后按 ESC + :wq 保存退出# 修改最后一次提交的说明(未推送到远端时使用)gitcommit --amend -m"修正后的提交说明"

技巧:提交说明要“言简意赅”,比如“新增用户管理模块”“修复数据加载卡顿问题”,避免写“更新文件”“修改代码”这种无意义的描述,毕竟是给未来的自己看的嘛。

3. 查看提交记录:git log
提交后,你可以通过git log查看所有提交记录,默认按“从近到远”的顺序展示:

# 完整格式展示提交记录(包含作者、时间、提交说明)gitlog# 精简格式:一行展示一条提交记录(便于快速浏览)gitlog --pretty=oneline# 只查看最近 n 条提交记录(n 为数字)gitlog -n3

  • 提交IDcommit 1a038c3f4c1dcfca47cf243ae4a097a813bbe1ad是每次提交时通过 SHA-1 算法计算出的唯一ID,这个ID能直接定位到某次提交的所有内容。只要文件内容或提交信息有一点变化,提交ID就会完全不同。

    5. 撤销操作
    不小心add错文件?提交说明写错了?这些问题都有对应的解决办法:
# 撤销暂存区的指定文件(回到工作区)gitreset HEAD[文件名]# 撤销暂存区的所有文件gitreset HEAD.# 修改最后一次提交的说明(未推送到远端)gitcommit --amend -m"新的提交说明"

Git 版本库的底层存储结构

执行git addgit commit后,Git 会在本地版本库(.git目录)中生成一系列文件和目录,核心包括indexHEADrefsobjects

1. 暂存区的载体:index 文件

  • index文件在初始化仓库(git init)时不存在,第一次执行git add后自动生成
  • 它存储了暂存区的元数据(如文件路径、哈希值、修改时间等),本质是“待提交文件的清单”;
  • 路径:.git/index(可通过git ls-files --stage查看暂存区内容)。

    2. 分支指针:HEAD
    HEAD是一个特殊的指针,始终指向当前工作分支的最新提交,我们可以把它理解为“当前位置的书签”。

    .git目录下就能找到HEAD文件,打开后会看到类似ref: refs/heads/master的内容,代表当前分支是master
    3. 分支的本质:refs 目录
    分支名对应的文件存储了该分支最新提交的 ID,路径为.git/refs/heads/[分支名](如.git/refs/heads/master)。
  • 示例:master文件内容为1a038c3f4c1dcfca47cf243ae4a097a813bbe1ad(即该分支最新提交的 ID)。
  • 核心逻辑:分支 = 提交 ID 的“别名”,Git 通过分支文件快速定位到最新提交。

    4. 数据存储核心:objects 目录
    Git 所有的版本数据(提交对象、树对象、文件内容)都以“对象”形式存储在.git/objects目录下,每个对象对应一个唯一的哈希值(即提交 ID/树 ID/文件 ID)。

以提交 ID1a038c3f4c1dcfca47cf243ae4a097a813bbe1ad为例:

  • 前两位字符1a是文件夹名称;
  • 剩余字符038c3f4c1dcfca47cf243ae4a097a813bbe1ad是文件夹内的文件名。

    要查看这个对象的内容,需要使用git cat-file命令:
# -p 参数表示以可读格式输出对象内容gitcat-file -p 1a038c3f4c1dcfca47cf243ae4a097a813bbe1ad

  • tree:指向一个“树对象”,记录本次提交的文件目录结构;
  • parent:指向父提交,形成提交历史的“链式结构”(即分支的提交记录链)。
  • author/committer:记录提交者信息和提交时间。

继续查看树对象的内容,就能看到本次提交包含的文件及对应的哈希值,最终通过哈希值找到文件的实际内容。

我们可以看到打印了一行内容着一行内容就是我们修改的内容。

Git 提交的完整逻辑链路

  1. git add:将工作区文件的哈希值写入.git/index(暂存区);
  2. git commit
    • 生成“文件对象(blob)”存储文件内容;
    • 生成“树对象(tree)”记录文件目录结构;
    • 生成“提交对象(commit)”关联树对象、父提交、作者和提交说明;
    • 更新当前分支文件(如master),写入最新提交 ID;
    • 更新HEAD指针,指向当前分支的最新提交;
  3. 最终链路:HEAD→ 分支文件 → 提交对象 → 树对象 → 文件对象 → 实际文件内容。

Git 提交的完整逻辑链路

通过前面的内容,我们可以梳理出git addgit commit的完整执行链路:

  1. git add执行过程

    • 计算工作区文件的哈希值;
    • 将文件内容封装为blob 对象存入.git/objects
    • 将 blob 对象的哈希值写入.git/index(更新暂存区索引)。
  2. git commit执行过程

    • 读取.git/index,生成tree 对象(记录目录结构和 blob 哈希),存入.git/objects
    • 生成commit 对象(关联 tree 对象、父提交 ID、作者信息、提交说明),存入.git/objects
    • 更新当前分支文件(如.git/refs/heads/master),写入最新 commit ID;
    • 更新HEAD指针,指向当前分支的最新提交。
  3. 版本追溯链路
    HEAD→ 分支文件 → commit 对象 → tree 对象 → blob 对象 → 实际文件内容

常见误区总结

  1. 误区1:把文件拖到仓库文件夹,就认为被 Git 管理了。
    → 正解:必须执行git add + git commit,文件才会进入版本库。
  2. 误区2:手动修改.git目录下的文件。
    → 正解:.git是 Git 核心目录,手动修改会导致仓库损坏。
  3. 误区3:提交说明写“更新文件”“修改代码”。
    → 正解:提交说明要清晰描述修改内容,便于后续版本追溯。
  4. 误区4:混淆git add .git add -A的作用范围。
    → 正解:前者管当前目录,后者管整个仓库,根据需求选择。

结语

Git 的添加与提交操作看似简单,背后却藏着“工作区-暂存区-版本库”的分层设计逻辑。理解底层原理,不仅能帮我们避免操作失误,还能在遇到问题时快速定位原因。

别忘了给这个博主点个赞赞喵、关个注注喵~(๑˃̵ᴗ˂̵)و 你对这个博主的支持就是他继续肝优质算法内容的最大动力啦喵~我们下篇博客,不见不散喵~

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询