二、Git 本地仓库:从 git init 到第一次提交
Git 本地仓库:从 git init 到第一次提交
上一篇主要整理了 Git 为什么存在,以及它能解决什么问题。
从这一篇开始,就正式进入 Git 的实际操作。
学习 Git 时,最先要掌握的不是分支,也不是远程仓库,而是 本地仓库。
因为 Git 的很多操作,本质上都是围绕本地仓库展开的。只有先理解本地仓库、工作区、暂存区、版本库之间的关系,后面学习 add、commit、reset、branch、merge 才不会觉得乱。
一、什么是 Git 仓库
在 Git 中,仓库可以理解为一个被 Git 管理起来的项目目录。
普通目录只是普通目录,Git 不会自动管理它。
只有当一个目录被初始化成 Git 仓库后,Git 才会开始追踪这个目录中的文件变化。
比如有一个目录:
gitcode
如果它只是一个普通目录,那么你在里面新增、修改、删除文件,Git 并不会记录这些变化。
想让 Git 管理这个目录,需要先进入这个目录,然后执行:
git init
执行完成后,这个目录就变成了一个 Git 本地仓库。
简单来说:
Git 仓库 = 一个被 Git 接管并可以进行版本管理的目录。

二、创建一个本地仓库
先创建一个用于练习的目录。
Linux / Git Bash 中可以这样写:
mkdir gitcode
cd gitcode
查看当前所在目录:
pwd
然后执行初始化命令:
git init
执行成功后,通常会看到类似输出:
Initialized empty Git repository in xxxxx
这句话的意思是:Git 已经在当前目录下初始化了一个空仓库。
这里有两个重点:
git init要在你希望管理的目录中执行;- 初始化完成后,当前目录下会多出一个隐藏目录:
.git。
可以查看隐藏文件:
ls -a
可能会看到:

其中 .git 就是 Git 仓库真正的核心。
三、git init 到底做了什么
很多人刚开始使用 Git 时,只知道 git init 是初始化仓库,但不清楚它具体做了什么。
其实 git init 最重要的动作就是:
在当前目录下创建一个 .git 隐藏目录。
这个 .git 目录里面保存了 Git 管理版本所需要的各种数据。
也就是说,真正让一个普通目录变成 Git 仓库的,并不是目录名字,也不是里面有多少代码,而是它内部出现了 .git 目录。
可以理解为:
普通目录
↓ 执行 git init
带有 .git 目录的 Git 仓库
如果把 .git 目录删掉,这个目录就不再是 Git 仓库了。
当然,正常情况下 不要手动修改或删除 .git 目录。
因为 Git 的版本信息、提交记录、分支引用等内容都保存在里面。随便改 .git 目录,很容易把仓库弄坏。
四、认识 .git 目录
初始化仓库后,可以看一下 .git 目录里面大概有什么。
在 Linux / Git Bash 中可以使用:
tree .git
如果没有安装 tree,也可以使用:
ls .git
看看我的:
一个刚初始化的 .git 目录中,通常会包含类似这些内容:
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
├── info
├── objects
└── refs
这些目录和文件后面都会逐渐接触到。现在先建立一个整体印象。
1. config
config 保存当前仓库的配置信息。
比如这个仓库单独使用的用户名、邮箱、远程仓库地址等,都可能写在这里。
2. HEAD
HEAD 可以先理解为一个指针。
它指向当前所在的分支,后面学习分支时会频繁遇到它。
刚开始可以先记住:
HEAD 和“当前版本”“当前分支”有关。
3. hooks
hooks 目录保存 Git 钩子脚本。
钩子可以在某些 Git 操作前后自动执行脚本,比如提交前检查代码格式。
刚入门时暂时不用深究。
4. objects
objects 是 Git 保存对象数据的地方。
提交、文件内容、目录结构等底层数据,最终都会以对象的形式保存在这里。
5. refs
refs 保存引用信息。
比如分支、标签,本质上都和 refs 有关。
后面学习分支和标签时会继续展开。
现在不需要一开始就把 .git 里的所有内容背下来,只需要知道:
.git 是 Git 仓库的核心,里面保存了 Git 进行版本管理所需的全部信息。

