当前位置: 首页 > news >正文

借助AI学习开源代码git0.7之编译和使用

如何学习优秀的开源代码?目前大部分的优秀开源代码,代码量都已经非常庞大,比如git。以git为例,git最新版本代码有279814行,
而git0.7版本已经大部分实现了现在git版本的基本功能,而代码量却只有4950行,
借助ai工具帮忙分析和整理,加上自己的代码阅读和学习验证,就可以从这些开源大神的代码中学到很多,从而提高自己。
学习源码之前,先编译和研究下现有编译的程序的使用。

编译

本人使用的笔记本是macbook,所以下面的是在macsos下编译,window和linux需自行验证。
执行make命令,报错如下:
“编译失败了,错误信息是 openssl/sha.h: No such file or directory。”

Makefile 默认使用 OpenSSL 的 SHA1 实现,但我的macos环境中没有安装OpenSSL的开发库,
不过项目本身在mozilla-sha1/和ppc/目录下提供了SHA1的实现。
可以修改Makefile来使用这些内置的实现。

修改Makefile

修改如下:

diff --git a/cpp/git-0.7/Makefile b/cpp/git-0.7/Makefile
index a4987f3..aa52a05 100755
--- a/cpp/git-0.7/Makefile
+++ b/cpp/git-0.7/Makefile
@@ -39,7 +39,7 @@ LIB_H += diff.hLIB_OBJS += diff.oLIBS = $(LIB_FILE)
-LIBS += -lz -lcrypto
+LIBS += -lzifdef MOZILLA_SHA1SHA1_HEADER="mozilla-sha1/sha1.h"
@@ -50,7 +50,7 @@ ifdef PPC_SHA1LIB_OBJS += ppc/sha1.o ppc/sha1ppc.oelseSHA1_HEADER=<openssl/sha.h>
-  LIBS += -lssl
+  LIBS += -lssl -lcryptoendifendif

重新编译

make MOZILLA_SHA1=1
ok,编译成功了。
会在当前目录生成很多git-*的可执行程序。
0.7版本的git,命令都是以git-开头的,比如git-init-db,git-update-cache,git-write-tree,git-commit-tree等。不像现在的git,命令都是git开头的,比如git init,git add,git commit等。

学习使用

先使用,才能更好地去学习源码。把当前目录加入PATH中方便使用命令(后续命令都是按加入PATH中)。
根据 README 中的 “Workflow” 部分,一个基本的使用流程如下:

第一步:初始化一个新的 “git” 仓库

创建一个 .git 目录,里面包含了对象数据库 (.git/objects) 和其他必要的文件。

mkdir ~/git_test
cd ~/git_test
git-init-db

第二步:将文件添加到暂存区 (index)

创建一个测试的新文件 hello.txt。

  1. touch hello.txt
  2. echo “hello world” > hello.txt
  3. git-update-cache --add hello.txt

其中git-update-cache命令会:

  1. 为 hello.txt 创建一个 blob 对象,并将其存入对象数据库。
  2. 在 index 文件中记录 hello.txt 的信息(文件名、权限、SHA1 等)。

第三步:创建一个 tree 对象

tree 对象代表了当前暂存区 (index) 的状态。
git-write-tree
这个命令会输出一个40个字符的SHA1哈希,这就是新创建的tree对象的 ID。需要记下这个ID。

第四步:创建一个 commit 对象

这个 commit 对象会将上一步创建的 tree 对象与一个提交信息和父提交(如果有的话)关联起来。

  1. 假设上一步得到的 tree SHA1 是 <tree_sha1>
  2. -p <parent_sha1> 是可选的,第一次提交没有父提交
  3. echo “Initial commit” | ./git-commit-tree <tree_sha1>

注意git0.7这个版本,tree_sha1是需要输入完整的字符的。
这个命令会输出一个新的 SHA1 哈希,这是 commit 对象的 ID。可以将这个ID保存到一个文件里,比如.git/HEAD,来跟踪当前的分支。

