Re: [BUG] git merge sometimes loses changes from one branch
From: Elijah Newren <hidden>
Date: 2025-09-12 22:57:07
On Fri, Sep 12, 2025 at 6:41 AM Guo Tingsheng [off-list ref] wrote:
Hello Git developers,
I would like to report a potential issue in Git's merge behavior, where changes from one branch may be lost even when the other branch does not modify the same location.
Environment:
- git version: 2.43.0
- OS: Ubuntu 24.04 LTS
Steps to reproduce:
1. On branch A, modify a file at a certain location:
@@ -1026,7 +1028,9 @@
public final class AutoBuilderCompilationTest {
" }",
"}");
Compilation compilation =
- javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);
+ javac()
+ .withProcessors(new AutoBuilderProcessor())
+ .compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
2. On branch B, make no changes to this location.
3. Merge branch A and branch B.
Expected result:
- The merge should retain the changes made in branch A:
@@ -1026,7 +1028,9 @@
public final class AutoBuilderCompilationTest {
" }",
"}");
Compilation compilation =
- javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);
+ javac()
+ .withProcessors(new AutoBuilderProcessor())
+ .compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
Actual result:
- Git sometimes produces a merged result where the modification from branch A is lost, yielding:
@@ -1026,7 +1028,9 @@
public final class AutoBuilderCompilationTest {
" }",
"}");
Compilation compilation =
javac().withProcessors(new AutoBuilderProcessor()).compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
Additional information:
- This issue occurs even when the other branch (B) does not modify the same location.
- It appears to happen non-deterministically and may lead to subtle bugs in real-world merges.My only guess here would be having a non-unique merge-base, where one of the merge bases also introduced this change, so that it appears that A made no change relative to the consolidated merge base while also making it look like branch B undid the change relative to that consolidated merge base. But, that's a wild guess and I have no idea if that's related to what you're seeing or if there's some unrelated issue at play. Can you create a testcase to reproduce this, either a repository that others can clone together with the commands to trigger it, or a bunch of commands to both create a simple repository and demonstrate the issue?