当前位置: 首页 > 知识库问答 >
问题:

git合并冲突究竟何时发生

胥智
2023-03-14

我正在使用git跟踪对LaTeX文档的更改。我倾向于将合著者的反馈保存在一个单独的分支中,并在以后将其合并。到目前为止,事情似乎神奇地正确地合并了,但我想知道合并冲突何时发生,这样我就可以在合并过程中获得一些真正的信任(当然我不希望文本出现问题)。

关于StackOverflow,有许多问题似乎问了同样的问题,但没有一个答案是非常具体的。例如,这个答案指定如果对同一个区域进行更改,就会发生冲突,但这让我想知道这些区域到底是什么。只是对同一行进行了更改,还是考虑了某些上下文?

共有1个答案

隗嘉歆
2023-03-14

这是逐行进行的,答案是否定的和肯定的:上下文确实重要,但重要的数量是棘手的。这比你一开始想象的要多也要少。

你可能想先浏览一下相关问题的答案,了解一下背景。现在,我将假设我们将base作为(单个)合并基础(也许我们通过标记特定提交来设置名称base,例如,git tag base$(git merge base HEAD other))和HEAD作为我们在分支b1上的提交,并使用其他分支名称b2命名另一个提交。

接下来,我们来看两个差异:

git diff base HEAD
git diff base b2

如果我们看到文件F的所有三个版本都不同(因此F出现在两个输出中,并且更改不同),那么我们必须在本质上一个一个地进行diff-hunk。当差异块重叠但进行不同的更改时,Git声明了冲突。但这似乎是你的问题,“做出不同的改变”到底意味着什么?

我认为这是最好的例子。例如:

$ git checkout b1
[checkout messages here - but I was already on b1]
$ git diff base HEAD
diff --git a/basefile b/basefile
index df781c1..e4f9e4b 100644
--- a/basefile
+++ b/basefile
@@ -4,6 +4,7 @@
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # are met:
+# added line in b1
 # 1. Redistributions of source code must retain the above copyright
 #    notice, this list of conditions and the following disclaimer.
 # 2. Redistributions in binary form must reproduce the above copyright

以及:

$ git diff base b2
diff --git a/basefile b/basefile
index df781c1..c96620e 100644
--- a/basefile
+++ b/basefile
@@ -4,7 +4,6 @@
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # are met:
-# 1. Redistributions of source code must retain the above copyright
 #    notice, this list of conditions and the following disclaimer.
 # 2. Redistributions in binary form must reproduce the above copyright
 #    notice, this list of conditions and the following disclaimer in the

请注意,虽然这些变化在某种意义上不触及同一条线,但在某种意义上,它们也触及同一条线。我添加了第7行(将旧的第7行向下推到第8行),我删除了旧的第7行。显然,这些是“相同”的路线。所以:

$ git merge b2
Auto-merging basefile
CONFLICT (content): Merge conflict in basefile
Automatic merge failed; fix conflicts and then commit the result.

让我们中止这个合并并考虑分支<代码> B3<代码>的提示(<代码> B1 < /代码>和<代码> B3 < /代码>的合并基础与“代码> B1 < /代码>和<代码> B2 < /代码>中的合并基)相同,在我的设置中)。

$ git merge --abort
$ git diff base b3
diff --git a/basefile b/basefile
index df781c1..e2b8567 100644
--- a/basefile
+++ b/basefile
@@ -5,7 +5,6 @@
 # modification, are permitted provided that the following conditions
 # are met:
 # 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
 # 2. Redistributions in binary form must reproduce the above copyright
 #    notice, this list of conditions and the following disclaimer in the
 #    documentation and/or other materials provided with the distribution.
 $ git merge --no-edit b3
Auto-merging basefile
Merge made by the 'recursive' strategy.
 basefile | 1 -
 1 file changed, 1 deletion(-)

这一次没有冲突,尽管两个不同的大块头接触了同一个区域。第二个diff删除了一个不“接触”添加行的行,因此Git认为这是安全的。

如果您以同样的方式进行更多的实验,您将准确地发现哪些看似重叠的更改成功地结合在一起,哪些更改会导致冲突。显然,直接重叠的更改(例如,删除原始行42和插入不同的新行42)将发生冲突。但所有更改始终表示为“删除一些现有行,尽管可能为零”,然后是“添加一些新行,尽管可能为零”。更改—即使更改、添加或删除一行中的一个单词—也会删除非零数量的现有行,并添加非零数量的新行。纯删除(一个或多个完整行)添加零行,纯插入删除零行。最后,它归结为:“我们和他们的变化是否都涉及到相同的行号?”上下文几乎变得不相关,除了删除零行或插入零行时,上下文本身在某种意义上“就是”行。(我不确定这个说法有多大意义,所以如果它不可理解,那是我的错。;-)

