git:如何自动合并同一文件中的非冲突更改?

git: How automatically merge non-conflicting changes in the same file?

提问人:jaw 提问时间:10/17/2023 最后编辑:jaw 更新时间:10/19/2023 访问量:95

问:

我正在尝试解决 git 冲突。

假设我有一个文件已经存在于 repo 中:versions.json

{
  "a": {
    "name": "component-a",
    "version": 1,
  },
  "b": {
    "name": "component-b",
    "version": 1,
  },
}

然后

  • 有一个具有并行阶段的 CI 管道。一个构建“component-a”,第二个构建“component-b”,两者都在 monorepo 中。
  • 当“component-a”完成时,它会更新文件并设置“a”"version": 2
  • 当“component-b”完成时,它会更新文件并设置“b”"version": 2
  • 每个组件将
  • 进行更改
  • 提交更改
  • 做一个git pull --rebase
  • 做一个git push

此操作失败,并出现合并冲突:

Rebasing (1/2)
Auto-merging versions.json
CONFLICT (add/add): Merge conflict in versions.json
error: could not apply 29b568d2... <previous commit message>

组件永远不会改变同一条线,因此没有真正的冲突 IMO。

我试图在提交之前添加一个拉取,这在大多数时候都有效,但由于 monorepo 非常大,它需要时间和一些时间,这会导致一个组件在另一个组件的拉取期间提交的竞争条件。

所以我想在最后的推动或直接拉动时修复它。

有没有办法在没有人工干预的情况下以自动化的方式做到这一点?

git git-merge-conflict

评论

0赞 matt 10/17/2023
“组件永远不会改变同一条线,因此没有真正的冲突 IMO。”更改 O. 冲突跨越相邻的行;这只是一个事实。你能在 和 之间插入一个虚拟行吗?这样他们就不会相邻了。"a""b"
0赞 jaw 10/17/2023
@matt实际上,更改之间有多行,我只是简化了文件,因为我认为这无关紧要。
0赞 jaw 10/17/2023
@matt我更新了 OP 以更好地反映实际文件。
1赞 matt 10/17/2023
哦,我明白。问题不在于双方都编辑了文件。问题是双方都创建了文件。对不起,我没有仔细研究证据。
0赞 TTT 10/18/2023
这是怎么回事:当“component-a”完成时,它会更新文件并在“a”中设置“version”: 2,但是,冲突错误显示“add/add”?是创建文件还是编辑文件?

答:

3赞 TTT 10/18/2023 #1

标题是一个技巧问题:

如何自动合并同一文件中的非冲突更改?

这是已经发生的情况,也是一旦你解决实际问题就会发生的情况,这只是你的并行管道阶段需要从文件已经存在的共享提交开始。原因是在 Git 中,冲突只能在“修改与修改”场景中自动解决。如果一方或双方“添加”或“删除”文件,则不会发生自动冲突解决。

由于您正在变基 2 次提交而不是 1 次提交,我们可以从输出中看到:

Rebasing (1/2)

由于冲突是:

CONFLICT (add/add): Merge conflict in versions.json

我们知道,要变基的第一次提交必须是添加文件的提交,第二次提交是修改文件的地方。管道每个阶段的第一次提交不是相同的 ID,这会导致“添加/添加”冲突。

解决方法是同步所有阶段,以便它们从已经包含文件的同一提交 ID 开始,然后从那时起重新运行管道应该能够按预期自动解析文件,因为行更改都相隔 2 行以上。

评论

0赞 jaw 10/19/2023
感谢您的回复。非常有趣,您可以从输出中获得哪些信息。但是:所有阶段都从同一个提交开始,该文件肯定在所有阶段之前和所有阶段都已经存在,并且文件中只有修改,没有添加任何内容。
1赞 j6t 10/19/2023
那么,您如何解释指示的是添加/添加冲突,而不是修改/修改的冲突?
0赞 TTT 10/19/2023
@jaw 不确定你是否看到 j6t 的评论,但我同意这个问题。您可以运行命令并检查输出吗?我怀疑您会在本地分支上看到 2 个提交,其中第一个添加了文件。此外,如果您尝试,您可能还会看到正在添加的文件。git log @ @{u} --graphgit show 29b568d2
0赞 jaw 10/21/2023
我 100% 确定,没有添加 was。此文件已存在多年。提交 29b568d2 是一个合并提交,我将 main 的最新更改合并到发布分支中。所有阶段都以相同的提交开始,我检查了一下。我到底在 git log graph 命令中寻找什么?
0赞 TTT 10/21/2023
@jaw 奇怪的是,合并提交正在使用 .此命令输出 1 还是 2:git pull --rebasegit show -s --format=%p 29b568d2 | wc -w