如何学习优秀的开源代码?目前大部分的优秀开源代码,代码量都已经非常庞大,比如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.pswp.cn/diannao/91515.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91515.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/91515.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ObservableCollection全面解析

本文仅作为参考大佬们文章的总结。 ObservableCollection是C#中一个功能强大的动态数据集合类&#xff0c;特别适用于需要数据绑定和UI自动更新的场景。本文将系统性地总结ObservableCollection的核心概念、使用方法、性能优化策略以及在实际项目中的应用实践。 一、Observab…

佰力博检测与您探讨超高温介电测试的应用领域

超高温介电测试是指在极端高温条件下&#xff08;通常高于1000℃&#xff09;对材料的介电性能进行测量和分析的过程。以评估材料在高温环境下的电学性能稳定性&#xff0c;如介电常数、介电损耗、阻抗谱等参数。超高温介电测试需要用到的超高温介电阻抗测试设备&#xff1a;UT…

OneCode自治UI核心组件Layout布局介绍:构建灵活高效的界面布局系统

在现代前端开发中&#xff0c;布局系统扮演着至关重要的角色&#xff0c;它不仅决定了界面的结构美感&#xff0c;更直接影响用户体验和开发效率。OneCode作为一款企业级低代码开发平台&#xff0c;其布局引擎通过精巧的设计实现了简洁API与强大功能的完美平衡。本文将深入剖析…

为何“白名单媒体”是性价比之选?

在信息媒体空前发展的今天&#xff0c;软文营销已成为企业品牌推广的重要手段之一。然而&#xff0c;面对众多媒体&#xff0c;如何选择高性价比的发稿媒体成为许多营销人员的一个课题。其中&#xff0c;“白名单媒体”凭借其高收录率、权威背书等优势&#xff0c;逐渐成为软文…

Python 异步编程之 async 和 await

基础知识 在 Python 中&#xff0c;async 和 await 是用于异步编程的关键字&#xff0c;引入了异步/协程&#xff08;coroutine&#xff09;的概念。核心思想是通过 协程&#xff08;Coroutine&#xff09; 和 事件循环&#xff08;Event Loop&#xff09; 实现非阻塞并发&…

关于接口测试的HTTP基础【接口测试】

HTTP 协议基础知识总结&#xff08;用于 Web API 接口测试&#xff09;接口测试中最常用的通讯协议就是 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;&#xff0c;本节旨在帮助理解 HTTP 协议的结构、工作流程以及如何用于接口测试。一、HTTP 协议简介HTTP 是一种…

STM32 DMA通信详解

