理解 Git 的三个工作区:工作区、暂存区和版本库

文章目录

创建 Git 本地仓库

要提前说的是,仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂件进⾏版本控制,就必须先创建⼀个仓库出来。创建⼀个 Git 本地仓库对应的命令为 git init ,注意命令要在⽂件⽬录下执⾏,例如:

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ pwd
/home/XMLife/Git_code
[XMLife@VM-8-6-centos Git_code]$ git init
Initialized empty Git repository in /home/XMLife/Git_code/.git/
[XMLife@VM-8-6-centos Git_code]$ ll -a
total 12
drwxrwxr-x 3 XMLife XMLife 4096 Sep 19 09:30 .
drwx------ 5 XMLife XMLife 4096 Sep 19 09:29 ..
drwxrwxr-x 7 XMLife XMLife 4096 Sep 19 09:30 .git

我们发现,当前⽬录下多了⼀个 .git 的隐藏⽂件, .git ⽬录是 Git 来跟踪管理仓库的,不要⼿动

修改这个⽬录⾥⾯的⽂件,不然改乱了,就把 Git 仓库给破坏了.如果大家感兴趣可以打开看看.


配置Git

当首次安装配置 Git 后⾸先要做的事情是设置自己的 ⽤⼾名称e-mail 地址,这是⾮常重要的。如果忘记配置会出现不必要的问题,配置命令为

cpp 复制代码
git config [--global] user.name "Your Name" 
git config [--global] user.email "email@example.com" 
# 把 Your Name 改成你的昵称
# 把 email@example.com 改成邮箱的格式,只要格式正确即可

其中 --global 是⼀个可选项。如果使⽤了该选项,表⽰这台机器上所有的 Git 仓库都会使⽤这个

配置。如果你希望在不同仓库中使⽤不同的 name 或 e-mail ,可以不要 --global 选项,但要

注意的是,执⾏命令时必须要在仓库⾥。

查看配置命令为:

c 复制代码
git config -l

删除对应的配置命令为:

c 复制代码
git config [--global] --unset user.name
git config [--global] --unset user.email

认识⼯作区、暂存区、版本库

  • ⼯作区:是在电脑上你要改动你的代码或⽂件的⽬录。
  • 暂存区:英⽂叫 stage 或 index。⼀般存放在 .git ⽬录下的 index ⽂件(.git/index)中,我们把暂存区有时也叫作索引(index)。
  • 版本库:⼜名仓库,英⽂名 repository 。⼯作区有⼀个隐藏⽬录 .git ,它不算⼯作区,⽽
    是 Git 的版本库。这个版本库⾥⾯的所有⽂件都可以被 Git 管理起来,每个⽂件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以"还原"。

下⾯这个图展⽰了⼯作区、暂存区和版本库之间的关系:

  • 图中左侧为⼯作区,右侧为版本库。Git 的版本库⾥存了很多东西,其中最重要的就是暂存区。
  • 在创建 Git 版本库时,Git 会为我们⾃动创建⼀个唯⼀的 master 分⽀,以及指向 master 的⼀个指针叫 HEAD。
  • 当对⼯作区修改(或新增)的⽂件执⾏ git add 命令时,暂存区⽬录树的⽂件索引会被更新。
  • 当执⾏提交操作 git commit 时,master 分⽀会做相应的更新,可以简单理解为暂存区的⽬录
    树才会被真正写到版本库中。

由上述描述我们便能得知:通过新建或粘贴进⽬录的⽂件,并不能称之为向仓库中新增⽂件,⽽只是在⼯作区新增了⽂件。必须要通过使⽤ git add 和 git commit 命令才能将⽂件添加到仓库中

进⾏管理!!!

  • Git 追踪管理的其实是修改,而不是文件

添加⽂件--场景

在包含 .git 的⽬录下新建⼀个 Fileme ⽂件,我们可以使⽤ git add 命令可以将⽂件添加到暂存区.

  • 添加⼀个或多个⽂件到暂存区: git add [file1] [file2] ...
  • 添加指定⽬录到暂存区,包括⼦⽬录: git add [dir]
  • 添加当前⽬录下的所有⽂件改动到暂存区: git add .

再使⽤ git commit 命令将暂存区内容添加到本地仓库中:

  • 提交暂存区全部内容到本地仓库中: git commit -m "message"
  • 提交暂存区的指定⽂件到仓库区: git commit [file1] [file2] ... -m "message"

注意 git commit 后⾯的 -m 选项,要跟上描述本次提交的 message,由⽤⼾⾃⼰完成,这部分内

容绝对不能省略,并要好好描述,是⽤来记录你的提交细节,是给我们开发人员看的.

git commit 命令执⾏成功后会告诉我们,1个⽂件被改动(就是我们新添加的ReadMe⽂件),插