(还请记住,如果您在工作时修改“合并到目前为止”文件,则在查看更改是否触及“相同”行时,必须使用原始基本文件的行号。由于“我们的”和“他们的”都具有相同的基本版本,因此我们可以在此处使用这条简单的捷径。)

请注意,这与应用补丁不同,补丁是在没有公共基础版本启动的情况下完成的。在补丁的情况下,上下文的使用要频繁得多:diff-hunk头提供了搜索上下文的位置,但由于它可能应用于不同版本的文件,因此上下文允许我们(和Git)在不同的行上进行相同的更改,只要上下文仍然匹配。

patch实用程序在这里使用不同的算法(一个“最大模糊”因子,看起来/-那么多行)。Git不做模糊因子;如果有必要,它会一直搜索到文件的开头或结尾。然而,它确实有一个通常的选择,即在确定上下文不匹配之前调整空白。

(当使用git apply应用补丁程序时,您可以添加-3-3way以允许git读取索引行,这些行提供文件blob的部分或完整散列ID。左侧散列ID是文件先前版本的散列:注意,在上述所有差异中,“基”basefile的版本具有IDdf781c1。如果Git可以从该ID中找到一个唯一的blob,它可以假装这是合并基,将一个合并基与HEAD区分开来,将补丁本身视为另一个差异,并以这种方式进行三方合并。这有时允许Git apply成功ere修补程序将失败。)

 类似资料:
  • 问题内容: HashMap中的Hash Collision或Hashing Collision并不是一个新话题,我遇到了多个博客和讨论区,解释了如何产生Hash Collision或如何以模棱两可和详细的方式避免它。我最近在一次采访中遇到了这个问题。我有很多事情要解释,但我认为准确地给出正确的解释真的很困难。抱歉,如果我在这里重复我的问题,请给我准确的答案: 哈希冲突到底是什么?它是一项功能或常见

  • 问题内容: 这是我在React中经常遇到的问题。保证在首次渲染组件时会触发该方法,因此似乎很自然地进行高度和偏移之类的DOM测量。但是,在组件生命周期的这一点上,很多时候我收到错误的样式读数。该组件 是 在DOM,当我与调试器打破,但它尚未在屏幕上绘制。我将宽度/高度大部分设置为100%的元素遇到了这个问题。当我进行测量时-一切正常,但是此方法在组件的初始渲染时不会触发。 所以我的问题是-何时确切

  • 对于很多人来说,合并时出现冲突是非常可怕的事,这就好像一不小心格式化了自己的硬盘一样。在这一章节里我将为你消除这种恐惧。 你不会把事情搞砸 首先你应该记住,你总是可以撤销一个合并操作,并且返回到冲突发生之前的状态。也就是说,你永远有机会放弃并重新开始。 如果你已经掌握了一些关于其它的版本控制系统的使用经验,例如 Subversion ,你可能会很难过。因为在 Subversion 中处理冲突是被大

  • 我制作了一个git存储库,并向其中添加了一个文本文件。这是100%用于学习目的。 > 从master创建了一个新分支,并附加了“2”。 最后,从master创建了一个分支并添加了“3”。 请您解释一下在这种或任何其他情况下,冲突是如何发生的?

  • 主要内容:执行 master 分支变更,出现冲突,解决冲突假设要在分支中执行更改,修改分支中的代码。添加一个计算长度的函数:,代码变化如下 - 假设验证代码后,没有问题就提交这些更改。 执行 master 分支变更 同时在分支中,另外一个开发人员()还会更改了内容,并将其更改推送到分支。 验证差异后,现在就提交更新内容。 在分支上,我们已经实现了一个函数。假设经过测试后,提交并将其更改推送到分支。 出现冲突 假设另外一个开发人员()想看看我们在分支上做了

  • 问题内容: 我看着一个合并标记,看起来都搞砸了。为了给您带来这种情况,让我们这样做: 现在进行合并(我使用SourceTree进行拉取)。标记看起来像这样: 因此,拉出的提交所做的是完全删除methodA并添加methodB。 但是您注意到有些行完全丢失了。 据我了解的过程,Git正在尝试一种所谓的自动合并,如果失败并在检测到冲突时发生冲突,则完全合并将由标有’<<< * HEAD’+ + +’=