其他常用命令

  1. git-cat-file
    * 功能: 
    1. 显示对象类型 (-t 选项):
    * 给定一个对象的 SHA1 哈希,它会告诉你这个对象是 blob (文件内容)、tree (目录结构) 还是 commit (提交记录)。
    2. 显示对象内容 (指定类型):
    * 给定一个对象的 SHA1 哈希和其类型(blob、tree 或 commit),它会打印出该对象的原始内容。
    * 用法: 
    git-cat-file -t 查看对象类型。
    git-cat-file 查看对象内容

  2. git-ls-tree
    * 功能:
    1. 列出 tree 对象的内容: 它会解析一个 tree 对象的二进制数据,并以人类可读的格式显示其包含的条目。
    2. 显示文件和子目录: 对于 tree 对象中的每个条目,它会显示其模式(权限)、类型(blob 或 tree)、SHA1 哈希以及对应的文件名或目录名。
    3. 递归显示 (可能): 现代 Git 的 ls-tree 命令通常支持递归显示子目录内容,这个早期版本可能也有类似的功能.

* 用法: git-ls-tree <tree_sha1> 这会列出 tree 对象中的文件和目录。

  1. git-read-tree
    * 功能: 
    1. 更新暂存区: 它的主要作用是用一个指定的 tree 对象所代表的目录结构和文件内容来完全替换或更新当前的暂存区(.git/index 文件)。
    2. 准备工作目录: 当你需要将仓库历史中的某个特定状态(由一个 tree 对象表示)恢复到暂存区时,git-read-tree
    是第一步。例如,在切换分支、合并或检出旧版本时,你首先会使用 git-read-tree 来更新暂存区,然后可能再使用 git-checkout-cache 将暂存区的内容写入工作目录。

* 用法: git-read-tree <tree_sha1>
<tree_sha1>: 你想要加载到暂存区中的 tree 对象的 40 位 SHA1 哈希值。git-read-tree<tree_sha1>这会用指定的tree对象更新 index。

4. git-checkout-cache
* 功能: 
1. 检出 index 中的文件: 它会从 index 中检出文件到工作目录,类似于 git checkout。
2. 检出 index 中的所有文件: 它会检出 index 中的所有文件到工作目录。
* 用法: git-checkout-cache -a 这会检出 index 中的所有文件到工作目录。

  1. git-diff-files
    * 功能: 比较工作目录中的文件与暂存区(index)中的对应文件之间的差异。
    * 用法: git-diff-files 这会显示工作目录中所有已修改但尚未添加到暂存区的文件差异。

  2. git-diff-tree
    * 功能: 比较两个 tree 对象之间的差异,或者一个 tree 对象与工作目录/暂存区之间的差异。
    * 用法:
    git-diff-tree <tree_sha1_1> <tree_sha1_2>
    比较两个 tree 对象
    git-diff-tree <tree_sha1>
    比较一个 tree 对象与当前暂存区/工作目录 (具体行为可能需要查看源码或帮助)

  3. git-rev-tree
    * 功能: 遍历一个 tree 对象及其所有子对象(包括 blob 和嵌套的 tree),并打印它们的 SHA1 哈希和路径。
    * 用法: git-rev-tree <tree_sha1> 这类似于 git ls-tree -r 的功能。

  4. git-show-files
    * 功能: 显示暂存区(index)中所有文件的信息,包括模式、SHA1 和文件名。
    * 用法: git-show-files 这类似于 git ls-files --stage。

  5. git-check-files
    * 功能: 检查工作目录中的文件是否与暂存区中的文件匹配。它会报告哪些文件在工作目录中被修改、删除或新增。
    * 用法: git-check-files

  6. git-merge-base
    * 功能: 查找两个或多个提交(commit)的最近共同祖先。这是进行三方合并(three-way merge)的基础。
    * 用法: git-merge-base <commit_sha1_1> <commit_sha1_2> 会输出共同祖先的 SHA1 哈希。

  7. git-merge-cache
    * 功能: 执行三方合并,将三个 tree 对象(通常是共同祖先、分支 A 和分支 B)合并到暂存区(index)中。
    * 用法: git-merge-cache <base_tree_sha1> <our_tree_sha1> <their_tree_sha1>
    这个命令会将合并结果写入暂存区。如果存在冲突,暂存区会包含冲突标记,需要手动解决。

  8. git-unpack-file
    * 功能: 从对象数据库中解压一个 blob 对象并将其内容写入标准输出。
    * 用法: git-unpack-file <blob_sha1> > output_file.txt

  9. git-export
    * 功能: 将一个 tree 对象的内容导出到指定目录。
    * 用法: git-export <tree_sha1> <output_directory>

  10. git-diff-cache
    * 功能: 比较暂存区(index)与一个 tree 对象之间的差异。
    * 用法: git-diff-cache <tree_sha1>

  11. git-rev-list
    * 功能: 遍历提交历史,并以逆序(从最新到最旧)打印提交的 SHA1 哈希。
    * 用法: git-rev-list <commit_sha1> 可以用来查看一个提交的所有祖先。

  12. git-mktag
    * 功能: 创建一个 tag 对象。在 Git 中,标签可以指向一个提交、一个树或一个 blob,通常用于标记重要的版本。
    * 用法: echo “My tag message” | ./git-mktag <object_sha1> <object_type> 它会输出新创建的 tag 对象的 SHA1 哈希。

  13. git-tar-tree
    * 功能: 将一个 tree 对象的内容打包成一个 tar 归档文件。
    * 用法: git-tar-tree <tree_sha1> > archive.tar

