.git文件夹学习

转自:https://juejin.cn/post/6844903986839945229

1.内容

.git% ls -lh
total 40
-rw-r--r--   1 x  staff    15B  8 10 00:20 COMMIT_EDITMSG
-rw-r--r--   1 x  staff    23B  8  9 23:57 HEAD
-rw-r--r--   1 x  staff   328B  8  9 23:58 config
-rw-r--r--   1 x  staff    73B  8  9 23:57 description
drwxr-xr-x  15 x  staff   480B  8  9 23:57 hooks
-rw-r--r--   1 x  staff   137B  8 10 00:20 index
drwxr-xr-x   3 x  staff    96B  8  9 23:57 info
drwxr-xr-x   4 x  staff   128B  8 10 00:20 logs
drwxr-xr-x   7 x  staff   224B  8 10 00:20 objects
drwxr-xr-x   5 x  staff   160B  8 10 00:28 refs

2.COMMIT_EDITMSG文件

.git % cat COMMIT_EDITMSG
initial commit 

存储最后一次commit的信息,没有commit过应该就没有这个文件。

COMMIT-EDITMSG是一个临时文件,存储最后一次提交的message,当敲入git commit命令,不加-m的话, 会打开编辑器。
执行git commit -m 'message'时,mssage就是COMMIT_EDITMSG的文件内容。

3.HEAD文件

表名当前在master分支:

.git % cat HEAD 
ref: refs/heads/master

此文件永远存储当前位置指针,指向当前工作区的分支。就像 linux 中的 $PWD 变量(指向当前目录)一样,永远指向当前位置,表明当前的工作位置。

当新建一个分支,并自动切换后,HEAD文件内容更改:

git_test % git checkout -b dev
Switched to a new branch 'dev'

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

查看所有分支:

% git branch
* dev
  master

3.config文件-配置

查看从远程pull到本地的仓储的config文件:

.git % cat config 
[core]
    repositoryformatversion = 0 
    filemode = true //true表示git把文件权限也算作文件差异的一部分,需要git add 才行?
    bare = false //远程的裸仓储,即不维护工作区(写代码)的是true
    logallrefupdates = true
    ignorecase = true  //忽略文件的大小写,如果ignorecase为true,当文件readme.md改为Readme.md,git会忽略这个改动
    precomposeunicode = true
[remote "origin"]
    url = git@MacBook-Pro-2.local:/Users/git/myproj/myproj.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

添加用户配置:

myproj % git config --local user.name bg

.git % cat config 
//多了如下内容:
[user]
    name = bg

直接修改 config 文件和使用命令行修改配置效果一样。

4.description文件

.git % cat description 
Unnamed repository; edit this file 'description' to name the repository.

用于GitWeb,不太了解,暂时不看,应该不重要。

5.index文件(暂存区)

索引文件,二进制格式。

  1. 当执行git add后,文件就会存入Git的对象objects里,并使用索引进行定位。
  2. 所以,只要执行了git add,就算工作目录中的文件被误删除,也不会引起文件的丢失;
  3. 创建了一个提交(commit), 那么提交的是当前索引(index)里的内容, 而不是工作目录中的内容。
在bg的仓储下新建一个文件,并且git add b.txt之后,可以查看到,修改a.txt文件后再次add,对应的编号会有变化。
通过git ls-files命令可以查看缓存区的文件信息:
myproj % vi b.txt
myproj % git add b.txt
myproj % git ls-files --stage
100644 f6581726472c338b7e7d4fc9425535f84c20fcc6 0    a.txt
100644 73944c3c5cd9b1af1e702505589c6580f332d098 0    b.txt

https://blog.51cto.com/u_15072910/3448677 

6.hooks/钩子

存放一些shell脚本,用于在 git 命令前后做检查或做些自定义动作。

如果要启用某个 hook,只需把 .sample(样本) 删除即可,然后编辑其内容来实现相应的逻辑,用shell脚本写就ok。 

//钩子有点像回调函数?只不过回调函数是在结束后触发,这里是命令之前和之后触发都可以。

7.info/

info % ls -F1
exclude
refs

info/exclude,初始化时只有这个文件,用于排除提交文件的规则,用于本地。初始时没有内容。

info/refs,用于跟踪各分支的信息。此文件一般通过命令 git update-server-info 生成,

info % git update-server-info
info % cat refs
594e046e8966ff38ad404791edb66f5a6f1e9e4d    refs/heads/dev  //包括新建的分支
594e046e8966ff38ad404791edb66f5a6f1e9e4d    refs/heads/master
594e046e8966ff38ad404791edb66f5a6f1e9e4d    refs/remotes/origin/HEAD
594e046e8966ff38ad404791edb66f5a6f1e9e4d    refs/remotes/origin/master

 

info/refs其中一个作用就是用于git clone过程。执行git clone ...后,它做的第一件事就是获取 info/refs 文件,这样就知道远程仓库的所有分支和引用信息。

8.logs/

 logs就是用来记录操作信息的,git reflog 命令以及像 HEAD@{1} 形式的路径会用到(?)。目录如下:

logs % tree
.
├── HEAD
└── refs
    ├── heads
    │   ├── feature
    │   │   └── 1
    │   └── master
    └── remotes
        └── origin
            └── master
  • HEAD记录在所有分支上的操作:

  •  refs/heads下面记录自己分支的操作,

