threads / discuss / 61225

Feature request: a merge strategy that makes any file difference a merge conflict

Subject: Feature request: a merge strategy that makes any file difference a merge conflict

## tl;dr

4 messages between Mar 29, 2024 and Apr 1, 2024.

replies: 3people: 3as markdown or json

Michael Ernst· Mar 29, 2024, 19:20 UTC · lore

Git's built-in merge strategies, such as ort, sometimes create a clean-but-incorrect merge. A merge driver or a mergetool cannot be used to correct such problems, because a merge driver or mergetool is only called when the strategy resulted in a conflict (so far as I understand). It is challenging to write a merge strategy, but it is much easier to write a merge driver or a mergetool.

If git had a strategy that always caused a merge conflict (even when the differences are mergeable), then a merge driver or mergetool would be called on every file difference. This effectively permits a user to completely replace git's merge strategy, without the difficulty of writing a merge strategy.

I realize that the proposed strategy would likely only create merge conflicts when no two of {parent1,parent2,base} are the same -- that is, only when the low-level merge driver `git merge-file` is called. That is fine with me.

What do you think of this feature request?

Thanks in advance, -Mike

Junio C Hamano· Mar 29, 2024, 19:40 UTC · re: Michael Ernst · lore

Re: Feature request: a merge strategy that makes any file difference a merge conflict

Michael Ernst <mernst@cs.washington.edu> writes:
Show 5 quoted lines
> Git's built-in merge strategies, such as ort, sometimes create a
> clean-but-incorrect merge.  A merge driver or a mergetool cannot be
> used to correct such problems, because a merge driver or mergetool is
> only called when the strategy resulted in a conflict (so far as I
> understand).

A custom low-level merge driver is always called when selected via the attribute mechansism (see how merge-ll.c:ll_merge() calls find_ll_merge_driver()) and participates in a content-level 3-way merge.

If you are trying to interfere with cases that a content-level 3-way merge does not kick in (e.g., your side did not change anything in the file since their history forked, and they modified the file; the tree level 3-way merge will resolve it to take their version), then it is true that the low-level merge driver is not invoked, but I somehow get an impression from the above description that it is not what you are trying to do.

> It is challenging to write a merge strategy, but it is
> much easier to write a merge driver or a mergetool.

A merge strategy is about performing three-way merge at the tree level, figuring out which three variants of contents to hand to a merge driver that handles the content-level three-way merge. They serve totally different purposes and comparing them is like comparing apples and oranges.

Michael Ernst· Mar 29, 2024, 20:43 UTC · re: Junio C Hamano · lore

Re: Feature request: a merge strategy that makes any file difference a merge conflict

Junio-

Thank you for the clarification. There is a lot of misleading information about this on the Internet.

I was mistaken about when a merge driver is called. Now I see that the merge driver is called anytime that no two of {base,parent1,parent2} are the same. This means that a merge driver *can* prevent a clean-but-incorrect merge. I was right that a mergetool cannot be used to correct a clean-but-incorrect merge.

-Mike
Thomas Braun· Apr 1, 2024, 11:00 UTC · re: Michael Ernst · lore

Re: Feature request: a merge strategy that makes any file difference a merge conflict

On 29.03.2024 20:20, Michael Ernst wrote:
[...]
> What do you think of this feature request?

I wanted to propose to mark the relevant files as binary as that should prevent the merge to happen. But this is not working.

git init

echo "*.txt binary" > .gitattributes git add .gitattributes git commit -m ".gitattributes: Add it" .gitattributes

echo "a" > test.txt git add test.txt git commit -m "test.txt: main" test.txt

git checkout -b feature echo "ab" > test.txt git commit -m "test.txt: feature" test.txt

git checkout main git merge --no-ff --stat --no-edit feature

Merge made by the 'ort' strategy.
  test.txt | Bin 22 -> 3 bytes
  1 file changed, 0 insertions(+), 0 deletions(-)
git log -p test.txt
commit ec7cab2fa30c26738c6254202a399a616959a661 (feature)
Author: Thomas Braun <thomas.braun@byte-physics.de>
Date:   Mon Apr 1 12:56:07 2024 +0200
     test.txt: feature
diff --git a/test.txt b/test.txt
index 346a56a..81bf396 100644
Binary files a/test.txt and b/test.txt differ

commit 61e195554351dada7494e4eb4935d96120680420
Author: Thomas Braun <thomas.braun@byte-physics.de>
Date:   Mon Apr 1 12:50:29 2024 +0200

     test.txt: main

diff --git a/test.txt b/test.txt
new file mode 100644
index 0000000..346a56a
Binary files /dev/null and b/test.txt differ

I would have expected to see a merge conflict as git can't know how to 
merge binaries. Or am I misunderstanding something here?

← back to recent threads