通过阅读Git的代码来提高您的编程技巧

2021-03-13 12:32:57

这些日子有很多时尚的方式来提高您的编程技能和知识,包括:

这些方法中的每一种都会吸引不同的人,每个方法都有一个肯定会让你更好的程序员。如果您是中间或高级编码器,则几乎确定您至少尝试过一次这些方法。

然而,还有另一种方法是,绝大多数开发人员忽视,这是我看来的耻辱,因为它有很多东西。这种方法是通过阅读,分析和解现有,高质量的码票来学习!

我们很幸运能够通过高质量,自由和开源(FOSS)项目往往免费获得良好代码的时间。它需要不到一分钟,克隆这些代码库的副本,从像Github或Bitbucket等网站到我们的本地机器。

此外,像Git这样的现代版本控制系统允许我们在其开发历史记录中的任何时候查看代码。显然,我们的鼻子面前有丰富的信息!

在本文中,我们将讨论Git' s代码的原始版本,以突出显示读取现有代码如何帮助提高您的编码技巧。

我们将涵盖为什么它&#39值得了解Git' s代码,如何访问git' s代码,并查看一些相关的C编程概念。

我们将提供Git'原始CodeBase结构的概述,并学习Git' S核心功能如何在代码中实施。

最后,我们将为好奇的开发人员推荐一些后续步骤,以继续从Git' s代码和其他项目学习。

git' s codebase是一个令人难以置信的资源,用于中间开发人员,以进一步编程知识和技能。以下是' s值得挖掘git'代码的7个原因:

1)Git可能是今天使用的最受欢迎的软件开发工具。简而言之,如果你'重新开发人员,你可能会使用git。学习Git' S代码的工作如何让您更深入地了解每天工作的重要工具。

2)Git很有趣! git是一个多功能的工具,解决了许多有趣的问题,以允许开发人员在代码上协作。作为一个好奇的人,我非常喜欢了解更多信息。

3)Git' s代码是用C编程语言编写的,为开发人员提供了一个很好的机会,将分支为重要的语言,他们可能无法使用。

4)GIT利用许多重要的编程概念,包括内容可寻址的数据库,文件压缩/通货膨胀,散列函数,缓存和简单数据模型。 git' s代码说明了如何在实际项目中实现这些概念。

5)Git' s代码和设计优雅。这是一个功能性,最简单的代码库的一个很好的例子,以清晰,有效的方式完成其目标。

6)Git' s初始提交大小很小 - 它仅由10个文件组成,包含少于1,000行的代码。与大多数其他项目相比,这非常小,并且非常可管理在合理的时间内理解。

7)Git' s初始提交中的代码可以成功编译和执行。这意味着您可以使用并测试Git' s代码的原始版本,以了解它的工作原理。

现在,让我们看看如何访问Git' s代码的原始版本。

git' s codebase的官方副本托管在此公共github存储库中。但是,我创建了一个git' s codebase的叉子,并为源代码添加了广泛的内联评论,以帮助开发人员通过行轻松阅读IT线。

自从我在Git&#39的历史中致力于第一次提交,因为我将这个项目名字命名为宝宝Git。婴儿GIT CodeBase位于此公共Bitbucket存储库中。

我建议通过在终端中运行以下命令,将婴儿git codebase克隆到本地计算机:

如果您想坚持Git' s原始代码库(没有我添加的广泛评论),请使用此命令:

通过运行命令CD Git来浏览到新GIT目录。随意戳在这里的文件夹和文件周围。

您' ll快速注意到当前版本的git - 目前在工作目录中签出的版本 - 有很多文件包含很多很长而复杂的代码。

显然,这个当前版本的Git对于单个开发人员来说太大,以便在合理的时间内熟悉。

这显示了Git' s提交登录的git&#39的列表,从git' s初始提交开始。请注意,列表中的第一个提交ID为E83C5163316F89BFBDE7D9AB23CA2E25604AF290。

通过运行命令查看此提交到工作目录的内容:

