Git对Git分支进行反向合并/重新设置并提交;“了解”;
我听过好几次Git保存了一个内部记录“它所知道的变化”。这就是为什么我们需要将更改(比如转移到dev的修补程序)或重定基址中固有的问题进行反向合并的原因。我觉得这有点像“一级对象”,其中使用的短语有点含糊不清,使用松散,而潜在的现实更直接 那么,“它知道的变化”到底意味着什么呢?在Git源代码中,每个分支在哪里维护它“知道”的sha1列表(可能在这里:某处)?当Git更改了一个sha1时会发生什么呢?比如说,发布分支上的某个人执行了a、b、c的挤压提交来生成dGit对Git分支进行反向合并/重新设置并提交;“了解”;,git,Git,我听过好几次Git保存了一个内部记录“它所知道的变化”。这就是为什么我们需要将更改(比如转移到dev的修补程序)或重定基址中固有的问题进行反向合并的原因。我觉得这有点像“一级对象”,其中使用的短语有点含糊不清,使用松散,而潜在的现实更直接 那么,“它知道的变化”到底意味着什么呢?在Git源代码中,每个分支在哪里维护它“知道”的sha1列表(可能在这里:某处)?当Git更改了一个sha1时会发生什么呢?比如说,发布分支上的某个人执行了a、b、c的挤压提交来生成d 发布分支是否知道关于a、b、c的信
发布分支是否知道关于a、b、c的信息,并且在合并时返回给dev,它是否也会传递该信息,或者仅仅传递d的存在?如果dev branch已经提交了a,那么同时管理d和a的存在是否足够明智呢?因为这很长,让我先回答最后一部分,然后清除其他部分: 。。。例如,假设release分支上的某个人执行a、b、c的挤压提交以生成d。发布分支是否知道关于a、b、c的信息,并且在合并时返回给dev,它是否也会传递该信息,或者仅仅传递d的存在 挤压,无论是通过
git-rebase-i
还是git-merge-squash
获得,都是一种新的、不同的提交。在大多数情况下,没有简单的方法来判断这个新的提交d
等同于a+b+c
。涉及复制提交或其效果的操作,即将提交d
或其效果复制到dev
,或将a+b+c
复制到release
,可能会看到合并冲突,但可能不会!这取决于行动和变化的程度
长的
我听过好几次git保存了一个内部记录“它所知道的变化”
这在模糊的意义上甚至都不是真的。Git所做的是根据需要计算更改集。理解这一点是使用Git的关键之一。特别是,我们需要了解当您要求Git执行merge操作时,Git将如何计算更改集(我喜欢说的是merge,或者merge-as-a-verb)
Git存储一个提交图,在该图中,每个提交链接回其直接的前一个,即父级、提交,或者对于合并提交,两个或更多这样的前一个。每个提交本身还间接存储一个快照—不是更改,而是整个快照
在这个级别上,精确的细节并不是很重要,但为了具体起见,Git主数据库中有一组对象,每个对象都是四种类型中的一种:提交、树(允许Git在提交中定位文件)、blob(主要存储文件内容)和注释标记(专门用于注释标记)。Git作为一个整体是一系列数据库:这是一个主数据库,它是一个由散列ID索引的简单键值存储,加上一些辅助数据库。一个关键的辅助数据库是另一个将名称转换为哈希ID的键值存储
关于更改与快照
在某种程度上,“更改”与“快照”是不相关的,在某种程度上也不是。用一个代数的例子(如果你太用力的话,它会崩溃,但应该能让人明白这一点):假设我告诉你,今天比昨天暖和或冷5度。现在我问你们:今天的温度是多少?你不能单凭这一点就知道!如果我告诉你们昨天是16ºC,现在你们可以知道了,因为现在你们有了一个快照值和5º增量。另一方面,如果我说一天是16ºC,第二天是21ºC,你可以从两个快照中找到增量
简而言之,给定提交中的快照,您(或Git)可以生成增量,但仅给定增量,就无法生成快照。同时,使用从提交到其父级的链接,还可以生成提交图:图在数学上定义为一对集合G=(V,E),其中V是顶点集,E是边集。Git将各个边存储在表示顶点的节点中。这些节点是对象数据库中的提交对象
使用图形
我上面提到的辅助数据库就在这里发挥作用。为了进入图形,Git需要一些起始点散列ID。还有另一个选项,像git fsck
和git gc
这样的维护命令可以使用:它们只需查找主数据库中的每个对象。但是这对于正常的工作来说太慢了,并且会使丢弃不需要的对象变得更加困难,所以Git对哈希ID数据库有一个辅助名称:像master
这样的分支名称会变成一个,并且只有一个哈希ID。对于分支名称,这个特定的哈希ID会定位一个提交,Git会调用分支的顶端
无法更改主数据库中的任何对象。这意味着任何提交都不会更改任何一位。文件也不会更改:要更改文件,只需将新版本的副本存储为新的blob对象。保存旧文件的旧提交链接到旧blob。带有新文件的新提交链接到新blob。一般来说,有一些特殊的例外情况,我们只向主数据库添加内容。要向分支添加新的提交,我们编写新的提交,它链接到分支的所有文件,也链接到分支的父提交。这将为我们提供一个新的哈希ID,然后将其存储到分支名称中
其效果是,分支名称始终只存储分支的最后一个哈希ID。我们使用它来查找提交,然后使用提交的父哈希ID来查找上一次提交,依此类推
。。。当git更改了sha1时会发生什么
Git从不更改散列ID。虽然散列ID当前为SHA-1,但有迁移计划切换到另一个散列
...--o--o--B---o--L <-- mainline (HEAD)
\
o--o--R <-- feature
git diff --find-renames <hash-of-B> <hash-of-L> # what we changed
git diff --find-renames <hash-of-B> <hash-of-R> # what they changed
...--o--o--B---o--L--M <-- mainline (HEAD)
\ /
o--o--R <-- feature
...--o--o--B---o--L--M--o--T <-- mainline (HEAD)
\ /
o--o--R--o--o--U <-- feature
...--o--o--B---o--L--S <-- mainline (HEAD)
\
o--o--R <-- feature
...--o--o--B---o--L--S--o--T <-- mainline (HEAD)
\
o--o--R--o--o--U <-- feature
...--o--o--H <-- us (HEAD)
\
o--o--B--C <-- them
git diff --find-renames <hash-of-B> <hash-of-C> # what they changed
...--o--o--H--C' <-- us (HEAD)
\
o--o--B--C <-- them