五、配置 Git 用户名和邮箱
Git 安装完成后,通常需要先配置用户名和邮箱。
这是因为 Git 的每一次提交都会记录提交者信息。如果不配置,提交时可能会报错,或者 Git 会使用不符合预期的默认身份。
常用配置命令如下:
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
实际使用时,把内容换成自己的信息:
git config --global user.name "zhangsan"
git config --global user.email "zhangsan@example.com"
这里的 --global 表示全局配置。
也就是说,这台电脑上当前用户下的所有 Git 仓库,默认都会使用这个用户名和邮箱。
1. 全局配置和当前仓库配置
Git 配置有不同作用范围,最常见的是两种:
- 全局配置
- 当前仓库配置
带 --global 的配置属于全局配置:
git config --global user.name "zhangsan"
git config --global user.email "zhangsan@example.com"
这种配置会影响当前用户下的所有 Git 仓库。
如果平时都是用同一个身份提交代码,使用全局配置最方便。
如果不加 --global,就是当前仓库配置:
git config user.name "lisi"
git config user.email "lisi@example.com"
这种配置只对当前仓库生效。
需要注意的是,执行当前仓库配置时,一般要在 Git 仓库目录中执行。
比如有些场景下,可能希望:
- 公司项目使用公司邮箱;
- 个人项目使用个人邮箱。
这时就可以全局配置一个默认身份,再在某个具体仓库中单独覆盖配置。
例如,先配置全局身份:
git config --global user.name "zhangsan"
git config --global user.email "personal@example.com"
然后在公司项目仓库中单独配置邮箱:
git config user.email "work@example.com"
这样这个公司项目就会使用 work@example.com,而其他仓库仍然使用全局邮箱。
如果一个配置同时存在全局配置和当前仓库配置,当前仓库配置优先级更高。

2. 查看 Git 配置
查看当前 Git 配置,可以使用:
git config -l
可能会看到类似内容:
user.name=zhangsan
user.email=zhangsan@example.com

如果只想查看某一项配置,可以写:
git config user.name
git config user.email
如果想查看全局配置,可以写:
git config --global user.name
git config --global user.email
3. 删除 Git 配置
删除配置可以使用 --unset。
删除全局用户名:
git config --global --unset user.name
删除全局邮箱:
git config --global --unset user.email
删除当前仓库配置时,不加 --global:
git config --unset user.name
git config --unset user.email
六、工作区、暂存区和版本库

理解 Git,必须先理解三个区域:
- 工作区
- 暂存区
- 版本库
这三个概念非常关键。
很多 Git 命令看起来难,其实是因为没有弄清楚文件到底处在哪个区域。
1. 工作区
工作区,就是我们平时真正编辑文件的目录。
比如当前项目目录是:
gitcode
那么这个目录中除 .git 以外的大部分内容,都可以理解为工作区。
你写代码、改文档、新增文件,都是在工作区中完成的。
例如:
gitcode/
├── ReadMe
├── main.c
└── src/
这些文件就是我们能直接看到、直接编辑的内容。
工作区的特点是:
- 可以直接编辑;
- 可以新增文件;
- 可以删除文件;
- 文件变化不一定已经被 Git 保存为版本。
也就是说:
文件出现在工作区,不代表它已经被 Git 版本管理起来了。
2. 暂存区
暂存区,英文叫 stage 或 index。
它是工作区和版本库之间的中间区域。
当执行:
git add ReadMe
这个操作并不是直接把文件提交到版本库,而是先把文件修改放到暂存区。
可以把暂存区理解为:
下一次提交前的准备区。
你可以先把多个文件陆续放进暂存区,然后一次性提交:
git add file1
git add file2
git add file3
git commit -m "add three files"
虽然执行了三次 git add,但最后只执行了一次 git commit。
原因就是:
git commit 提交的是暂存区中的内容。
暂存区一般对应 .git/index 文件,所以暂存区有时也被叫作索引区。
3. 版本库
版本库,也叫仓库,英文是 repository。
对于一个 Git 项目来说,.git 目录就是 Git 的版本库核心。
版本库中保存了:
- 提交历史;
- 文件快照;
- 分支信息;
- 标签信息;
- Git 配置;
- 对象数据。
工作区是我们编辑文件的地方,版本库是 Git 保存历史版本的地方。
如果某个文件只是被复制到了项目目录中,但没有执行 git add 和 git commit,那么它还没有真正进入版本库。
所以可以记住这句话:
新建文件只是进入工作区,执行 git add 后进入暂存区,执行 git commit 后才进入版本库。