⼊了两⾏内容(ReadMe有两⾏内容)。如下:

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ vim Fileme
[XMLife@VM-8-6-centos Git_code]$ cat Fileme
hello git
[XMLife@VM-8-6-centos Git_code]$ git add Fileme
[XMLife@VM-8-6-centos Git_code]$ git commit -m "commit my first file"
[master (root-commit) 05f37ff] commit my first file
 1 file changed, 1 insertion(+)
 create mode 100644 Fileme

我们还可以多次 add 不同的⽂件,⽽只 commit ⼀次便可以提交所有⽂件,是因为需要提交的⽂件是通通被 add 到暂存区中,然后⼀次性 commit 暂存区的所有修改。如下:

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ touch file1 file2 file3
[XMLife@VM-8-6-centos Git_code]$ git add file1 file2 file3
[XMLife@VM-8-6-centos Git_code]$ git commit -m "add 3 file"
[master 1f3d1a3] add 3 file
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file1
 create mode 100644 file2
 create mode 100644 file3

截⾄⽬前为⽌,我们已经更够将代码直接提交⾄本地仓库了。我们可以使⽤ git log 命令,来查看下历史提交记录.如下:

cpp 复制代码
[XMLife@VM-8-6-centos Git_code]$ git log
commit 1f3d1a3b718a4eab4fb951808b20a9545cbd54a8
Author: XMLife <1277707726@qq.com>
Date:   Tue Sep 26 09:29:33 2023 +0800

    add 3 file

commit 05f37ff848941e9b4c53b0e8daf604f4e18c9f2f
Author: XMLife <1277707726@qq.com>
Date:   Tue Sep 26 08:46:37 2023 +0800

    commit my first file

该命令显⽰从最近到最远的提交⽇志,并且可以看到我们 commit 时的⽇志消息。

如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数:如下:

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ git log --pretty=oneline
1f3d1a3b718a4eab4fb951808b20a9545cbd54a8 add 3 file
05f37ff848941e9b4c53b0e8daf604f4e18c9f2f commit my first file

需要说明的是,我们看到的⼀⼤串类似1f3d1a...05f37ff 的是每次提交的 commit id (版本

号),Git 的 commit id 不是1,2,3......递增的数字,⽽是⼀个 SHA1加密 计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表⽰(你看到的 commit id 和我的肯定不⼀样,以你⾃⼰的为准)


查看 .git ⽂件

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ ll -al
total 16
-rw-rw-r-- 1 XMLife XMLife    0 Sep 26 09:28 file1
-rw-rw-r-- 1 XMLife XMLife    0 Sep 26 09:28 file2
-rw-rw-r-- 1 XMLife XMLife    0 Sep 26 09:28 file3
-rw-rw-r-- 1 XMLife XMLife   10 Sep 26 08:45 Fileme
drwxrwxr-x 8 XMLife XMLife 4096 Sep 26 09:29 .git

.git 是我们的版本库 (仓库)

其余文件是我们的工作区.