STM32 DMA通信详解DMA(Direct Memory Access&#xff0c;直接内存访问)是STM32微控制器中一种重要的数据传输机制&#xff0c;它允许外设与内存之间或内存与内存之间直接传输数据&#xff0c;而无需CPU的干预。这种机制可以显著提高系统性能&#xff0c;特别是在需要高速数据传…

pytest--1--pytest-mock常用的方法

1. mocker.patch mocker.patch 是最常用的方法&#xff0c;用于替换指定的对象或方法。它可以用于模拟函数、方法、类或模块。 语法 mocker.patch(target, newDEFAULT, specNone, createFalse, spec_setNone, autospecNone, new_callableNone, **kwargs)示例 import pytest fro…

尚庭公寓----------分页查询

根据条件分页查询公寓列表 进行分页配置 package com.nie.lease.common.mybatisplus;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.in…

【图像质量评价指标】图像熵(Image Entropy) —— 熵值饱和现象

文章目录一、图像熵&#xff08;Image Entropy&#xff09;&#xff08;1&#xff09;基本原理&#xff08;2&#xff09;优势与局限&#xff08;3&#xff09;推荐策略多指标联合推荐体系噪声应对机制建议二、项目实战 —— 通过图像熵评价序列图像&#xff0c;并提取最优图像…

GaussDB in的用法

1 in的作用in运算符允许您在WHERE子句中指定多个值。 in运算符是多个OR条件的简写。2 in的语法select column_name(s) from table_name where column_name in (value1, value2, ...); 或者 select column_name(s) from table_name where column_name in (select statement);3 i…

【C语言进阶】内存函数

目录 1.memcpy函数 1.1 模拟实现 2.memmove函数 3.memcmp函数 1.memcpy函数 字符串拷贝strcpy和strncpy是有一定局限性的&#xff0c;只能拷贝字符串&#xff0c;而memcpy可以拷贝任意类型的数据&#xff0c;单位是字节。 1.1 模拟实现 #include<stdio.h> #include&l…

从乱序到整洁:Swift 实现奇偶链表重排的最佳方案

文章目录摘要描述题解答案题解代码分析分段讲解示例测试及结果时间复杂度空间复杂度总结摘要 在开发中&#xff0c;链表结构经常出现在缓存淘汰、操作系统任务调度、或是 LRU 算法中&#xff0c;尤其是对节点位置的灵活操作更是链表的强项。LeetCode 第 328 题「奇偶链表」就给…

WPF+CEF 执行JS报错

WPFCEF 执行JS报错 在WPF中执行 webBrowser.EvaluateScriptAsync(“window.scrollBy(0, 1000);”); 在部分网站会报异常&#xff1a; Request BrowserId : XXXX not found it’s likely the browser is already closed环境 .Net Framework 4.7 CefSharp.Wpf 131.3.50 解决方案&…

【Python3-Django】快速掌握DRF:ModelViewSet实战指南

DRF讲解 1. 什么是 Django 和 Django REST Framework&#xff1f; 在深入 ModelViewSet 之前&#xff0c;我们先简单了解一下背景知识&#xff1a; Django 是一个基于 Python 的 Web 开发框架&#xff0c;旨在帮助开发者快速构建安全、可扩展的 Web 应用。它遵循“不要重复自己…

TRAE IDE** 下载、安装、开发、测试和部署 2048 小游戏的全流程指南

以下是一份完整的 TRAE IDE 下载、安装、开发、测试和部署 2048 小游戏的全流程指南。整个过程基于 TRAE 作为 AI 辅助编程工具的特性&#xff08;对标 Cursor/AWS Kiro&#xff09;&#xff0c;假设它支持智能代码生成和云部署功能。 【插播】腾讯云AI Coding大赛https://mar…

重学前端005 --- 响应式网页设计 CSS 盒子模型

文章目录BOX 盒子概念CSSoverflow: hidden;filter: blur(3px);box-shadow: 0 0 3px 3px #efb762;border-radius: 30px 25px 60px 12px;transform: rotate(-0.6deg);每个 HTML 元素都是一个盒子&#xff0c;它拥有着自己的间距和边框。这叫作“盒子模型”。 BOX 盒子概念 内容…

TC500R立式加工中心主轴箱机械结构设计cad【11张】三维图+设计说明书

TC500R立式加工中心主轴箱机械结构设计 摘 要 数控机床作为工业制造的基础&#xff0c;在国家的发展中起着非常重要的作用。随着我国经济的快速发展&#xff0c;我国已经成为工业制造大国&#xff0c;制造业的发展离不开数控机床&#xff0c;而TC500R立式加工中心作为数控机床…

CSS Grid布局:构建现代网页的强大网格系统

目录 一、Grid布局基础概念 1.1 网格容器与网格项 1.2 创建基本网格 二、核心属性详解 2.1 定义网格轨道 2.2 网格间距控制 2.3 网格项对齐方式 三、实战布局技巧 3.1 创建经典布局 3.2 网格项定位技巧 3.3 响应式网格设计 四、Grid布局 vs Flexbox布局 五、高级…

Elasticsearch / MongoDB / Redis / MySQL 区别

1、一句话简介名称核心用途Elasticsearch强大的全文检索与日志分析引擎MongoDB灵活的文档数据库&#xff0c;适合半结构化/结构化数据Redis高性能的内存键值缓存数据库&#xff0c;用于实时高并发处理MySQL经典关系型数据库&#xff0c;强事务支持&#xff0c;结构化数据持久存…