-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ch5): translate 365-589 #57
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,193 @@ | ||||||||||||||||||
[365] | ||||||||||||||||||
是的,问题提得很好 | ||||||||||||||||||
这个东西叫合并冲突 | ||||||||||||||||||
当你合并你的平行开发的分支时 | ||||||||||||||||||
Git 将尝试以某种方式自动合并变化 | ||||||||||||||||||
以保留所有重要的修改 | ||||||||||||||||||
但如果它不知道咋办 | ||||||||||||||||||
就会报告一个合并冲突 | ||||||||||||||||||
然后把问题留给你这个程序员来解决 | ||||||||||||||||||
好比如何合并相同文件或类似的东西(在不同分支)同时发生变化的问题 | ||||||||||||||||||
或者你也可以用一些程序来辅助 | ||||||||||||||||||
还有什么问题吗 | ||||||||||||||||||
我们有了文件和文件夹的模型 | ||||||||||||||||||
还有把不同快照相互关联的历史模型 | ||||||||||||||||||
[384] | ||||||||||||||||||
这里有一个小细节 | ||||||||||||||||||
每个圆圈都对应着一个快照 | ||||||||||||||||||
就像一棵有文件和文件夹的树 | ||||||||||||||||||
但它们也有一些元数据 | ||||||||||||||||||
比如在这里,我们可能有我是这个提交的作者(Author) | ||||||||||||||||||
我们可能有其他的元数据 | ||||||||||||||||||
比如与这个提交相关的一些消息 | ||||||||||||||||||
我可能描述我做了什么样的改动 | ||||||||||||||||||
这些改动存在于这个快照中 | ||||||||||||||||||
而不是前一个快照 | ||||||||||||||||||
所以接下来我们要讨论的是比这更低一级的数据结构 | ||||||||||||||||||
比如这个数据结构在 Git 里面到底是怎么表示的 | ||||||||||||||||||
所以我实际上要写下伪代码 | ||||||||||||||||||
因为我觉得这样最容易理解 | ||||||||||||||||||
首先我们要有文件 | ||||||||||||||||||
所以 blob 只是一堆字节 | ||||||||||||||||||
[404] | ||||||||||||||||||
所以我说这是一个字节数组 | ||||||||||||||||||
好的,那么什么是树(tree)呢? | ||||||||||||||||||
* 为了便于理解,括号内将标注术语对应词汇 | ||||||||||||||||||
记住,这只是一个文件夹 | ||||||||||||||||||
它们是文件名或目录名到实际内容的映射 | ||||||||||||||||||
而内容是另一棵树(tree) | ||||||||||||||||||
比如子树(tree)或文件(blob) | ||||||||||||||||||
最后我们还有最后一个东西 | ||||||||||||||||||
到目前为止,我一直称之为快照 | ||||||||||||||||||
按术语,这些被称为提交(commit) | ||||||||||||||||||
那么什么是提交? | ||||||||||||||||||
一个提交是一堆东西 | ||||||||||||||||||
提交有父亲(parent) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里我翻译的很蛋疼,父节点是树里的概念,但是Git 是个 DAG |
||||||||||||||||||
描述了它们之前的内容 | ||||||||||||||||||
所以在大多数正常提交的情况下 | ||||||||||||||||||
它们有一个父亲 | ||||||||||||||||||
比如它们来自什么地方 | ||||||||||||||||||
合并提交可以有多个父亲 | ||||||||||||||||||
所以父本是一个提交的数组 | ||||||||||||||||||
Comment on lines
+48
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
然后有一些元数据 | ||||||||||||||||||
比如作者和可能的消息 | ||||||||||||||||||
最后是实际内容 | ||||||||||||||||||
快照是一棵树,是一个特定提交的顶层树 | ||||||||||||||||||
这是一个非常简洁的历史模型 | ||||||||||||||||||
这就是 Git 的历史模型的全部内容 | ||||||||||||||||||
有什么问题吗? | ||||||||||||||||||
现在我们有了更深入的了解 | ||||||||||||||||||
让我们谈谈它是如何实际存储和处理这些数据的 | ||||||||||||||||||
[441] | ||||||||||||||||||
因此,在磁盘上维护的东西 | ||||||||||||||||||
实际上我们在后面要看到 | ||||||||||||||||||
是一组将内容作为地址存储的对象 | ||||||||||||||||||
所以如果你有这些对象中的任何一个 | ||||||||||||||||||
你用这个对象的哈希值做为它的键值进行储存 | ||||||||||||||||||
所以在伪代码中,我可能会说 | ||||||||||||||||||
为了存储一个特定的对象 O | ||||||||||||||||||
我所做的是通过获取 O 的 SHA-1 哈希值来计算它的 ID | ||||||||||||||||||
然后我把它放到我的对象映射中 | ||||||||||||||||||
把它存储到磁盘上 | ||||||||||||||||||
快举手,这里有谁知道什么是哈希函数 | ||||||||||||||||||
好吧,我快速总结一下 | ||||||||||||||||||
基本上哈希函数就是你可以把它想象成一个魔法函数 | ||||||||||||||||||
把一个长的数据变成一个短的 | ||||||||||||||||||
在高层次上,这些都是用来 | ||||||||||||||||||
我觉得说这么多足够了 # REVIEW: Need discussion 18:45 | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 他没说你不就只能猜了 |
||||||||||||||||||
我不会在这里说得太详细 | ||||||||||||||||||
但你可以事后问我 | ||||||||||||||||||
如果你很好奇 | ||||||||||||||||||
所以基本上他们给你一种方法 | ||||||||||||||||||
以一种确定性的方式来命名它的内容 | ||||||||||||||||||
它把东西作为输入 | ||||||||||||||||||
返回给你一个简短的名字 | ||||||||||||||||||
然后,与存储的方式相反 | ||||||||||||||||||
我们可以从存储中加载东西 | ||||||||||||||||||
你可能已经猜到了 | ||||||||||||||||||
你可以通过他们的 ID 来查找他们 | ||||||||||||||||||
我们通过 ID 从对象存储中检索它 | ||||||||||||||||||
然后返回给我们内容 | ||||||||||||||||||
有什么问题吗? | ||||||||||||||||||
这个问题问得好 | ||||||||||||||||||
这都是用什么语言写的? | ||||||||||||||||||
它是用我刚编出来的语言写的 | ||||||||||||||||||
所以它是伪代码 | ||||||||||||||||||
git 主要是 C 语言写的 | ||||||||||||||||||
加上一些 bash 和 Perl 脚本 | ||||||||||||||||||
还有其他的问题吗 | ||||||||||||||||||
这个伪代码足够清晰吗 | ||||||||||||||||||
还需要解释哪些代码 | ||||||||||||||||||
[484] | ||||||||||||||||||
好吧,那么 blob、tree 和 commit 都是统一的 | ||||||||||||||||||
它们都是对象 | ||||||||||||||||||
而且正如你可能认为的那样 | ||||||||||||||||||
鉴于我在这里的描述 | ||||||||||||||||||
看起来提交包含一大堆其他的提交 | ||||||||||||||||||
包含快照之类的东西 | ||||||||||||||||||
实际上并不是这样的 | ||||||||||||||||||
而是所有这些都是指针 | ||||||||||||||||||
所以一个提交将能够通过 ID 引用一堆父亲 | ||||||||||||||||||
所以这实际上不是一个提交本身的数组 | ||||||||||||||||||
而是 ID 的数组 | ||||||||||||||||||
同样,提交中的快照也不是实际的树对象 | ||||||||||||||||||
而是树的 ID | ||||||||||||||||||
所以所有这些对象都是独立存储在这个对象存储中 | ||||||||||||||||||
然后所有对不同对象的引用都是通过它们的 ID | ||||||||||||||||||
也就是它们的 SHA-1 哈希值 | ||||||||||||||||||
这有意义吗? | ||||||||||||||||||
你几乎可以在你的头脑中 | ||||||||||||||||||
把它映射成像 Java 这样的编程语言中的对象 | ||||||||||||||||||
然后这是一个对树的引用,所以它就像一个指针 | ||||||||||||||||||
然后这就是你的领域了 | ||||||||||||||||||
希望这个类比能帮助你理解 | ||||||||||||||||||
[511] | ||||||||||||||||||
是的,所以我再重复一遍 | ||||||||||||||||||
让大家在麦克风上听到 | ||||||||||||||||||
这是磁盘上的数据存储 | ||||||||||||||||||
是一个内容地址存储 | ||||||||||||||||||
对象是通过它们的哈希值来寻址的 | ||||||||||||||||||
好的,到目前为止有什么问题吗? | ||||||||||||||||||
好了,现在我们有了一种识别方法 | ||||||||||||||||||
我们已经将所有不同类型的对象统一为一种类型 | ||||||||||||||||||
我们称之为 object | ||||||||||||||||||
我们有了一种通过 SHA-1 哈希值来识别对象的方法 | ||||||||||||||||||
这些实际的 SHA-1 哈希值是什么样子的呢? | ||||||||||||||||||
它们是长达 40 个字符的十六进制字符串 | ||||||||||||||||||
比如 SHA-1 是一个 160 位的哈希值 | ||||||||||||||||||
所以由 SHA-1 函数返回的实际 ID 将是一个非常长的字符串 | ||||||||||||||||||
所以考虑到我们会有方法来识别这些不同的东西 | ||||||||||||||||||
比如我们会有一个对应的 ID | ||||||||||||||||||
比如一个 4af32cb 等等之类的东西 | ||||||||||||||||||
所以现在我们有一种方法来命名这个提交图中的所有东西 | ||||||||||||||||||
但这些名字真的很不方便 | ||||||||||||||||||
因为它们超长 | ||||||||||||||||||
而且就像文本字符串一样 | ||||||||||||||||||
对人类没有任何意义 | ||||||||||||||||||
这个问题的解决方案是 | ||||||||||||||||||
它维护了一组对象 | ||||||||||||||||||
然后维护了一组引用 | ||||||||||||||||||
我们的引用在这里 | ||||||||||||||||||
我会把左边的这部分擦掉 | ||||||||||||||||||
这部分很有逻辑性 | ||||||||||||||||||
引用就在这里 | ||||||||||||||||||
这是 Git 内部维护的另一块数据 | ||||||||||||||||||
引用是一个从字符串到字符串的映射 | ||||||||||||||||||
你可以把它看作是人类可读的名字的映射 | ||||||||||||||||||
比如我可能有一个名字是「fix encoding bug」 | ||||||||||||||||||
一个人类可读的名字 | ||||||||||||||||||
这将被映射到像那个长的十六进制字符串 | ||||||||||||||||||
所以有了这些引用 | ||||||||||||||||||
你可以想象 | ||||||||||||||||||
我们有何办法做创建新的引用和更新引用之类的事 | ||||||||||||||||||
[559] | ||||||||||||||||||
有了这个 | ||||||||||||||||||
我现在可以用名字来指代我的提交图中的东西 | ||||||||||||||||||
所以我可能会有另一个名字,比如「fix bug」 | ||||||||||||||||||
指代同样的对象 | ||||||||||||||||||
或者我可能会有一个名字来指代这里的东西 | ||||||||||||||||||
诸如此类,所以有了这个 | ||||||||||||||||||
我可以用人类可读的名字来指代历史中的特定快照 | ||||||||||||||||||
而不是这些长长的十六进制字符串 | ||||||||||||||||||
还有一点需要注意的是 | ||||||||||||||||||
鉴于 Git 对历史的设计 | ||||||||||||||||||
整个图实际上是不可变的 | ||||||||||||||||||
* 事实上有一个专门的术语称呼这种数据结构:可持久化 | ||||||||||||||||||
你可以向它添加新的东西 | ||||||||||||||||||
但实际上你不能在这里操作任何东西 | ||||||||||||||||||
我不会去研究具体的方法或原因 | ||||||||||||||||||
但只是假设这是事实 | ||||||||||||||||||
但是引用是不可变的 | ||||||||||||||||||
所以当你更新历史的时候 | ||||||||||||||||||
比如说你一直在开发这个软件 | ||||||||||||||||||
你创建了一个新的提交 | ||||||||||||||||||
所以我用这个圆圈来表示 | ||||||||||||||||||
这个圆圈指向之前的提交 | ||||||||||||||||||
实际上我可以说我的「fix bug」引用指向这里 | ||||||||||||||||||
我可以更新这个引用,现在指向这里 | ||||||||||||||||||
但是我不能比如说把这个指向这里 | ||||||||||||||||||
这甚至不是一个有意义的事情 | ||||||||||||||||||
因为这只是这个对象的哈希值 | ||||||||||||||||||
要改变这个哈希值 | ||||||||||||||||||
我需要改变这个对象的内容 | ||||||||||||||||||
这没意义 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我记得这只是最常见的,还有一些其他问题也会造成合并冲突