先来看看我们的 .git 的⽬录结构:

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ tree .git/
.git/
|-- branches
|-- COMMIT_EDITMSG
|-- config
|-- description
|-- HEAD
|-- hooks
|   |-- applypatch-msg.sample
|   |-- commit-msg.sample
|   |-- post-update.sample
|   |-- pre-applypatch.sample
|   |-- pre-commit.sample
|   |-- prepare-commit-msg.sample
|   |-- pre-push.sample
|   |-- pre-rebase.sample
|   `-- update.sample
|-- index
|-- info
|   `-- exclude
|-- logs
|   |-- HEAD
|   `-- refs
|       `-- heads
|           `-- master
|-- objects
|   |-- 05
|   |   `-- f37ff848941e9b4c53b0e8daf604f4e18c9f2f
|   |-- 1f
|   |   `-- 3d1a3b718a4eab4fb951808b20a9545cbd54a8
|   |-- 2a
|   |   `-- 318fbaab981ff723a3621e39c862bbfa0b8082
|   |-- 8d
|   |   `-- 0e41234f24b6da002d962a26c2495ea16a425f
|   |-- e6
|   |   `-- 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
|   |-- ef
|   |   `-- 877764d92409acd539cdf1408ddb8e859d7785
|   |-- info
|   `-- pack
`-- refs
    |-- heads
    |   `-- master
    `-- tags

18 directories, 24 files
  1. index 就是我们的暂存区,add 后的内容都是添加到这⾥的.
  2. HEAD 就是我们的默认指向 master 分⽀的指针.
c 复制代码
[XMLife@VM-8-6-centos Git_code]$ cat .git/HEAD
ref: refs/heads/master

⽽默认的 master 分⽀,其实就是

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ cat .git/refs/heads/master
1f3d1a3b718a4eab4fb951808b20a9545cbd54a8

打印的 1f3d1a3b718a4eab4fb951808b20a9545cbd54a8是什么东西呢?保存的就是当前最新的 commit id

  1. objects 为 Git 的对象库,⾥⾯包含了创建的各种版本库对象及内容。当执⾏ git add 命令
    时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新的对象中,就位于 ".git/objects" ⽬录下,让我们来看看这些对象有何⽤处:
cpp 复制代码
[XMLife@VM-8-6-centos Git_code]$ ls .git/objects/
05  1f  2a  8d  e6  ef  info  pack

查找 object 时要将 commit id 分成2部分,其前2位是⽂件夹名称,后38位是⽂件名称。

找到这个⽂件之后,⼀般不能直接看到⾥⾯是什么,该类⽂件是经过 sha (安全哈希算法)加密过的⽂件,好在我们可以使⽤ git cat-file 命令来查看版本库对象的内容:

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ git cat-file -p 1f3d1a3b718a4eab4fb951808b20a9545cbd54a8

tree ef877764d92409acd539cdf1408ddb8e859d7785
parent 05f37ff848941e9b4c53b0e8daf604f4e18c9f2f
author XMLife <1277707726@qq.com> 1695691773 +0800
committer XMLife <1277707726@qq.com> 1695691773 +0800

add 3 file

# 这就是我们最近⼀次的提交!

其中,还有⼀⾏ tree ef877764d92409acd539cdf1408ddb8e859d7785 ,我们使⽤同样的⽅

法,看看结果:

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ git cat-file -p ef877764d92409acd539cdf1408ddb8e859d7785
100644 blob 8d0e41234f24b6da002d962a26c2495ea16a425f	Fileme
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	file1
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	file2
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	file3

在看 Fileme 对应的 8d0e41234f24b6da002d962a26c2495ea16a425f :

cpp 复制代码
[XMLife@VM-8-6-centos Git_code]$ git cat-file -p 8d0e41234f24b6da002d962a26c2495ea16a425f
hello git
# 这是我们对ReadMe做的修改!!被git记录了下来!!

回过头我们在看看 parent 05f37ff848941e9b4c53b0e8daf604f4e18c9f2f

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ git cat-file -p 05f37ff848941e9b4c53b0e8daf604f4e18c9f2f
tree 2a318fbaab981ff723a3621e39c862bbfa0b8082
author XMLife <1277707726@qq.com> 1695689197 +0800
committer XMLife <1277707726@qq.com> 1695689197 +0800

commit my first file

他保存的是我们上一次提交的记录

  • 总结
    在本地的 git 仓库中,有⼏个⽂件或者⽬录很特殊
  • index: 暂存区, git add 后会更新该内容。
  • HEAD: 默认指向 master 分⽀的⼀个指针。
  • refs/heads/master: ⽂件⾥保存当前 master 分⽀的最新 commit id 。
  • objects: 包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改。

添加⽂件--场景⼆

我们已经清楚了如何向仓库中添加⽂件,并且对于⼯作区、暂存区、版本库也有了⼀定

的认识。那么我们再展⽰⼀种添加⽂件的场景,能加深对⼯作区、暂存区、版本库.

c 复制代码
[XMLife@VM-8-6-centos Git_code]$ touch file4
[XMLife@VM-8-6-centos Git_code]$ git add file4
[XMLife@VM-8-6-centos Git_code]$ touch file5
[XMLife@VM-8-6-centos Git_code]$ git commit -m "add file"
[master bcadde4] add file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file4

提交后发现打印了 1 file changed, 0 insertions(+), 0 deletions(-) ,意思是只有⼀个⽂件改变了,这时我们提出了疑问,不是新增了两个⽂件吗?

再来回忆下, git add 是将⽂件添加到暂存区, git commit 是将暂存区的内容添加到本地仓库

中。由于我们并没有使⽤ git add file5 ,file5 就不在暂存区中维护,所以我们 commit 的时候

其实只是把已经在暂存区的 file4 提交了,⽽遗漏了⼯作区的 file5。如何提交 file5 呢?很简单,再次add , commit 即可,

相关推荐
GoppViper1 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
m0_464832363 小时前
Linux服务器上安装git lfs命令
git
贩卖纯净水.10 小时前
白月光git
git·github
爱吃瓜的猹z14 小时前
git reset 几点疑问
git·源代码管理
悟空201620 小时前
001、Git开发流程规范
git
Li小李同学Li20 小时前
git学习【持续更新中。。。】
git·学习·elasticsearch
晨春计1 天前
【git】
android·linux·git
念幽1 天前
Git常用命令
git
神技圈子1 天前
【git系列】git中的那些迷惑的术语以及概念详解
git
benben0441 天前
Photoshop使用方法大全
git