美文网首页Git系列篇
用Git来分析Git是怎么通过.git/来实现版本控制的

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

作者: 拙峰朽木 | 来源:发表于2017-06-15 16:11 被阅读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
    

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

    • COMMIT_EDITMSG:保存最近一次的commit_msg
    • refs/heads/master目录下则是保存最近一次的commit_id:
    • **git add ** 会导致objects下生成一个哈希值
    • git commit会导致objects下生成两个哈希值
    • logs/目录下的HEAD是保存所有的log信息的

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/hfhuqxtx.html