git 从http改git_从内而外地了解git

git 从http改git

Although as a programmer we use git in our day-to-day life many of us don’t really know what it does internally to do what it does. In this article, I’ll try to explain what git really is and how it internally works.

尽管作为程序员,我们在日常生活中使用git,但我们中的许多人实际上并不真正知道它在内部执行什么工作。 在本文中,我将尝试解释git的真正含义以及它的内部工作方式。

Git命令的类型 (Types of Git commands)

We use many git commands in our day to day life like git commit, git push, git checkout etc. this are the common commands that are more user friendly and are called “Porcelain” commands. But because git was initially a toolkit for version control rather than a full user friendly VCS is also has many subcommands which does low level work and those are called “Plumbing” commands.

我们在日常生活中使用了许多git命令,例如git commitgit pushgit checkout等。这是更用户友好的常见命令,被称为“瓷器”命令。 但是因为git最初只是用于版本控制的工具包,而不是完全用户友好的VCS,所以它也具有许多子级命令,这些子级命令执行低级工作,这些子命令称为“管道”命令。

Git plumbing commands works with low level and gives access to inner working of git we’ll be mostly dealing with those commands in this article. These commands aren’t meant to be run from the command line but rather to be used in building blocks of any custom scripting.

Git管道命令以较低级别工作,并允许访问git的内部工作,在本文中我们将主要处理这些命令。 这些命令不是要从命令行运行,而是要用在任何自定义脚本的构造块中。

观察新初始化的.git目录 (Observing a newly initialised .git directory)

When we do git init it creates a .git directory which contains almost everything git creates and manipulates. If you want to backup or clone your repo copying this .git folder will give you almost everything you needed. So now let’s look at how .git directory looks like

当我们执行git init它将创建一个.git目录,其中包含git创建和操作的几乎所有内容。 如果您要备份或克隆存储库,则复制此.git文件夹将为您提供所需的几乎所有东西。 现在让我们看看.git目录的样子

Image for post

This is my newly initialised .git folder looks like. You many have some different content depending on your git version. It may add some more when you creates a file and add it to git.

这是我新初始化的.git文件夹的样子。 根据您的git版本,您可能有一些不同的内容。 创建文件并将其添加到git时,它可能还会添加更多内容。

config: contains your project specific configuration options.

config :包含您的项目特定的配置选项。

hooks: contains your server or client side scripts that you run maybe before commit or push.

hooks :包含在提交或推送之前运行的服务器或客户端脚本。

HEAD, objects and refs are the core part of git and git changes them more frequently.

HEADobjectrefs是git的核心部分,而git更频繁地更改它们。

objects: stores all the content for your git repository/directory/project also called database by git.

objects :存储git仓库/目录/项目的所有内容,也称为git。

refs: stores pointers to commit into data(branches, tags, remote etc)

refs :存储要提交到数据(分支,标签,远程等)的指针

HEAD: this file contains pointer to the branch you currently checked out.

HEAD :此文件包含指向您当前签出的分支的指针。

Git是文件系统 (Git is filesystem)

git is content-addressable filesystem, that means git is a simple key value data store, by means of that you can insert any kind of data into your git repository and for that git will hand you over a unique key from which you can retrieve your data back later.

git是内容可寻址的文件系统,这意味着git是一个简单的键值数据存储,通过这种方式,您可以将任何类型的数据插入git存储库中,并且git将为您提供一个唯一的密钥,您可以从中检索您的稍后再返回数据。

Now for the demonstration purpose lets look at plumbing command git hash-object which takes some data and stores it into .git/objects directory also called the object database it will give you back a unique key that now refers to that data object.

现在,出于演示目的,让我们看一下管道命令git hash-object ,该命令将一些数据存储到.git/objects目录(也称为对象数据库)中,它将为您提供一个唯一的键,该键现在指向该数据对象。

Let’s verify that nothing is there in the current object directory

让我们验证当前对象目录中没有内容

Image for post

git has initialised the directory and created pack and info directory but there is no file as such.

git已经初始化了目录并创建了packinfo目录,但是没有这样的文件。

Let’s use git has-object command and create new data object, store it in Git Database manually.

让我们使用git has-object命令并创建新的数据对象,然后将其手动存储在Git数据库中。

Image for post

In it’s simplest form git has-object would take the content you handed to it and merely returns the unique key that would be used to store it in your git database. the -w command tells the git to not only returns the key but also write that object to database. Finally, the --stdin option tells the git to get the content to be processed from stdin; otherwise, the command would expect a filename argument at the end of the command containing the content to be used.

git has-object是最简单的形式,它将获取您交给它的内容,并且仅返回用于将其存储在git数据库中的唯一键。 -w命令告诉git不仅返回键,而且将该对象写入数据库。 最后, --stdin选项告诉git的去从标准输入处理的内容; 否则,该命令将在命令末尾包含一个文件名参数,其中包含要使用的内容。

The output of the following command will be a 40-character checksum hash. This is the SHA-1 — a checksum of the content you are storing plus header.

以下命令的输出将是一个40个字符的校验和哈希。 这是SHA-1-存储的内容的校验和加上标题。

Now if we see the object directory again there will be one entry for the file. This is how git stores content as single file per piece of content. The subdirectory is named with first 2 characters of SHA-1 and filename with rest 38 characters.

现在,如果我们再次看到对象目录,则该文件将只有一个条目。 这就是git将内容存储为单个文件的方式。 子目录的名称以SHA-1的前2个字符命名,文件名以38个其余字符命名。

Image for post

检索git hash-object存储的内容 (Retrieving the content stored by git hash-object)

Once we store the content in the git object(database) we can get it by git cat-file command passing -p to the command tells it to first get the file type and later show it accordingly.