通过命令查看如下:

myproj % git reflog
c3a96ee (HEAD -> master) HEAD@{0}: reset: moving to c3a96ee4f
594e046 (origin/master, feature/1) HEAD@{1}: reset: moving to HEAD~1
c3a96ee (HEAD -> master) HEAD@{2}: commit: m a.txt, add b.txt
594e046 (origin/master, feature/1) HEAD@{3}: checkout: moving from feature/1 to master
594e046 (origin/master, feature/1) HEAD@{4}: checkout: moving from master to feature/1
594e046 (origin/master, feature/1) HEAD@{5}: checkout: moving from feature/1 to master
594e046 (origin/master, feature/1) HEAD@{6}: checkout: moving from master to feature/1
594e046 (origin/master, feature/1) HEAD@{7}: commit (initial): initial commit 

9.objects/

 在执行了git add之后,文件会存入objects中:

objects % ls -lh
total 0
drwxr-xr-x  3 x  staff    96B  8 20 13:22 73
drwxr-xr-x  3 x  staff    96B  8 20 13:20 f6
//。。。省略3个旧文件 drwxr
-xr-x 2 x staff 64B 8 9 23:57 info drwxr-xr-x 2 x staff 64B 8 9 23:57 pack

可以通过如下命令,查看文件类型和打印文件内容:

 73 % git cat-file -t 73944c3c5cd9b1af1e702505589c6580f332d098
blob

73 % git cat-file -p 73944c3c5cd9b1af1e702505589c6580f332d098
bg用户新建文件 20220820

格式是:文件名+哈希值(可能是md5之后的结果,应该就是通过md5sum 文件名 ,得到的校验码)。

在初始化的时候,objects里有两个空的文件夹:info和pack,因为Git 往磁盘保存对象时默认使用的格式叫松散对象 (loose object) 格式,当你对同一个文件修改哪怕一行,git 都会使用全新的文件存储这个修改了的文件,放在了objects中,所以就比较占用磁盘空间。

那么git可以打包压缩至二进制文件,

  • Git 时不时地将这些对象打包至一个叫 packfile 的二进制文件以节省空间并提高效率,当版本库中有太多的松散对象,
  • 或者手动执行 git gc 命令,
  • 或者向远程服务器执行推送时,Git 都会这样做。
pack % git gc
枚举对象中: 5, 完成.
对象计数中: 100% (5/5), 完成.
写入对象中: 100% (5/5), 完成.
总共 5(差异 0),复用 0(差异 0),包复用 0

pack % ls
pack-1485273b210e41237b88dab6a74ff8659ec64f95.idx
pack-1485273b210e41237b88dab6a74ff8659ec64f95.pack

info % ls -lh
total 16
-r--r--r--  1 x  staff   1.1K  8 20 15:21 commit-graph
-rw-r--r--  1 x  staff    54B  8 20 15:21 packs

所有5个文件被打包到pack中,.pack 存储对象文件,.idx 是索引文件,用于允许它们被随机访问;info 文件夹记录对象存储的附加信息,这里存储着打包后的文件名。

10.refs/引用

refs文件夹存储着分支和标签的引用。下面创建一个分支feature/1,那么refs目录的项目结构为: 

myproj % git checkout -b feature/1
切换到一个新分支 'feature/1'

refs % tree
.
├── heads
│   └── feature
│       └── 1
├── remotes
│   └── origin
└── tags

5 directories, 1 file

 

//为什么heads下没有master分支了??再运行git update-server-info命令,然后查看info/refs文件:

info % cat refs              
594e046e8966ff38ad404791edb66f5a6f1e9e4d    refs/heads/feature/1
594e046e8966ff38ad404791edb66f5a6f1e9e4d    refs/heads/master
594e046e8966ff38ad404791edb66f5a6f1e9e4d    refs/remotes/origin/master

是本地heads下有master和feature的,为什么tree下看不到?查看对应的文件内容,

refs % cat heads/feature/1
594e046e8966ff38ad404791edb66f5a6f1e9e4d

文件存储的是哈希值。//不太懂什么意思。

  • refs/heads/ 文件夹内的 ref 一般通过 git branch 生成。git show-ref --heads 可以查看;
refs % git show-ref --heads
594e046e8966ff38ad404791edb66f5a6f1e9e4d refs/heads/feature/1
594e046e8966ff38ad404791edb66f5a6f1e9e4d refs/heads/master

这里可以看到哎,heads下是有master的。

  • refs/tags/ 文件夹内的 ref 一般通过 git tag 生成git show-ref --tags 可以查看。//不太知道tags有什么用。

11.packed-refs文件

 https://icode.best/i/76560043735694

  • Git 会不定时地自动运行一个叫做 “auto gc” 的命令,大多数时候,这个命令并不会产生效果。然而,如果有太多松散对象(不在包文件中的对象)或者太多包文件,Git 会运行一个完整的 git gc 命令。“gc” 代表垃圾回收,这个命令会做以下事情:收集所有松散对象并将它们放置到包文件中,将多个包文件合并为一个大的包文件,移除与任何提交都不相关的陈旧对象。

//反正就是和文件打包有关系。不重要吧应该。

posted @ 2022-08-20 16:43  lypbendlf  阅读(543)  评论(0编辑  收藏  举报