阅读 git 最初版源码总结

7 篇文章 0 订阅

阅读 git 第一版源码有利于加深对 git 的理解,也可以通过阅读优雅的代码提高个人的编程技能。

准备工作

准备源码

下载 git 源码

git clone https://github.com/git/git.git

查询第一次提交的记录

git log --reverse

切换到最初版本

git checkout e83c5163316

安装库

程序使用到 sha 函数库 和 zlib 函数库:

sudo apt install zlib1g-dev
sudo apt install libssl-dev

相关函数库的使用示例参照:

编译

修改Makefile,在Makefile 的 LIBS 变量后添加 -lz -cyrpto,如下

LIBS= -lssl -lz -lcrypto

编译

make all

生成以下 7 个可执行程序。

  • init-db
  • update-cache
  • write-tree
  • commit-tree
  • read-tree
  • cat-file
  • show-diff

相关概念

第一版的git中有三种对象,关系如下图所示:

  • blob : 即普通文件被压缩后的格式。
  • tree : 记录当前已经添加的文件信息,根据 index 文件生成。
  • commit : 记录提交的 tree 信息以及作者和日志等其他信息。
    在这里插入图片描述

完整的命令执行流程

$ ./init-db 
defaulting to private storage area

$ ./update-cache file.txt 

$ ./write-tree 
f6edc0f50407d4dc262fe150f34cc71050548e68

$ ./commit-tree f6edc0f50407d4dc262fe150f34cc71050548e68 < changelog 
Committing initial tree f6edc0f50407d4dc262fe150f34cc71050548e68
1a3eba95a112f5b6c47d809b79055e177b6c64c1

$ ./read-tree f6edc0f50407d4dc262fe150f34cc71050548e68
100664 file.txt (0a3b8a9755adc2ed0776337ce2ee6b144bf854c2)

$ ./cat-file 0a3b8a9755adc2ed0776337ce2ee6b144bf854c2
temp_git_file_Lfe8J6: blob

$ cat temp_git_file_Lfe8J6 
hello world!

$ ./show-diff 
file.txt: ok

详细每步分析

  • init-db: 初始化 git 仓库,会创建一个目录结构,用于存放压缩后的文件和提交记录。相当于git init

    仓库的目录结构如下图:

    ./.dircache/
    └── objects
        ├── 00
        ├── 01
        ├── 02
        ├── 03
        ├── 04
        ├── 05
        ├── 06
        ...
        ├── fa
        ├── fb
        ├── fc
        ├── fd
        ├── fe
        └── ff
    
  • update-cache 用于将文件添加到仓库中,并将记录写入staging index。相当于 git add

    $ ./update-cache file.txt 
    

    程序会将文件添加一个blob 头,再压缩,然后求sha1值。以前两位作为文件目录,后面的值作为文件名。比如创建文件 file.txt。

    echo "hello world!" > file.txt
    

    程序会将文件重写如下:

    blob 13^@hello world!
    

    再压缩,求sha1 哈希,得到的值 0a3b8a9755adc2ed0776337ce2ee6b144bf854c2
    其中 0a为文件目录,3b8a9755adc2ed0776337ce2ee6b144bf854c2 为文件名。

    命令执行过后,仓库的目录结构下图:

    ./.dircache/
    ├── index
    └── objects
        ├── 00
        ├── 01
        ...
        ├── 09
        ├── 0a
        │   └── 3b8a9755adc2ed0776337ce2ee6b144bf854c2
        ├── 0b
        ├── 0c
        ...
        ├── fe
        └── ff
    
  • write-tree: 根据 index文件的内容生成一个 tree 对象,并将其加入仓库。tree对象包含着提交的各个文件的文件名和对应的 sha1 值。

    $ ./write-tree 
    f6edc0f50407d4dc262fe150f34cc71050548e68
    

    命令执行过后,仓库的目录结构下图:

    ./.dircache/
    ├── index
    └── objects
        ├── 00
        ├── 01
        ...
        ├── 09
        ├── 0a
        │   └── 3b8a9755adc2ed0776337ce2ee6b144bf854c2
        ├── 0b
        ├── 0c
        ...
        ├── f5
        ├── f6
        │   └── edc0f50407d4dc262fe150f34cc71050548e68
        ├── f7
        ├── f8
    	...
        ├── fe
        └── ff
    
  • commit-tree: 提交这个tree 对象,生成一条提交记录,并加入仓库,这条提交记录指向tree 对象,并且包含相应的作者信息和日志。

    $ ./commit-tree f6edc0f50407d4dc262fe150f34cc71050548e68 < changelog 
    Committing initial tree f6edc0f50407d4dc262fe150f34cc71050548e68
    1a3eba95a112f5b6c47d809b79055e177b6c64c1
    

    命令执行过后,仓库的目录结构下图:

    .dircache/
    ├── index
    └── objects
        ├── 00
        ├── 01
    	...
    	├── 09
        ├── 0a
        │   └── 3b8a9755adc2ed0776337ce2ee6b144bf854c2
        ├── 0b
        ├── 0c
    	...
        ├── 19
        ├── 1a
        │   └── 3eba95a112f5b6c47d809b79055e177b6c64c1
        ├── 1b
        ├── 1c
      	...
        ├── f5
        ├── f6
        │   └── edc0f50407d4dc262fe150f34cc71050548e68
        ├── f7
        ├── f8
    	...
        ├── fe
        └── ff
    
  • read-tree: 用于输出指定的 tree 对象内容。

    $ ./read-tree f6edc0f50407d4dc262fe150f34cc71050548e68
    100664 file.txt (0a3b8a9755adc2ed0776337ce2ee6b144bf854c2)
    
  • cat-file: 通过 sha1 值去git仓库读取相应的文件,解压缩并生成一个临时文件。使用普通的文本工具可以读取其内容。相当于 git show

    $ ./cat-file 0a3b8a9755adc2ed0776337ce2ee6b144bf854c2
    temp_git_file_Lfe8J6: blob
    $ cat temp_git_file_Lfe8J6 
    hello world!
    
  • show-diff: 通过比对当前目录下和index记录的同名文件不同。相当于 git diff

    $ ./show-diff 
    file.txt: ok
    

参考:

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
git 微信抽奖源码指的是使用Git版本控制系统来管理和分享微信抽奖项目的源代码。 首先,在Git上创建一个新的仓库,用于存储微信抽奖项目的源码。可以选择在本地创建一个新的文件夹作为项目的目录,然后通过Git的命令行工具来进行初始化,或者直接使用Git客户端进行操作。之后,将该项目目录与Git仓库进行关联,并将项目的初始代码上传至Git仓库中。 接下来,可以使用Git的分支和合并功能来进行代码的修改和流程的管理。可以根据具体需求创建不同的分支,如开发分支、测试分支等。在开发过程中,可以多次进行代码提交,通过Git的提交历史记录来追踪代码的改动和版本更新。如果需要修改代码,可以在相应的分支下创建一个新的分支,并在该分支上进行代码的修改,保持原有分支的代码完整性。 同时,可以使用Git的标签功能来标记项目中的重要节点,如版本发布、功能上线等。可以在需要标记的节点上创建一个新的标签,并附上相应的描述信息,方便查找和回溯。 此外,Git还提供了协作功能,可以方便地与团队成员共享和合作开发项目。可以克隆远程仓库到本地,进行代码的拉取和推送操作,实现团队成员之间的代码同步和协同开发。 总之,通过Git版本控制功能和协作功能,可以方便地管理和分享微信抽奖项目的源码,保证代码的可追踪性和团队的协同效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lylhw13_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值