Git 中的合并冲突是由什么构成的?

发布于 2024-10-16 08:20:22 字数 364 浏览 3 评论 0 原文

git 如何确定特定合并存在冲突以及冲突是什么?

我的猜测是这样的:如果被合并的两个提交有一个共同的父提交,并且如果它们都更改了父提交的 X 行,那就是冲突。

让我的理解变得复杂的是:

  • “更改行 X”可能意味着用几行新行替换它,并且这仍然显示为一个冲突(版本 A 有这一行,版本 B 有这 5 行,或其他)
  • 如果您确实插入提交之一中的行,一个愚蠢的算法会认为所有后续行都已更改:第 30 行现在具有第 25 行以前的内容,第 31 行具有第 26 行以前的内容,等等。但是 git 可以说它们是相同的,但我不知道如何。

谁能解释一下这是如何工作的,或者给我指出一个链接?

How does git determine that a particular merge has a conflict and what the conflict is?

My guess would go something like this: if the two commits being merged have a common parent commit, and if they have both changed line X from what the parent had, that's a conflict.

What complicates my understanding is:

  • "Changing line X" can mean replacing it with several new lines, and that's still shown as one conflict (version A has this one line, and version B has these 5 lines, or whatever)
  • If you did insert lines in one of the commits, a dumber algorithm would think that all subsequent lines had changed: Line 30 now has the former contents of line 25, 31 has the former contents of 26, etc. But git can tell that those are the same, and I don't know how.

Can anybody explain how this works, or point me to a link that does?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叫思念不要吵 2024-10-23 08:20:22

基本上,使用git,每次合并都是一次冲突,这会留下一个索引,其中包含每个文件的三个版本,每个分支的版本和基础版本。在此索引上,运行各种解析器,它们可以为每个单独的文件决定如何解决问题。

第一阶段是一个简单的解析器,它负责处理诸如未更改的文件、一个分支修改了文件而另一个分支没有修改文件的情况,或者两个分支包含相同的文件新版本的情况。

之后,插件会查看剩余的情况。有一个插件可以通过识别一个分支中的各个更改(例如 diff)并尝试将这些更改应用到另一个分支来处理文本文件,如果这不起作用,则重新放置冲突标记。此时,您可以轻松地连接自己的合并工具,例如,您可以编写一个工具,知道如何在不违反格式良好的情况下合并 XML 文件,或者提供允许交互式编辑和并排的图形用户界面。 -侧视图(例如,kdiff3 就是这样做的)。

所以冲突的呈现实际上是所使用的插件的问题;文本文件的默认插件将使用与 CVS 相同的样式,因为人们和工具都习惯了它,并且冲突标记是几乎所有编程语言中已知的语法错误。

Basically, with git, every merge is a conflict, which leaves you with an index that contains three versions of each file, the versions from each branch and the base. On this index, various resolvers are run, which can decide for each individual file how to resolve the matter.

The first stage is a trivial resolver, which takes care of things like unchanged files, cases where one branch has modified a file while the other didn't, or where both branches contain the same new version of the file.

Afterwards, it's plugins that look at the remaining cases. There is a plugin that handles text files by identifying individual changes (like diff) in one branch and trying to apply those to the other branch, falling back on placing conflict markers if that doesn't work. You can easily hook in your own merge tool at this point, for example, you could write a tool that knows how to merge XML files without violating well-formedness, or that gives a graphical user interface that allows interactive editing and a side-by-side view (for example, kdiff3 does that).

So the presentation of conflicts is really a matter of the plugin used; the default plugin for text files will use the same style as CVS did, because people and tools are used to it, and the conflict markers are a known syntax error in almost any programming language.

り繁华旳梦境 2024-10-23 08:20:22

我不认为合并算法与 Git 有什么特别之处:它是一个经典的 3 路合并算法 (不是 Codeville 的),可以使用具有多种策略(默认:递归、解析或章鱼)。
结果是相当简单的合并过程这是此处描述的
然后,任何可视化需求都会委托给第三方合并/差异工具。

I don't think the merge algorithm has anything special with Git: it is a classic 3-way merge algorithm (not the Codeville one), which can be used with several strategies (default: recurse, or resolve or octopus).
The result is a fairly simply merge process which is described here.
Any visualization need is then delegated to third-party merge/diff tools.

烟雨凡馨 2024-10-23 08:20:22

浏览至此 如何呈现冲突 段落rel="nofollow">页面

LE:没有关于冲突情况的真正文档,也没有文件冲突标记,因为我在这里的评论中受到攻击,所以这里是源代码中的指针,这些指针导致接近 git 为了实现冲突状态而遵循的策略。文件 merge-recursive.c,搜索“CONFLICT字符串。通过这样做,我们可以很容易地发现确实存在一些冲突情况,例如:

  • CONFLICT(重命名/重命名)
  • 冲突(内容)
  • 冲突(重命名/目录)
  • 冲突(重命名/删除)
  • 冲突(重命名/添加)
  • 冲突(删除/修改)
  • ... 等等

如果你问我,是的,它们应该被记录并明确指出,但是他们并不是没有什么可做的,然后检查源代码..但是有人真的可以从这里开始并创建一个很好的文档,然后将其发送到 git 项目

@Wim Coenen 是的,这也取决于合并策略,但是如何。如果你问我,你也可以阅读合并策略,但你仍然有疑问。

Browse to the HOW CONFLICTS ARE PRESENTED paragraph on this page.

LE: There is no real documentation for the conflict cases nor file conflict markers and since i am getting bashed in the comments here, here's the pointers in the source code that lead somewhere close to what strategies does git follow in order to achieve a conflict state. File merge-recursive.c, search for the "CONFLICT string. By doing that we can easily find out that there are really a handful of conflict cases like:

  • CONFLICT (rename/rename)
  • CONFLICT (content)
  • CONFLICT (rename/directory)
  • CONFLICT (rename/delete)
  • CONFLICT (rename/add)
  • CONFLICT (delete/modify)
  • ... ans so on

If you ask me, yes they should be documented and clearly pointed out, but they aren't so nothing left to do then inspect the source.. but someone can really pick up from here and create a nice documentation and then send it to the git project.

@Wim Coenen yes it depends on merge strategies too, but how conflicts are presented gives much more of an insight. Then you can read merge strategies too if you ask me, but you still remain in doubt.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文