侧边栏壁纸
  • 累计撰写 94 篇文章
  • 累计创建 100 个标签
  • 累计收到 10 条评论

目 录CONTENT

文章目录
Git

Git学习-.git目录介绍

汤圆学Java
2022-01-21 / 0 评论 / 0 点赞 / 376 阅读 / 3,584 字
温馨提示:
本文最后更新于 2022-01-21,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

本篇主要介绍了 git 初始化后的 .git 目录,虽然平时我们不用去关注,但是了解一下git的存储原理还是可以的;

目录

  1. git 初始化
  2. objects 目录
  3. refs 目录
  4. HEAD 文件

正文

1. git初始化

这里的初始化有两种方式;

  • 方式1:git init,直接在对应的目录执行git init命令,此时会在当前目录生成一个.git目录

    D:\StudyData\github-project\GitLearning\GitBasic>git init
    Initialized empty Git repository in D:/StudyData/github-project/GitLearning/GitBasic/.git/
    
  • 方式2:git clone,将远程仓库的项目克隆到本地,这种方式的前提是 项目已经存在于git仓库中

    D:\StudyData\github-project\GitLearning\GitBasic>git clone git@github.com:Jalon2015/git-basic-demo.git
    Cloning into 'git-basic-demo'...
    warning: You appear to have cloned an empty repository.
    
    1. 因为这里的远程仓库的项目是空的(刚在GitHub创建的),所以会有一个空项目的提示;

    2. 这里克隆的项目会单独创建一个子目录,存放到当前目录(这一点跟git init不同,git init会直接在当前目录初始化)

不管是哪种方式,都会在对应目录生成一个.git目录,内容如下所示:

image-20220119114814409

  • hooks: 存放钩子脚本,在我们执行git命令时会触发这里的钩子脚本

  • info: 初始化后,默认info内部会生成一个exclude文件,用来记录要排除的文件的忽略模式(即不希望被提交的文件通配符)

    exclude类似于.gitignore,不同的是exclude文件只存在本地,仅自己可见;而.gitignore会被提交,所有人可见

  • objects: 核心目录之一,存放了git仓库的所有数据(下面有详细介绍)

  • refs: 核心目录之一,存放了分支branch、标签tags、远程仓库等数据的指针(下面有详细介绍)

  • config: 配置文件,记录了该项目的git相关配置(这里的git配置会覆盖全局git配置)

  • description: 描述文件,这个文件的作用就是描述该项目的相关信息;

    • 该文件的默认内容为Unnamed repository; edit this file 'description' to name the repository.
    • 该文件不需要我们操作,仅供GitWeb(GitHub的一个前身)使用
  • HEAD:该文件指向当前操作的分支

    当前操作的分支,可通过 git branch 查看

2. objects 目录

上面简单介绍了.git目录的组成,下面我们就详细介绍下.git目录的核心组成

先从 objects目录开始;

objects 目录存放了git的所有数据内容,我们可以把它当作一个数据库(类似于redis键值对形式);

每次我们执行git addgit commit命令时,本质就是把数据保存到objects目录;

刚初始化后的objects目录有两个目录,info和pack,且都为空;

  • 现在我们新建一个a.txt,并执行git add进行提交:
touch a.txt
git add a.txt
  • 此时再查看objects目录,会发现多了一个目录e6,如下所示,这里多出来的/e6/9de29...文件就是刚才我们添加的a.txt,只不过换了一种形式进行保存
$ ls -R
.:
e6/  info/  pack/

./e6:
9de29bb2d1d6434b8b29ae775ad8c2e48c5391

./info:

./pack:
  • 接着执行git commit -m "add a.txt",会发现objects下又多了两个目录,这里多出来的就是提交的数据

这里需要注意一点,我们每执行一次git add或者git commit,就会在objects目录下添加新的目录,而不是覆盖已有的目录,这正是版本控制的强大之处:保存历史记录,进行细粒度的版本管理,方便追溯

3. refs 目录

该目录记录的是分支的引用信息,也就是分支指向的是哪条commit记录;

这里的分支默认为master主分支,后面创建了其他分支会自动添加进来

下面我们用例子来看下:

  • 先查看提交的历史记录
$ git log
commit 72c17db1e70b1399a35ae64c114112ae890d98e4 (HEAD -> master)
Author: jalon2015 <1121263265@qq.com>
Date:   Wed Jan 19 15:56:10 2022 +0800

    update a.txt 2

commit 5e1e2692fd45c6c04b80279d89b6b6c632c2cfc4
Author: jalon2015 <1121263265@qq.com>
Date:   Wed Jan 19 15:27:49 2022 +0800

    update a.txt

commit fdbd487e4167174a4b987dc1f2ce7377a15337c4
Author: jalon2015 <1121263265@qq.com>
Date:   Wed Jan 19 15:19:29 2022 +0800

    add a.txt

可以看到,最新的提交记录为 72c17

  • 再查看.git/refs/heads/master文件,可以看到,指向的就是最新提交
$ cat .git/refs/heads/master
72c17db1e70b1399a35ae64c114112ae890d98e4
  • 此时我们再创建并切换分支dev

    $ git branch dev # 创建分支dev
    
    $ git branch # 查看当前的所有分支
      dev
    * master
    
    $ git switch dev # 切换到dev分支
    Switched to branch 'dev'
    
    

    再次查看refs/heads目录,可以看到多了一个dev文件,这个dev文件存储的就是我们刚才创建的dev分支的引用信息;

    现在我们可以查看下dev文件的内容,如下所示:可以看到,内容就是最新的commit记录

    $ cat .git/refs/heads/dev
    72c17db1e70b1399a35ae64c114112ae890d98e4
    

4. HEAD 文件

这个就比较清晰了,就是存储当前指向的分支;

而分支具体引用的是哪个commit记录,就要去上面的refs中查找了;

  • 我们先看下当前的HEAD文件内容:

    $ cat .git/HEAD
    ref: refs/heads/dev
    

    可以看到,当前指向的是dev分支

  • 当我们切换到master分支时,再查看下:

    $ git switch master
    Switched to branch 'master'
    
    $ cat .git/HEAD
    ref: refs/heads/master
    
    

    可以看到,现在指向的是master分支

总结

.git目录就是git的核心数据存储区,包括所有的数据存储、引用对象、各个分支等信息。

0

评论区