总结一下,一个完整的从无到有的提交流程是:(fish shell为例)

  1. git-init-db
  2. 创建或修改文件
  3. git-update-cache --add …
  4. set -x TREE_ID $(git-write-tree)
  5. set -x COMMIT_ID $(echo “My commit message” | git-commit-tree $TREE_ID)
  6. echo $COMMIT_ID > .git/HEAD

这就是这个早期 git 0.7版本的基本用法。它比现代的git要底层和手动得多,但核心概念是一致的。

http://www.dtcms.com/a/281998.html

相关文章:

  • Gradle vs Maven:构建工具世纪对决 —— 像乐高积木与标准模型之间的选择艺术
  • SQL中对字符串字段模糊查询(LIKE)的索引命中情况
  • Git问题排查与故障解决详解
  • C++---emplace_back与push_back
  • 工业网络协议桥接设计指南:从LIN到CAN/RS-232的毫秒级互通方案
  • Adobe illustrator、klayout绘制光刻图及其尺寸映射
  • docker的搭建
  • 微信小程序141~150
  • 控制Vue对话框显示隐藏
  • 实例操作:基于 PipeLine 实现 JAVA项目集成 SonarQube代码检测通知 Jenkins
  • 【Linux】基本指令详解(二) 输入\输出重定向、一切皆文件、认识管道、man、cp、mv、echo、cat
  • 如何配置一个简单的docker容器应用?
  • 【2025/07/16】GitHub 今日热门项目
  • 基于 Spring Boot 构建的文件摆渡系统(File Ferry System)
  • Python19 —— 一维数据的处理
  • 小白成长之路-Elasticsearch 7.0 配置
  • Coze工作流无法更新问题处理
  • 如何通过扫描电镜检测汽车清洁度中的硬质颗粒并获取成分信息
  • 【源力觉醒 创作者计划】百度携文心 4.5 入局,开源大模型市场再添一员猛将,与 Qwen3 对比如何?
  • C++修炼:IO流
  • WPF 多窗口分文件实现方案
  • openEuler 22.03 LTS Rootless Docker 安装指南
  • 【MySQL基础】MySQL事务详解:原理、特性与实战应用
  • 每日算法刷题Day49:7.16:leetcode 差分5道题,用时2h
  • c语言-数据结构-二叉树的遍历
  • 数字ic后端设计从入门到精通11(含fusion compiler, tcl教学)全定制设计入门
  • arm版本的ubuntu安装git或者vim等方法
  • 力扣-23.合并K个升序链表
  • Linux 驱动中 Timer / Tasklet / Workqueue 的作用与对比
  • 查看.bin二进制文件的方式(HxD十六进制编辑器的安装)