这将git放入分离的头状态,将git'原始代码文件放入工作目录中。

现在运行ls命令列出这些文件,并注意只有10实际包含代码! (第11个只是一个自述人士)。了解这些文件中的代码对于中间开发人员来说是完全可管理的!

注意:如果您使用我的婴儿git存储库,请' ll想要运行命令git checkout master以放弃分离的头部并移回主分支的尖端。这将使您能够查看描述Git' S代码如何按行的所有内联评论!

在直接进入Git' s代码之前,它有助于获得在整个代码库中出现的几个C编程概念的修复。

C头文件是在.h扩展中结尾的代码文件。标题文件用于存储开发人员想要在多个.c源代码文件中包含的变量,函数和其他c对象使用#include" headerfile.h"指示。

如果您熟悉Python或Java的导入文件,这是一个可比的过程。

函数原型或签名告诉C编译器信息有关函数定义的信息 - 函数' s名称,参数数,参数的数量,以及返回类型 - 而不提供函数体。它们帮助C编译器在调用函数后出现的情况下识别函数属性。

C中的宏基本上是一个基本变量,在C程序中的代码编译之前处理。宏是使用#define指令创建的,例如:

这将创建一个名为testmacro的宏,具有ASDF的值。如果在代码中使用占位符testmacro,它将被值(代码编译之前)替换为ASDF。

要存储一个简单的整数或字符串值以在多个位置的代码中替换

存储一个简单的(通常是一行)代码片段将在多个位置的代码中替换

宏是方便的工具,因为它们使开发人员能够更新单行代码,这会影响多个位置中代码的行为。

C中的结构是与单个对象相关的分组属性集。

您可能熟悉Java和Python等语言的课程。结构是一个类的前身 - 它可以被认为是没有方法的原始类。

该结构代表一个人,通过将ID字段分组,以及一个人和姓氏和姓氏。可以从此结构实例化并初始化变量,如下所示:

指针是变量的存储器地址 - 它是存储该变量的值的存储器地址。

可以通过使用&amp来获得与现有变量的指针;符号,并存储在用*符号声明的指针变量中:

此代码段定义变量年龄并将其分配值为21.然后它定义了指向一个名为age_pointer的整数的指针,并使用该指针,并使用&要获取年龄变量的值存储的内存地址。

指针可以取消引用(即获取存储在内存地址的值),也可以使用*。

继续从我们上一个示例中,我们使用* age_pointer语法来获取存储在指针(21)中的值,然后添加10。所以new_age变量将包含值31。

现在,我们的简短SEGUE进入C编程,让'返回Git' s代码。

有十个相关的代码文件,可以弥补git' s初始提交。我们' LL开始简要讨论这两个:

makefile是一个构建文件,包含一组用于将其他源代码文件构建到可执行文件中的命令。

运行命令所有从命令行进行命令时,Makefile将编译源代码文件并吐出Git' s命令的相关可执行文件。如果您' ref兴趣,我在git' makefile上写了一个深入的指南。

注意:如果您实际上要编译Git'我建议您做的代码,您' ll需要使用上面提到的代码的婴儿git版本。原因是我做了一些调整,以允许Git'原始代码来编译现代操作系统。

接下来是cache.h文件,它是婴儿git' o opon的标题文件。如上所述,标题文件定义了.c源代码文件中使用的许多函数签名,结构,宏和其他设置。如果您' refious,我在git' s头文件上写了一个深入的指南。

每个文件(read-cache.c)以git命令命名它包含的代码 - 有些可能看起来很熟悉。例如,init-db.c文件包含用于初始化新git存储库的init-db命令的代码。正如您可能猜到的那样,这是Git Init命令的前身。

实际上,这些.c文件中的每一个(read-cache.c)包含原始八个git命令之一的代码。构建过程编译这些文件中的每一个,并为每个文件创建可执行文件(具有匹配的名称)。一旦将这些可执行文件添加到文件系统路径,它们就可以与任何现代Git命令同样执行。

