* git merge bug report
@ 2025-04-15 12:23 mu gsh
2025-04-15 13:52 ` Junio C Hamano
2025-04-15 14:13 ` Lucas Seiki Oshiro
0 siblings, 2 replies; 4+ messages in thread
From: mu gsh @ 2025-04-15 12:23 UTC (permalink / raw)
To: git
Dear Git Maintainers,
I would like to report a bug I encountered in Git during a merge
operation. The method from one branch was merged into the wrong class,
despite there being no reported conflict.
Git Version: git version 2.49.0
Operating System: Arch Linux
Description:
When merging two commits involving changes to the same file, Git does
not report a conflict, but the resulting merged file places a method
in an unexpected class. This seems like a mismerge.
Steps to Reproduce
You can reproduce the issue using the following shell script:
```
#!/bin/bash
set -e
# init in /tmp dir
rm -rf /tmp/git-merge-bug
mkdir -p /tmp/git-merge-bug && cd /tmp/git-merge-bug
git init
cat > models.py <<EOF
class User:
name = "str"
class Product:
id = 0
EOF
git add models.py
git commit -m "initial: User and Product class"
# feature1
git checkout -b feature
cat > models.py <<EOF
class User:
name = "str"
def user_method(self):
return
class Product:
id = 0
EOF
git commit -am "feature: add method to User"
# feature 2
git checkout master
cat > models.py <<EOF
class User:
name = "str"
bugger = "fix me"
class NoMethod:
pass
class Product:
id = 0
EOF
git commit -am "master: add field to User and new class"
git merge feature
echo
echo "==== merged, user_method into NoMethod class ===="
cat models.py
```
Actual Result
After the merge, the user_method ends up inside the NoMethod class,
which is incorrect and unexpected.
Please let me know if any additional information is needed. Thank you
for your time and help.
Best regards,
gshmu
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: git merge bug report
2025-04-15 12:23 git merge bug report mu gsh
@ 2025-04-15 13:52 ` Junio C Hamano
2025-04-15 14:13 ` Lucas Seiki Oshiro
1 sibling, 0 replies; 4+ messages in thread
From: Junio C Hamano @ 2025-04-15 13:52 UTC (permalink / raw)
To: mu gsh; +Cc: git
mu gsh <yue937@gmail.com> writes:
> cat > models.py <<EOF
> class User:
> name = "str"
>
>
> class Product:
> id = 0
> EOF
> git add models.py
> git commit -m "initial: User and Product class"
>
> # feature1
> git checkout -b feature
> cat > models.py <<EOF
> class User:
> name = "str"
>
> def user_method(self):
> return
>
>
> class Product:
> id = 0
> EOF
> git commit -am "feature: add method to User"
>
> # feature 2
> git checkout master
> cat > models.py <<EOF
> class User:
> name = "str"
> bugger = "fix me"
>
>
> class NoMethod:
> pass
>
>
> class Product:
> id = 0
> EOF
> git commit -am "master: add field to User and new class"
>
> git merge feature
> echo
> echo "==== merged, user_method into NoMethod class ===="
> cat models.py
> ```
>
> Actual Result
>
> After the merge, the user_method ends up inside the NoMethod class,
> which is incorrect and unexpected.
>
>
> Please let me know if any additional information is needed. Thank you
> for your time and help.
I think this is very much expected, unfortunately. Git is language
agnostic in the sense that it does not know the meaning of the
contents of the file it is thrown at. With the merge, what it was
asked to do is:
- The other branch, "feature1", added three lines, an empty
user_method() definition and a blank line around it, before
lines that have 'class product:' and ' id = 0' (or after lines
that have 'class User:' and ' name = str' followed by a blank
line).
- In the meantime, you added some stuff in feature2.
- Please replay what the other branch did on top of what we have.
But after your feature2, the precontext lines that it can use as an
anchor no longer exist (the blank line after 'class User:' and '
name = str' is gone). while the post context lines ("blank followed
by 'class Product: followed by 'id = 0'") are still intact.
Wiggling the added three lines there would be a more natural choice
than having to deal with "bugger = 'fix me'" whose disposition is
totally unclear to unthinking non-mind that is a mechanical merge
machinery in Git.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: git merge bug report
2025-04-15 12:23 git merge bug report mu gsh
2025-04-15 13:52 ` Junio C Hamano
@ 2025-04-15 14:13 ` Lucas Seiki Oshiro
2025-04-15 16:20 ` mu gsh
1 sibling, 1 reply; 4+ messages in thread
From: Lucas Seiki Oshiro @ 2025-04-15 14:13 UTC (permalink / raw)
To: mu gsh; +Cc: git
Hi!
> I would like to report a bug I encountered in Git during a merge
> operation. The method from one branch was merged into the wrong class,
> despite there being no reported conflict.
Thanks for your script! I could reproduce this here!
When two branches changes the same plaintext file, Git tries to merge
them based on their contents without taking into account the syntax.
It is done using diff algorithms, which you can change using
`-X diff-algorithm=<algorithm>`.
I tried the four algorithms available (minimal, histogram, myers and
patience) and all of them produced the same result.
Sadly, they are not infallible and those mistakes may happen. There
are other cases where it can happen. For example, imagine a Python
class with only two methods and each branch deletes one of them.
After merging, it will leave an empty class definition, which is not
allowed in Python (unless you use `pass`). These algorithms are not
aware of that, and they'll leave an invalid Python file.
Also note that they are not exactly wrong. They only do their work
naively based on the information they have.
This way, it's always a good idea to check if the merge went well.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: git merge bug report
2025-04-15 14:13 ` Lucas Seiki Oshiro
@ 2025-04-15 16:20 ` mu gsh
0 siblings, 0 replies; 4+ messages in thread
From: mu gsh @ 2025-04-15 16:20 UTC (permalink / raw)
To: Lucas Seiki Oshiro; +Cc: git
Hi!
focus on the feature 2, the two double empty lines, which one is the new one?
```
bugger = "fix: the empty lines blow not the new added lines"
class NoMethod:
pass
class Product
```
Should the second one be newly added? instead of the first
On Tue, 15 Apr 2025 at 22:13, Lucas Seiki Oshiro
<lucasseikioshiro@gmail.com> wrote:
>
> Hi!
>
> > I would like to report a bug I encountered in Git during a merge
> > operation. The method from one branch was merged into the wrong class,
> > despite there being no reported conflict.
>
> Thanks for your script! I could reproduce this here!
>
> When two branches changes the same plaintext file, Git tries to merge
> them based on their contents without taking into account the syntax.
> It is done using diff algorithms, which you can change using
> `-X diff-algorithm=<algorithm>`.
>
> I tried the four algorithms available (minimal, histogram, myers and
> patience) and all of them produced the same result.
>
> Sadly, they are not infallible and those mistakes may happen. There
> are other cases where it can happen. For example, imagine a Python
> class with only two methods and each branch deletes one of them.
> After merging, it will leave an empty class definition, which is not
> allowed in Python (unless you use `pass`). These algorithms are not
> aware of that, and they'll leave an invalid Python file.
>
> Also note that they are not exactly wrong. They only do their work
> naively based on the information they have.
>
> This way, it's always a good idea to check if the merge went well.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-04-15 16:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-15 12:23 git merge bug report mu gsh
2025-04-15 13:52 ` Junio C Hamano
2025-04-15 14:13 ` Lucas Seiki Oshiro
2025-04-15 16:20 ` mu gsh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox