# Conflict Resolution

> Use when encountering merge/rebase conflicts in Java/Gradle repos - create a safety branch first, resolve conflicts cleanly, verify with ./gradlew clean build, confirm the application still runs, and keep the change revertable.

- Skill: `ananthdakoji2001/conflict-resolution` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ananthdakoji2001/conflict-resolution`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ananthdakoji2001/conflict-resolution/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Ananthdakoji2001 (https://skillmd.com/u/ananthdakoji2001)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ananthdakoji2001/conflict-resolution

---

# Conflict Resolution (Java/Gradle)

## Overview

Handle merge/rebase conflicts systematically to maintain code integrity.

**Core principle:** Conflicts require careful resolution, not just picking one side.

**Workspace facts:**
- Repos are Java + Gradle (Spring Boot), branched off `master` (not `main`) unless the repo uses another trunk.
- Shell may be Windows PowerShell. Run Gradle with `.\gradlew` (or `./gradlew` in git-bash).
- Build/verify command is **`./gradlew clean build`**.
- `spotless` may reformat code on build (`spotlessApply`); expect formatting/import-order changes.
- A **library** module is verified via build + `publishToMavenLocal`.
- A **runnable Spring Boot app** is verified via `bootRun` (clean startup).

**Announce at start:** "I'm using conflict-resolution to handle these merge conflicts."

## When Conflicts Occur

| Situation | Example |
|-----------|---------|
| Rebasing on updated master | `git rebase origin/master` |
| Merging master into branch | `git merge origin/master` |
| Cherry-picking commits | `git cherry-pick <sha>` |
| Pulling with local changes | `git pull` |

## The Resolution Process

```
Conflict Detected
       │
       ▼
┌─────────────────┐
│ 0. SAFETY NET   │ ← Create backup branch (revertable)
└────────┬────────┘
         ▼
┌─────────────────┐
│ 1. UNDERSTAND   │ ← What's conflicting and why?
└────────┬────────┘
         ▼
┌─────────────────┐
│ 2. ANALYZE      │ ← Review both versions
└────────┬────────┘
         ▼
┌─────────────────┐
│ 3. RESOLVE      │ ← Make informed decision
└────────┬────────┘
         ▼
┌─────────────────┐
│ 4. VERIFY       │ ← Build passes, app runs
└────────┬────────┘
         ▼
┌─────────────────┐
│ 5. CONTINUE     │ ← Complete the operation
└─────────────────┘
```

## Step 0: Create a Safety Net (do this FIRST)

**Before starting any rebase/merge or touching conflicts**, make the state revertable.

1. Confirm a clean working tree (commit or stash local changes first):

```bash
git status
```

2. Record the current commit and create a backup branch that points at it:

```bash
# Record where you are (copy the SHA somewhere)
git rev-parse HEAD

# Create a backup branch at current HEAD (does not switch branches)
git branch backup/<current-branch>-pre-merge
```

Use a clear, unique name, e.g. `backup/feature-PROJ-1234-pre-rebase`. If one exists, add a numeric suffix.

3. Only now start the operation (`git rebase origin/master`, `git merge origin/master`, etc.).

**To revert to the old state at any point:**

```bash
# Abort the in-progress operation
git rebase --abort        # or: git merge --abort

# If already past the point of abort, hard-reset back to the backup
git reset --hard backup/<current-branch>-pre-merge

# Last resort: find the pre-conflict commit
git reflog
git reset --hard <good-sha>
```

Delete the backup branch only after the build passes, the app runs, and the change is pushed:

```bash
git branch -D backup/<current-branch>-pre-merge
```

## Step 1: Understand the Conflict

```bash
# List files with conflicts
git status