因此,使用make all命令编译代码后,产生以下可执行文件:

CAT文件:从GIT存储库中检索对象的内容,并将其存储在当前目录中的临时文件中。相当于git show。

show-diff:显示索引中暂存的文件与这些文件中的当前版本之间的差异,因为它们存在于文件系统中。相当于git diff。

这些命令按顺序单独执行,类似于现代Git命令如何作为标准开发工作流程的一部分执行。

我们尚未讨论的一个文件'尚讨论的是read-cache.c。此文件包含一组辅助函数,即其他.c源代码文件用于从GIT存储库中检索信息。

现在我们触摸了Git'初始提交的每个重要文件,让'讨论了允许Git功能的一些核心编程概念。

在本节中,我们' ll讨论了Git用来工作的以下编程概念,以及如何在Git'原始代码中实现它们的原始代码:

文件压缩,也知道为通货紧缩,用于Git中的存储和性能效率。这减少了GIT存储在磁盘上的文件的大小,并在GIT需要在网络中传输这些文件时,增加数据检索的速度。

由于Git'本地和网络操作需要尽可能快地实现这一点。作为数据检索过程的一部分,git解压缩或膨胀,文件以获得其内容。

使用流行的Zlib.h C库在Git'原始代码中实施了文件通货紧缩和通货膨胀。此库包含用于压缩和解压缩内容的函数,结构和属性。具体来说,ZLIB定义了用于保持要缩小或充气的内容的Z_Stream结构。

以下ZLIB函数用于分别初始化流的流或通货膨胀的流:

/ * *初始化内部`z_stream`状态*以在`level`中压缩,这表明*从0-9的*比例上的速度Versuss压缩的比例。来自< zlib.h&gt ;. * / deflateInit(z_stream,level); / * *初始化内部`z_stream`状态以进行*解压缩。来自< zlib.h&gt ;. * / formateinit(z_stream);

/ * *按尽可能多的数据并停止*当输入缓冲区变为空或*输出缓冲区已满时。来自< zlib.h&gt ;. * /偏转(z__stream,flush); / * *在输入缓冲区变为空或*输出缓冲区变为空中时,可以尽可能多地解压缩并停止*。来自< zlib.h&gt ;. * /充气(z_stream,flush);

实际的通货紧缩/通胀过程比这更复杂,涉及设置压缩流的几个参数,但我们在这里赢得了更多细节。

接下来,我们' LL讨论哈希函数的概念以及它们在Git'原始代码中的实施方式。

散列函数是一种功能,可以轻松地将输入转换为唯一的输出,但是使其非常困​​难或不可能反转该操作。换句话说,它是单向功能。今天不可能使用散列函数的输出来推断用于生成该输出的输入的技术。

Git使用哈希函数 - 特别是SHA-1哈希函数 - 为我们告诉Git追踪的文件生成唯一标识符。

作为开发人员,我们在使用文本编辑器上工作的代码库中的代码文件更改,在某些时候,我们告诉Git跟踪这些更改。此时,Git使用这些文件更改为散列函数的输入。

散列函数的输出称为哈希。散列是长度的十六进制值40个字符,例如47A013E660D408619D894B20806B1D5086AAB03B。

Git用于各种目的使用这些哈希,以便我们将在以下部分中看到。

git使用简单的数据模型 - 一个结构化的相关对象集 - 实现其功能。这些对象是能够使Git能够跟踪对Codebase文件的更改的块。 git使用的三种类型的对象是:

Blob对于二进制大物体是短暂的。当git被告知使用update-cache< filename.ext&gt来跟踪文件。命令(前任git添加),git使用该文件的压缩内容创建一个新的blob。

git获取文件的内容,使用上面描述的zlib函数压缩它,并将该压缩内容用作SHA-1哈希函数的输入。这创建了一个40个字符的哈希,用于识别有问题的BLOB。

