cherry-pick 是应用更改还是尝试合并整个文件的内容?
Does cherry-pick apply changes or try to merge the contents of the entire file?
我正在阅读 this article 关于 cherry-picking 的文章,那里有下面的图片:
但是,这张图片似乎误导了我。从我的简单测试来看,似乎不仅是差异,而且整个文件内容都被合并了。这是实验:
我有这个提交图:
A--B
\
C
提交 A
在 file.txt
中有此内容:
l1
l2
l3
提交 B
有小改动:
l1
l2-new
l3
提交 C
有小改动:
l1
l2
l3-new
所以现在我正在尝试使用 cherry-pick、
在提交 C
上重播提交 B
git cherry-pick B
我遇到了冲突,
<<<<<<< HEAD
l2
l3-new
=======
l2-3
l3
>>>>>>> C
如果仅应用更改,则不应存在。由于我在 C
提交中没有触及 l2
行,它应该可以顺利应用。我说得对吗?
Git 正在存储文件,而不是差异,所以 mb 由于行很近,git 无法正确解析它。
你最终会遇到冲突,因为更改太靠近了(就行号而言)。上下文(通常是实际差异块周围的 3 行)需要匹配,否则 Git(和其他版本控制系统)会将更改标记为冲突。由于您的示例中的部分上下文发生了变化,因此它被标记为冲突。
Git
存储文件,但它在很多地方生成和使用差异。
A diff
记录提交前后受影响行的状态;它还存储修改区域前后的一行文本。 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
之间的更改。
该格式是 统一差异格式 的变体,维基百科页面上有关于 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
然后我们挑选提交 B
,并应用它引入的更改(将第 2 行从 l2
更改为 l2-new
) 而无需验证上下文。该文件现在看起来像:
l1
l2-new
等一下! l3
在哪里?
我没有在提交 C
时删除行 l3
并且在提交 B
时我也没有触及它。 在不检查上下文的情况下应用差异会导致数据丢失。 Git
在应用差异时总是检查上下文,我想所有使用差异的程序都会这样做一样。
我正在阅读 this article 关于 cherry-picking 的文章,那里有下面的图片:
但是,这张图片似乎误导了我。从我的简单测试来看,似乎不仅是差异,而且整个文件内容都被合并了。这是实验: 我有这个提交图:
A--B
\
C
提交 A
在 file.txt
中有此内容:
l1
l2
l3
提交 B
有小改动:
l1
l2-new
l3
提交 C
有小改动:
l1
l2
l3-new
所以现在我正在尝试使用 cherry-pick、
在提交C
上重播提交 B
git cherry-pick B
我遇到了冲突,
<<<<<<< HEAD
l2
l3-new
=======
l2-3
l3
>>>>>>> C
如果仅应用更改,则不应存在。由于我在 C
提交中没有触及 l2
行,它应该可以顺利应用。我说得对吗?
Git 正在存储文件,而不是差异,所以 mb 由于行很近,git 无法正确解析它。
你最终会遇到冲突,因为更改太靠近了(就行号而言)。上下文(通常是实际差异块周围的 3 行)需要匹配,否则 Git(和其他版本控制系统)会将更改标记为冲突。由于您的示例中的部分上下文发生了变化,因此它被标记为冲突。
Git
存储文件,但它在很多地方生成和使用差异。
A diff
记录提交前后受影响行的状态;它还存储修改区域前后的一行文本。 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
之间的更改。
该格式是 统一差异格式 的变体,维基百科页面上有关于 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
然后我们挑选提交 B
,并应用它引入的更改(将第 2 行从 l2
更改为 l2-new
) 而无需验证上下文。该文件现在看起来像:
l1
l2-new
等一下! l3
在哪里?
我没有在提交 C
时删除行 l3
并且在提交 B
时我也没有触及它。 在不检查上下文的情况下应用差异会导致数据丢失。 Git
在应用差异时总是检查上下文,我想所有使用差异的程序都会这样做一样。