Git
存储文件,但它会在很多地方生成和使用差异。
Adiff
记录提交前后受影响行的状态;它还存储修改区域前后的一行文本。Git
使用此信息来避免数据丢失和不一致。
假设我们创建了名为 的分支A
,B
并且C
在您的描述中具有这些名称的提交上。
$ git diff A B -- file.txt
diff --git a/file.txt b/file.txt
index f0f2307..0acba21 100644
--- a/file.txt
+++ b/file.txt
@@ -1,3 +1,3 @@
l1
-l2
+l2-new
l3
我要求Git
在file.txt
提交A
和B
.
该格式是统一差异格式的一种变体,在 Wikipedia 页面上对diff utility
.
简而言之,这diff
表示:将文件的第 2 行从更改为l2
,l2-new
但前提是第 1 行是l1
并且第 3 行是l3
。即使只更改了文件的第 2 行,Git
也包括文件的第 1 行和第 3 行diff
。它们是第 2 行发生的变化的上下文。
备注:在这种情况下,文件很小,第 1-3 行代表整个文件。Git
不使用整个文件,它只保护更改前 1 行和更改后 1 行更改的任何行块。例如,如果文件有 20 行,我们更改第 12 和 13 行,则diff
包含第 11-14 行。
回到我们的diff
,提交C
时文件的样子:
l1
l2
l3-new
但为了应用diff
,Git
期望它看起来像:
l1
l2
l3
因为它的期望没有得到满足,Git
所以不能diff
安全地应用并决定这是一个冲突。
为什么Git
需要上下文行?
假设在提交时C
我们删除了第二行。该文件将如下所示:
l1
l3
然后我们挑选 commit B
,并应用它引入的更改(将第 2 行从 更改l2
为l2-new
)而不验证 context。该文件现在看起来像:
l1
l2-new
稍等!在哪里l3
?
我没有l3
在提交时删除该行,C
也没有在提交时触摸它B
。在不检查上下文的情况下应用差异可能会导致数据丢失。 Git
总是在应用差异时检查上下文,我想所有使用差异的程序都这样做。