一旦我们将内容存储在git对象(数据库)中,就可以通过git cat-file命令将其传递给命令-p来告诉它首先获取文件类型,然后相应地显示它。

Image for post

Now we are able to store and retrieve content from git. We can also do this via giving a file and do version controlling with it.

现在我们可以从git存储和检索内容。 我们还可以通过提供文件来执行此操作,并对其进行版本控制。

版本控制 (Version Controlling)

let us try creating a file with some content and do version controlling for that.

让我们尝试创建包含一些内容的文件,并为此进行版本控制。

Image for post
Image for post

As we have stored some content in the file, let us store some more content for the another version.

由于我们已经在文件中存储了一些内容,因此让我们为另一个版本存储更多的内容。

Image for post

Now the our object contains both the version first one as well as the second version.

现在,我们的对象同时包含第一个版本和第二个版本。

Image for post

Now we can remove the local file file.txt and can retrieve the data from git object either the first or second version.

现在我们可以删除本地文件file.txt并可以从git对象的第一个版本或第二个版本中检索数据。

Image for post

We can store each content in git object but it’s not practical scenario also it’s not storing the file name but just the content this type of object is called “blob”. You can see the type by using git cat-file -t sha-1

我们可以将每个内容存储在git对象中,但这不是实际的情况,也不是存储文件名,而只是存储这种对象的内容称为“ blob”。 您可以使用git cat-file -t sha-1查看类型

树对象(Tree Objects)

Now to solve the problem and store both content and filename we have something called tree objects it allows git to store filename with content. It also allows to store group of files together which we generally use while making commits. Git stores content in similar manner to a UNIX system, but with simplified a bit. All contents is stored in tree and blob objects, with tree likes UNIX directories when blobs are more like file content. A single tree object can contain one or more entries each of which can have corresponding blob objects.

现在要解决问题并存储内容和文件名,我们有一个称为树对象的东西,它允许git将文件名和内容一起存储。 它还允许将在提交时通常使用的文件组存储在一起。 Git以与UNIX系统类似的方式存储内容,但略有简化。 当blob更像文件内容时,所有内容都存储在tree和blob对象中,并且树类似于UNIX目录。 单个树对象可以包含一个或多个条目,每个条目可以具有相应的blob对象。

Image for post
Simple version of the Git data model
Git数据模型的简单版本

Now let us create some files and make the commit manually with just lower-level commands.

现在,让我们创建一些文件,并仅使用较低级别的命令手动进行提交。

We first need to create a tree which can be done easily by creating and staging the files. Git generally creates tree from making objects from your staging or index area. Staging area is where your uncommitted changes are present.

我们首先需要创建一棵树,通过创建和暂存文件可以轻松完成。 Git通常通过从暂存区或索引区制作对象来创建树。 暂存区域是您未提交的更改所在的位置。

To stage the file we can use git update-index command, we’ll use this command to add our file.txt to staging area also we need to pass --add option because the file doesn’t exists in the staging area yet (we don’t even have staging area set yet), we will also need to use --cachedinfo because the file we are adding is not in the directory but is in the database then mode sha-1 filename

git update-index文件,我们可以使用git update-index命令,我们将使用此命令将file.txt添加到暂存区域,我们还需要传递--add选项,因为暂存区域中尚不存在该文件(我们甚至还没有设置临时区域),我们还需要使用--cachedinfo因为我们要添加的文件不在目录中,而是在数据库中,所以mode sha-1 filename

Image for post

模式 (Modes)

100644 - Normal file
100755 - Executable file
120000 - Symbolic link.

We can now use git write-tree to write the staging area out in tree object. Calling this command automatically creates the tree index from the staged area.

现在,我们可以使用git write-tree将临时区域写到tree对象中。 调用此命令会自动从暂存区创建树索引。

Image for post

Few things to notice here, git write-tree has created the tree and given sha for it once we check the type of the object it says tree

这里没有什么要注意的,一旦我们检查了表示tree的对象的类型, git write-tree就创建了树并为其指定了sha

We can now create new version of the file and also can add a new file to the tree.

现在,我们可以创建文件的新版本,也可以将新文件添加到树中。

Image for post

Notice that the latest tree has both the files with the sha.

请注意,最新的树同时具有带sha的文件。

提交对象 (Commit Objects)

Now we have done storing content with filenames using tree but the problem still remains same, still need to remember few sha ids which is not practical. You cannot track your version with just these sha ids you will also need an appropriate message to identify which commit has what. We need to know the basic reasons why we saved the object and when we saved the object. These are the basic information we need to make it more useful.

现在我们已经完成了使用树存储带有文件名的内容的操作,但是问题仍然存在,仍然需要记住一些不实用的sha id。 您不能仅使用这些共享ID来跟踪您的版本,您还需要一条适当的消息来标识哪个提交具有什么。 我们需要知道为什么保存对象以及保存对象的基本原因。 这些是我们使其更有用的基本信息。

In order to solve this problem we need to make a commit with some basic information and we can do this using git commit-tree

为了解决这个问题,我们需要提交一些基本信息,并且可以使用git commit-tree

Image for post

Wow, We just made a commit with all low-level git commands.

哇,我们刚刚使用了所有低级git命令进行了提交。

This is essentially what git does when we do git add git commit commands it store the blobs and tree that you have saved and use them to make commit.

本质上,这就是git在执行git add git commit命令时所做的工作,该命令存储您已保存的Blob和树,并使用它们进行提交。

That’s all for this article, thanks for reading. Keep committing :)

这就是本文的全部内容,感谢您的阅读。 继续提交:)

翻译自: https://medium.com/swlh/knowing-git-inside-out-223499c58860

git 从http改git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值