最后,git将blob保存为一个名为对象数据库的特殊文件夹中的二进制文件(在一分钟内更具内容)。 Blob文件的名称是生成的散列,Blob文件的内容是使用Update-Cache添加的压缩文件内容。

树对象用于将多个BLOB链接在一起,该BLOB一次将添加到Git。它们也用于将Blob与文件名(以及其他文件元数据等权限相关)相关联,因为Blobs Don' t提供了除哈希和压缩二进制文件内容之外的任何信息。

例如,如果使用update-cache命令添加两个已更改的文件,则将创建一个树,其中包含这些文件的哈希以及每个Blob对应的文件名。

接下来的git是非常有趣的,所以要注意。 git使用树本身的内容作为输入到SHA-1哈希函数的输入,它生成40个字符的哈希。此哈希用于标识树对象,GIT在诸多的特殊文件夹中保存此功能,这些文件夹已保存在ob - 对象数据库中我们' LL触摸不久。

您可能更熟悉提交对象而不是blob和树。提交表示Git保存的一组文件更改,以及关于提交消息,作者' s name等更改的描述性信息,以及提交的时间戳。

在git'原始代码中,一个提交对象是运行commit-tree< tree-hash&gt的结果。命令。生成的提交对象包括指定的树对象(记住,表示通过映射到其文件名的一个或多个blob的文件更改的集合,以及前一段中提到的描述性信息。

像Blob和树木一样,Git通过使用SHA-1哈希函数散列其内容并将其保存在对象数据库中来识别提交。重要的是,每个提交对象还包含其父提交的散列。通过这种方式,提交表格形成一个Git可以用于代表项目历史的链条。

您可能知道git' s暂存区域作为更改文件在使用git add命令后进行更改的文件,请耐心等待使用git提交。但是常产区究竟是什么?

在Git'原始版本中,暂存区域称为当前目录缓存。当前目录缓存只是一个二进制文件,存储在路径.dircache /索引处的存储库中。

如上一节所述,使用update-cache(git add)命令将更改的文件添加到git后,git计算与这些更改相关联的blob和树对象。与暂存文件关联的生成的树对象被添加到索引文件中。

它被称为缓存,因为它只是暂时存储位置,以便在提交之前驻留在内。当用户通过运行commit-tree命令进行提交时,可以提供来自当前目录缓存的树。它还包括其他提交信息,如Git创建新提交对象的提交消息。

此时,索引文件简单地删除,为要暂存的新更改腾出空间。

对象数据库是Git' s主存储位置。这是存储在上面讨论的所有对象 - 存储的所有对象 - 存储在内。在Git' s原始版本中,对象数据库只是路径中的目录.dircache /对象/。

当git通过update-cache,write-tree和commit树等操作创建对象时,(git add和git提交的前辈),这些对象被压缩,散列,并存储在对象数据库中。

每个对象的名称是其内容的哈希,因此对象数据库也称为内容可寻址数据库。基于从内容本身生成的标识符存储和检索每个内容(BLOB,树或提交)。

现代版的Git工作非常相同。不同之处在于已经优化了存储格式以使用更有效的方法(特别是与网络的数据传输相关),但基本原理是相同的。

在本文中,我们讨论了Git' s代码的原始版本,以突出显示读取现有代码如何有助于提高编码技巧。

我们介绍了Git是一个伟大的项目,以这种方式学习,如何访问Git' s代码,并审查了一些相关的C编程概念。最后,我们提供了Git' S原始码库结构的概述,并进入了Git' s代码依赖的一些概念。

如果您' ref兴趣了解更多关于git' s代码,我们写了一本可以查看的指南。本书详细潜入Git'原始的C代码,并直接解释了代码的工作原理。

我鼓励任何和所有开发人员探索开源社区,以试图找到您感兴趣的质量项目。这些项目将有代码库,您可以在几分钟内克隆。

花一些时间来探讨代码,你可能会学到你从未想过的东西。 学会免费学习。 FreeCodecamp'开源课程有助于更多 ......