# See the conflict markers in a file
git diff <path>
```

```java
<<<<<<< HEAD
// Your changes (current branch)
public User createUser(UserData data) {
  return new User(data, generateId());
}
=======
// Their changes (master)
public User createUser(UserData data) {
  return repository.save(new User(data, generateId()));
}
>>>>>>> origin/master
```

```bash
# See what changed on each side
git log --oneline --left-right HEAD...origin/master -- <path>
git diff HEAD...origin/master -- <path>
```

## Step 2: Analyze Both Versions

| Question | Consider |
|----------|----------|
| What was the intent of your change? | Your feature/fix |
| What was the intent of their change? | Their feature/fix |
| Are they mutually exclusive? | Can both coexist? |
| Which is more recent/correct? | Check issue references |
| Do both need to be kept? | Merge the logic |

## Step 3: Resolve the Conflict

### Keep Theirs (master)

```bash
git checkout --theirs <path>
git add <path>
```

### Keep Ours (your branch)

```bash
git checkout --ours <path>
git add <path>
```

> Note: during a **rebase**, `--ours`/`--theirs` are inverted (ours = master, theirs = your commit). Read `git status` header to confirm.

### Manual Merge (both)

Remove ALL conflict markers and combine logic intentionally:

```java
public User createUser(UserData data) {
  validateUserData(data);                       // your addition
  return repository.save(new User(data, generateId())); // their change
}
```

```bash
git add <path>
```

The final file must have NO `<<<<<<<`, `=======`, or `>>>>>>>` markers.

## Step 4: Verify Resolution

### No leftover markers

```bash
git diff --check
git grep -nE "^(<<<<<<<|=======|>>>>>>>)" -- src
```

Both should return nothing.

### Build (required)

```bash
./gradlew clean build
```

- If it fails on **checkstyle/spotless**, fix, save, and re-run — spotless may rearrange imports/formatting.
- If it fails after 3 attempts, stop and ask the user for guidance before continuing.

### The application must run (required)

After the build passes, confirm the artifact actually works:

- **Spring Boot app:** start it and confirm clean startup, then stop it.

```bash
./gradlew bootRun
# Wait for "Started ...Application in N seconds", confirm no startup errors, then stop (Ctrl+C).
```

- **Library module:** publish locally so downstream can consume it.

```bash
./gradlew publishToMavenLocal
```

Do not consider the conflict resolved until the build passes **and** the app starts / the library publishes cleanly.

## Step 5: Continue the Operation

### After Rebase

```bash
git rebase --continue
# repeat resolution for further conflicts
git push --force-with-lease
```

### After Merge

```bash
git commit          # completes the merge (keep default merge message or a clear one)
git push
```

### If resolution goes wrong

```bash
git rebase --abort         # or: git merge --abort
git reset --hard backup/<current-branch>-pre-merge
```

## Complex Conflicts

### Multiple files

Resolve one file at a time: edit → `git add <file>` → next. When all are staged, `git rebase --continue` (or commit the merge).

### Semantic conflicts

Code can merge cleanly but still be broken (e.g. a caller uses an old method signature). This is why **`./gradlew clean build` and running the app are mandatory** after resolution.

### Generated sources

If the project regenerates sources from OpenAPI/config on build, do not hand-resolve conflicts in generated folders — resolve the inputs, then `./gradlew clean build` regenerates them.

### Dependency conflicts (build.gradle / gradle.properties)

```
<<<<<<< HEAD
  libraryVersion = "0.32.0"
=======
  libraryVersion = "0.31.0"
>>>>>>> origin/master
```

1. Choose the correct version (usually the higher/newer unless there is a reason not to).
2. Re-run `./gradlew clean build` so dependency resolution and locks update.

## Checklist

- [ ] Working tree clean; backup branch `backup/<branch>-pre-merge` created
- [ ] All conflicting files identified
- [ ] Each conflict analyzed (both sides understood)
- [ ] Conflict markers removed; files staged (`git add`)
- [ ] `git diff --check` and marker grep are clean
- [ ] `./gradlew clean build` succeeds
- [ ] Application runs (`bootRun` for app) / library publishes (`publishToMavenLocal`)
- [ ] Operation completed (`git rebase --continue` / merge commit)
- [ ] Backup branch deleted only after push succeeds

## Integration

Called when `git rebase`, `git merge`, or a PR/MR shows conflicts. Ensures a revertable safety net, clean resolution, a passing `./gradlew clean build`, and a working application.

