Q3 of 40 · Git

Walk through resolving a complex merge conflict in a Java test class.

GitSeniorgitmerge-conflictsjavateam-workflowconflict-resolution

Short answer

Short answer: A conflict in a Java test class typically happens when two branches modified the same method or class-level setup. Resolve it by reading both sides' intent (via git log), keeping both changes where sensible, verifying compilation and tests before finalising the merge commit, and scanning for leftover conflict markers.

Detail

Git marks conflicts with <<<<<<<, =======, and >>>>>>> markers. In a Java test file, conflicts commonly occur when: two branches added a new test method in the same position; one branch refactored a shared @BeforeEach while another added assertions that depended on the original setup; or both branches updated the same import list.

Step-by-step resolution:

  1. Open in a visual tool: git mergetool (configured to IntelliJ, VS Code, or vimdiff). Three-panel view: LOCAL (your branch), REMOTE (incoming branch), BASE (common ancestor). Never resolve complex Java conflicts in a text editor looking only at markers.

  2. Understand both changes' intent: read commit messages for both branches (git log --oneline HEAD...MERGE_HEAD). Don't resolve mechanically — understand what each change was trying to achieve.

  3. Keep both where sensible: if branch A added testCreateUser_returns201() and branch B added testCreateUser_returns400_withInvalidEmail(), both tests should survive. Conflicts aren't always "pick one".

  4. Update shared setup: if @BeforeEach changed on both sides, merge the setups so all tests still compile. Run ./mvnw test -Dtest=UserApiTest to confirm.

  5. Scan for leftover markers: grep -r "<<<<<<" src/test — one missed marker will break the build.

  6. Write a meaningful merge commit message: note what the conflict was and how you resolved it. Future readers will thank you.

// EXAMPLE

# Start the merge
git checkout main
git merge feature/user-api-refactor
# Auto-merging fails: CONFLICT in UserApiTest.java

# Inspect what changed on each side
git log --oneline HEAD...MERGE_HEAD --left-right

# Open visual merge tool (configured in ~/.gitconfig)
git mergetool src/test/java/com/example/api/UserApiTest.java
# Or in IntelliJ: Git menu → Resolve Conflicts

# After resolving, stage the fixed file
git add src/test/java/com/example/api/UserApiTest.java

# Verify compilation before committing
./mvnw compile -q

# Run affected tests
./mvnw test -pl api-tests -Dtest=UserApiTest -q

# Scan for any unresolved markers
grep -r "<<<<<<<" src/test/java && echo "UNRESOLVED" || echo "Clean"

# Complete the merge with a descriptive message
git merge --continue
# Write: "Merge feature/user-api-refactor — kept both createUser tests,
# merged @BeforeEach to preserve token setup from both branches"

// WHAT INTERVIEWERS LOOK FOR

A methodical process (understand intent, keep both changes, verify compilation and tests, scan for markers), use of a visual merge tool rather than raw text editing, and writing a meaningful merge commit message. Bonus: reading git log --left-right to understand what each branch changed before touching anything.

// COMMON PITFALL

Accepting 'theirs' or 'ours' blindly without reading both changes. In test files that often means silently dropping a valid test. The right resolution is almost always 'understand both branches' intent, then synthesise'.