- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Chapter 3.1 of the the Git book明确指出,只有暂存文件必须作为blob存储在提交树中。
如果像提交对象一样,blob获得了对其内容唯一的哈希ID,那么Git如何设法跟踪跨提交的blob与文件之间的对应关系?由于提交文件的内容不同,因此它们在不同提交中的哈希ID无法匹配。
一个简单的例子:
假设我只是创建了一个没有提交的空仓库。我创建一个文件README.md,暂存并提交。 Git存储一个树对象,该树对象的Blob由README.md内容的哈希标识。
假设我修改了README.md,进行了阶段提交。 Git存储一个树对象,该树对象的Blob由README.md的已修改内容的哈希标识。自然,我们可以期望第二个哈希与第一个提交树中标识README.md的blob的哈希不同。
Git将如何回答有关README.md历史记录的请求?
git log README.md
最佳答案
这实际上是一个很好的问题。
提交的内部存储形式部分相关,因此让我们考虑一下。实际上,单个提交很小。这是来自Git的Git存储库中的一个,即commit b5101f929789889c2e536d915698f58d5c5c6b7a
:
$ git cat-file -p b5101f929789889c2e536d915698f58d5c5c6b7a | sed 's/@/ /'
tree 3f109f9d1abd310a06dc7409176a4380f16aa5f2
parent a562a119833b7202d5c9b9069d1abb40c1f9b59a
author Junio C Hamano <gitster pobox.com> 1548795295 -0800
committer Junio C Hamano <gitster pobox.com> 1548795295 -0800
Fourth batch after 2.20
Signed-off-by: Junio C Hamano <gitster pobox.com>
sed 's/@/ /'
也许是为了减少Junio Hamano必须获得的电子邮件垃圾邮件的数量:))。如您所见,提交对象通过另一个提交的哈希ID
a562a11983...
引用其父提交对象。它还通过哈希ID引用树对象,并且树对象的哈希ID以
3f109f9d1a
开头。我们也可以使用
git cat-file -p
来查看这个树对象:
$ git cat-file -p 3f109f9d1a | head
100644 blob de1c8b5c77f7566d9e41949e5e397db3cc1b487c .clang-format
100644 blob 42cdc4bbfb05934bb9c3ed2fe0e0d45212c32d7a .editorconfig
100644 blob 9fa72ad4503031528e24e7c69f24ca92bcc99914 .gitattributes
040000 tree 7ba15927519648dbc42b15e61739cbf5aeebf48b .github
100644 blob 0d77ea5894274c43c4b348c8b52b8e665a1a339e .gitignore
100644 blob cbeebdab7a5e2c6afec338c3534930f569c90f63 .gitmodules
100644 blob 247a3deb7e1418f0fdcfd9719cb7f609775d2804 .mailmap
100644 blob 03c8e4c613015476fffe3f1e071c0c9d6609df0e .travis.yml
100644 blob 8c85014a0a936892f6832c68e3db646b6f9d2ea2 .tsan-suppressions
100644 blob 536e55524db72bd2acf175208aef4f3dfc148d42 COPYING
100644
),类型(
blob
,这是模式所隐含的,也记录在内部Git对象中;它实际上没有存储在树对象中),哈希ID(< cc>)和blob的名称(
de1c8b5c77f...
)。您还可以看到
.clang-format
可以引用其他
tree
对象,就像
tree
子树一样。
$ git cat-file -p de1c8b5c77f | head
# This file is an example configuration for clang-format 5.0.
#
# Note that this style definition should only be understood as a hint
# for writing new code. The rules are still work-in-progress and does
# not yet exactly match the style we have in the existing code.
# Use tabs whenever we need to fill whitespace that spans at least from one tab
# stop to the next one.
#
# These settings are mirrored in .editorconfig. Keep them in sync.
.github
子树:
$ git cat-file -p 7ba15927519648dbc42b15e61739cbf5aeebf48b
100644 blob 64e605a02b71c51e9f59c429b28961c3152039b9 CONTRIBUTING.md
100644 blob adba13e5baf4603de72341068532e2c7d7d05f75 PULL_REQUEST_TEMPLATE.md
.github
构建的缓存会说,名称
b5101f929789889c2e536d915698f58d5c5c6b7a
具有模式
.clang-format
和blob哈希
100644
,而名称
de1c8b5c77f7566d9e41949e5e397db3cc1b487c
具有模式
.github/CONTRIBUTING.md
和blob-hash
100644
。
64e605a02b71c51e9f59c429b28961c3152039b9
加
.github
)已加入到内存缓存中。 (以磁盘格式,通过算法欺骗将它们压缩。)
CONTRIBUTING.md
与其他提交进行比较,则Git还将另一个提交读入内存缓存中。该其他高速缓存具有一个名为
b5101f929789889c2e536d915698f58d5c5c6b7a
的条目,或者没有。
.github/CONTRIBUTING.md
的简单事实足以将它们标识为“同一文件”。名称相同,到此完成。
.github/CONTRIBUTING.md
提供额外的服务
git diff
的文件可能会重命名为
a/b.c
或
d/e.f
。
d/e.c
,文件名为
a123456
。然后,我们提交
a/b.c
。第二个提交没有
f789abc
,但是确实有
a/b.c
。 Git会简单地从索引(缓存的磁盘形式)和工作树中删除
d/e.f
,并将新的
a/b.c
填充到我们的索引和工作树中,一切都很好。
d/e.f
与
a123456
进行比较。 Git可以告诉我们:要将
f789abc
更改为
a123456
,请删除
f789abc
并使用这些内容创建一个新的
a/b.c
。这就是
d/e.f
所做的,足够了。但是,如果内容完全匹配怎么办? Git告诉我们的效率更高:要将
git checkout
更改为
a123456
,将
f789abc
重命名为
a/b.c
。实际上,使用正确的选项,
d/e.f
可以做到这一点:
git diff --find-renames a123456 f789abc
git diff
)。进一步假设提交R包含不在提交L中的某个文件(
a/b.c
)。与其立即告诉我们:您应该删除L文件并使用R文件,Git现在可以比较两个文件的内容。
d/e.f
与R中的
a/b.c
100%相同。在这种情况下,它们将具有完全相同的哈希ID!因此,Git做到了:如果某个文件已从L消失,而另一些文件已出现在R中,并且要求Git查找重命名,则Git会检查哈希ID是否匹配。如果找到某些文件,它将对这些文件进行配对(并将它们从不匹配文件的队列中删除-包含L和R中的文件的该队列是“重命名检测队列”)。
d/e.f
获取匹配的结果并调用那些文件重命名。同样,这仅在使用
git diff
(或
--find-renames
)时发生,并且可以根据需要将阈值设置为50%以外的值。
-M
命令提供另一项服务。请注意,我们首先假设,如果提交L和R具有相同名称的文件,则即使内容不同,这些文件也都是相同的文件。但是,如果不是这样呢?如果L中的
git diff
重命名为R中的
file
,并且有人在R中创建了新的
bettername
怎么办?
file
提供了
git diff
(或“中断配对”)选项。启用
-B
时,如果名称不太相似,则以名称开头的文件将失去配对。也就是说,Git将检查两个blob哈希是否匹配,如果不匹配,则Git将计算相似性索引。如果索引低于某个阈值,则Git将破坏配对并将两个文件放入重命名检测队列,然后再运行
-B
样式的重命名检测器。
--find-renames
,您实际上指定了两个相似性阈值:第一个数字是何时暂时断开配对,第二个数字是何时永久断开配对。
-B
使用
git merge
git diff --find-renames
执行三向合并时,有三个输入:
git merge
和
--ours
。
--theirs
命令。一个将基数与L比较,另一个将基数与R比较。
git diff
的情况下运行。如果从base到L的差异找到一个重命名,则Git知道使用该重命名中显示的更改。同样,如果从base到R的差异找到一个重命名,则Git知道使用这些更改。如果两个差异都显示重命名,它将合并两组更改,并尝试(但通常失败)合并两个重命名。
--find-renames
也使用重命名检测器
git log --follow
时,Git遍历提交历史记录,一次提交一对(父级和子级),从父级到子级进行比较。它打开有限形式的重命名检测代码,以查看您正在抄送的一个文件是否在该提交对中被重命名。如果是这样,
git log --follow
移至父级后,它将立即更改其查找的名称。该技术效果很好,但是在合并时会遇到一些问题(因为合并提交有多个父项)。
--follow
与提交R中的文件
git log
是“不是”文件,因此Git可以使用重命名检测来确定。在某些情况下(例如检出提交L或R),这一点无关紧要。在某些情况下,例如将两个提交区分开,这很重要,但仅对我们试图理解所发生情况的人类有用。但是在某些情况下,例如合并,这非常重要。
关于git - git如何将Blob与提交树中的文件匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55616349/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!