Git系列篇

用Git来分析Git是怎么通过.git/来实现版本控制的

2017-06-15  本文已影响21人  拙峰朽木

本还未完结,目前更偏向自己的笔记,后期再整理。

新建一个空的GitStudy文件目录,然后使用git init对其初始化,此时这个文件目录就被加入git管理了。本来这个是个空目录,但是在执行玩git init后我们发现里面有个.git的隐藏目录(. ..这两个是ubuntu自带的)。

frc@frc:~/GitHub/study/GitStudy$ ls -a
.  ..  .git

打开文件目录,想看看里面的结构,发现一个个点好麻烦,此时就想到能不能在终端中显示它的结构树,然后就在终端中输入: tree .git/,没想到还真给提示了,说我没有安装tree,需要安装。sudo install tree就ok了,然后再执行tree .git/

image.png

整体结构一目了然,尤其最后一行9 directories, 14 files,告诉我们有9个目录,14个文件。
我们发现里面很多的目录都是空的,而且有些文件名比较熟悉,比如:HEAD,config还有写目录名也挺熟悉的,比如:branchs , tags。

那么下面我们就要对GitStudy这个目录做一些修改提交操作,然后看看.git目录都做了哪些操作。怎么观察改变呢,用git啊。用git来监控.git/目录的改变。哈哈哈,是不是很天才。如何来做呢,我们进入.git/目录,然后**git init **就行了。

frc@frc:~/GitHub/study/GitStudy$ cd .git/

frc@frc:~/GitHub/study/GitStudy/.git$ ls
branches  config  description  HEAD  hooks  info  objects  refs

frc@frc:~/GitHub/study/GitStudy/.git$ git init
已初始化空的 Git 仓库于 /home/frc/GitHub/study/GitStudy/.git/.git/

frc@frc:~/GitHub/study/GitStudy/.git$ ls -a
.  ..  branches  config  description  .git  HEAD  hooks  info  objects  refs

然后把里面的文件提交:

image.png

我们看到此时的./git目录下也有了./git目录。好吧下面回到GitStudy/我们创建一个REDME.txt文件,然后使用git status查看下状况:

image.png

此时git告诉我们有个变更的文件,然后我们进入.git/目录,然后使用git status看下./git目录有没有变化:

frc@frc:~/GitHub/study/GitStudy$ cd .git/

frc@frc:~/GitHub/study/GitStudy/.git$ git status
位于分支 master
无文件要提交,干净的工作区

此时它告诉我们并没有什么改动。
回到上级目录,我此时使用git add将REDME.txt文件加入暂缓区

frc@frc:~/GitHub/study/GitStudy$ git add REDME.txt 

此时再进入.git/目录(晕了),然后使用git status再看下:

image.png

哎!让哥逮着了吧。看看都有啥变动。瞅了下index打不开,用命令行打开,全是乱码:

image.png
先放着。我们来看看objects/这个目录。 image.png

我们发现多了个44的目录,而目录下只保存了一串哈希值,难道这跟我提交的生成的commit_id的哈希值有关?(下面证明毛关系啊,只是个唯一标识)

现在回到上级目录,然后commit ,commit成功后git log看下里面的log信息:

frc@frc:~/GitHub/study/GitStudy$ git log
commit 40c72db34529598d5ecf5153f009589c04ed9048
Author: fengrongcheng <fengrongcheng2017@outlook.com>
Date:   Thu Jun 15 11:34:33 2017 +0800

    first commit

然后到.git/中使用用git status看下变更:

image.png

我们看到index文件被修改了,看下COMMIT_EDITMSG

image.png

是我刚才提交时的备注。
再看下logs/

image.png

看下HEAD:

image.png

看下组成:commit_id+作者+邮箱+时间+备注。这个是不是和我们上面使用**git log **输出的信息一样。
在看了下refs/heads/master 里面内容一样的。

下面再看下objects的变化

frc@frc:~/GitHub/study/GitStudy/.git$ tree  objects/
objects/
├── 40
│   └── c72db34529598d5ecf5153f009589c04ed9048
├── 44
│   └── bbec9e9b949e96bae4a10c33844e28c84f9aa4
├── d2
│   └── 4eb685594287d46e0c6717aee6466df9680d7f
├── info
└── pack

5 directories, 3 files

我们看到objects中比我们之前add后多了2个目录:40d2。而且他们里面的哈希值跟commit_id不一样(40c72db34529598d5ecf5153f009589c04ed9048),所以我之前的猜测不对啊。

继续最后一个是refs,进到它里面的master看下,里面就一行

40c72db34529598d5ecf5153f009589c04ed9048

终于找到个跟commit_id一样的了。

我们通过上面有很多不同路径下相同名称的文件,比如:refs,HEAD,master。还有些空目录。目测是因为我们操作太少。

我们现在对REDME.txt再进行修改并提交,再到.git/中看它的变化:

    修改:     COMMIT_EDITMSG
    修改:     index
    修改:     logs/HEAD
    修改:     logs/refs/heads/master
    修改:     refs/heads/master

未跟踪的文件:
  (使用 "git add <file>..." 以包含要提交的内容)

    objects/ce/
    objects/db/
    objects/92/

发现logs/HEAD和logs/refs/heads/master内容一样,保存了这两次的提交信息:

0000000000000000000000000000000000000000 40c72db34529598d5ecf5153f009589c04ed9048 fengrongcheng <fengrongcheng2017@outlook.com> 1497497673 +0800        commit (initial): first commit
40c72db34529598d5ecf5153f009589c04ed9048 ce97d3ee3e85989f86e655c81a3d4d6a17461dfa fengrongcheng <fengrongcheng2017@outlook.com> 1497500926 +0800        commit: first change
~                                                                                     
~              

而COMMIT_EDITMSG则保存这最近一次的备注(以后叫commit_msg):

first change

refs/heads/master目录下则是保存最近一次的commit_id:

ce97d3ee3e85989f86e655c81a3d4d6a17461dfa

objects目录下又添加了三个哈希值。

我来看下现在.git/的结构:

frc@frc:~/GitHub/study/GitStudy$ 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
│   ├── pre-receive.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 40
│   │   └── c72db34529598d5ecf5153f009589c04ed9048
│   ├── 44
│   │   └── bbec9e9b949e96bae4a10c33844e28c84f9aa4
│   ├── 92
│   │   └── 516e223eaf9b259248fb774495c7f3c357e956
│   ├── ce
│   │   └── 97d3ee3e85989f86e655c81a3d4d6a17461dfa
│   ├── d2
│   │   └── 4eb685594287d46e0c6717aee6466df9680d7f
│   ├── db
│   │   └── 1e64707bd6061984b8db2f2c01a693a1a21a0e
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

18 directories, 25 files

根据以上的尝试能得出以下的结论:

由于尝试数据有限,得出结论可能不准。

上一篇下一篇

猜你喜欢

热点阅读