七、git add 和 git commit:从暂存到提交
刚开始学习 Git 时,很容易把 git add 和 git commit 混在一起。
其实它们的职责不同:
git add :把工作区中的修改加入暂存区
git commit :把暂存区中的内容提交到本地仓库
1. git add
git add 的作用是把工作区中的修改加入暂存区。
常见用法:
git add ReadMe
添加多个文件:
git add file1 file2 file3
添加某个目录:
git add src
添加当前目录下所有变化:
git add .
2. git commit
git commit 的作用是把暂存区中的内容提交到本地仓库。
常见用法:
git commit -m "提交说明"
这里的 -m 后面要跟提交信息。
提交信息非常重要,不要随便写成:
git commit -m "update"
这种信息后面看起来基本没有意义。
更推荐写清楚本次提交做了什么,例如:
git commit -m "add ReadMe file"
或者:
git commit -m "fix login error message"
好的提交说明,能让后面查看历史记录时更容易理解项目变化。
3. 第一次提交文件
下面完整走一遍第一次提交文件的流程。
先在仓库目录中创建一个 ReadMe 文件:
vim ReadMe
写入内容:
hello git
hello git
如果不使用 vim,也可以用其他编辑器创建这个文件。
查看文件内容:
cat ReadMe
输出:
hello git
hello git
此时 ReadMe 只是工作区中的一个文件,还没有进入 Git 仓库。
先添加到暂存区:
git add ReadMe
然后提交到本地仓库:
git commit -m "commit my first file"
我这里演示的是我之前的socket编程的代码
提交成功后,可能会看到类似输出:
[master (root-commit) c614289] commit my first file
1 file changed, 2 insertions(+)
create mode 100644 ReadMe
这段输出可以简单理解为:
- 当前提交发生在
master分支; - 这是当前仓库的第一次提交,所以有
root-commit; - 本次提交 ID 的前几位是
c614289; - 有 1 个文件发生变化;
- 新增了 2 行内容;
- 创建了一个新文件
ReadMe。
这里的 master 是分支名。
不同 Git 版本或不同平台中,默认分支名也可能是 main。如果看到的是 main,也不用奇怪,本质是一样的。

4. 一次提交多个文件
Git 支持多次 git add,然后一次 git commit。
例如创建三个文件:
touch file1 file2 file3
分别加入暂存区:
git add file1
git add file2
git add file3
最后一次性提交:
git commit -m "add three files"
可能会看到类似输出:
[master 23807c5] add three files
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file1
create mode 100644 file2
create mode 100644 file3
这说明三个文件被作为同一次提交保存到了版本库中。
这里也能看出暂存区的作用:
暂存区可以帮我们组织下一次提交要包含哪些内容。
不是所有工作区修改都必须一次提交。
我们可以选择一部分修改加入暂存区,再提交这一部分内容。
这个习惯在真实开发中非常重要。
八、查看提交历史
提交完成后,可以使用 git log 查看历史提交记录:
哎,暴露邮箱了,懒得打码了。工作邮箱而已,欢迎大家学习交流。
git log
示例输出:
commit 23807c536969cd886c4fb624b997ca575756eed6 (HEAD -> master)
Author: zhangsan <zhangsan@example.com>
Date: Sat May 6 11:27:32 2023 +0800
add three files
commit c61428926f3853d4ec6dde904415b0e6c1dabcc6
Author: zhangsan <zhangsan@example.com>
Date: Sat May 6 11:25:50 2023 +0800
commit my first file
从日志中可以看到:
- 每次提交都有一个
commit id; - 每次提交都有作者信息;
- 每次提交都有时间;
- 每次提交都有提交说明;
- 最新提交一般显示在最上面。
其中 commit id 是 Git 为每次提交生成的唯一标识。
后面做版本回退时,经常会用到它。
HEAD -> master 表示当前 HEAD 指向 master 分支,而 master 分支当前指向这次提交。
现在不需要完全理解 HEAD 和分支的细节,只要先知道:
git log 可以查看仓库的提交历史。
总结
这一篇从零开始整理了 Git 本地仓库的基本使用流程。
主要内容包括:
- 如何使用
git init创建本地仓库; .git目录的作用;- Git 用户名和邮箱配置;
- 全局配置和当前仓库配置的区别;
- 工作区、暂存区、版本库三个核心区域;
git add和git commit的关系;- 如何完成第一次文件提交;
- 如何一次提交多个文件;
- 如何使用
git log查看提交历史。
到这里,已经可以完成最基本的本地提交操作了。
下一篇继续围绕文件状态展开,重点整理:
- Git 如何识别文件新增和修改;
- 如何查看当前仓库状态;
git status怎么读;git diff如何查看文件差异;- 为什么提交前一定要检查修改内容。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)