Skip to main content

Overview

Merge conflicts occur when Git cannot automatically merge changes from different branches. GitHub Desktop provides an intuitive interface to help you resolve conflicts and complete merges successfully.

Conflict Detection

Automatically detect conflicts when merging or rebasing

Visual Resolution

See conflicted sections side-by-side with clear markers

Manual Resolution

Choose “ours”, “theirs”, or edit manually

File-Level Actions

Resolve entire files with one click when appropriate

Understanding Merge Conflicts

What Causes Conflicts?

Conflicts happen when:
  • Two branches modify the same lines in a file
  • One branch modifies a file while another deletes it
  • Two branches create files with the same name
  • Binary files are modified in different ways

Types of Conflicts

Both branches modified the same lines:
<<<<<<< HEAD
const greeting = "Hello, World!";
=======
const greeting = "Hi there!";
>>>>>>> feature-branch
You must choose which version to keep or combine them.
One branch modified a file while another deleted it:
  • Keep the file: Use the modified version
  • Delete the file: Accept the deletion
Both branches renamed the same file differently:
  • Choose which name to use
  • Or rename to a new name entirely
Images or other binary files modified on both branches:
  • Choose one version (cannot merge binary files)
  • Or replace with a new file

Detecting Conflicts

During Merge

When merging branches:
1

Initiate Merge

Click Branch > Merge into current branch
2

Select Branch

Choose the branch to merge
3

Conflict Warning

If conflicts exist, GitHub Desktop:
  • Shows number of conflicted files
  • Lists affected files
  • Stops the merge for resolution

During Rebase

When rebasing:
1

Start Rebase

Click Branch > Rebase current branch
2

Conflict Detection

If conflicts occur:
  • Rebase pauses at the conflicted commit
  • Shows which commit caused the conflict
  • Displays conflicted files

During Cherry-Pick

When cherry-picking commits:
  • GitHub Desktop highlights conflicts immediately
  • Shows the commit being applied
  • Lists files with conflicts

Resolving Conflicts in GitHub Desktop

Conflict Resolution Interface

When conflicts occur, the Changes tab shows: Conflicted Files Section
  • Red warning icon
  • List of files with conflicts
  • “Resolve in [editor]” button
  • Manual resolution options
Conflict Markers
<<<<<<< HEAD (Current Change)
Your current branch's version
=======
The incoming branch's version
>>>>>>> branch-name (Incoming Change)

Step-by-Step Resolution

1

Identify Conflicted Files

In the Changes tab, locate files marked with a conflict icon
2

Open Conflict

Click a conflicted file to see the conflict markers
3

Choose Resolution Method

Select how to resolve:
  • Use Ours: Keep your current branch’s changes
  • Use Theirs: Accept the incoming branch’s changes
  • Open in Editor: Manually edit to combine or modify
4

Resolve Each Conflict

Repeat for all conflicted files
5

Mark as Resolved

Files are automatically staged after resolution
6

Complete Merge

Click Commit merge to finish the merge

Manual Resolution in Editor

For complex conflicts, edit files directly:
1

Open in Editor

Click Open in [your editor] for a conflicted file
2

Find Conflict Markers

Look for <<<<<<<, =======, and >>>>>>> markers
3

Edit the File

  • Remove conflict markers
  • Keep, combine, or rewrite the conflicted sections
  • Save the file
4

Return to GitHub Desktop

The file is automatically marked as resolved
Most code editors (VS Code, Sublime Text, etc.) provide syntax highlighting and quick actions for merge conflicts.

Conflict Resolution Implementation

Manual Conflict Resolution

GitHub Desktop supports choosing “ours” or “theirs” for entire files:
// From app/src/models/manual-conflict-resolution.ts
export enum ManualConflictResolution {
  ours = 'ours',   // Keep current branch's version
  theirs = 'theirs' // Use incoming branch's version  
}

// Applied during merge commit creation
export async function createMergeCommit(
  repository: Repository,
  files: ReadonlyArray<WorkingDirectoryFileChange>,
  manualResolutions: ReadonlyMap<string, ManualConflictResolution>
): Promise<string> {
  // Apply manual conflict resolutions
  for (const [path, resolution] of manualResolutions) {
    const file = files.find(f => f.path === path)
    if (file !== undefined) {
      await stageManualConflictResolution(repository, file, resolution)
    }
  }
  
  await stageFiles(repository, otherFiles)
  await git(['commit', '--no-edit', '--cleanup=strip'])
}

Modify/Delete Conflict Resolution

When one branch modifies and another deletes:
// Conflict is indicated by GitError.ConflictModifyDeletedInBranch
if (result.gitError === GitError.ConflictModifyDeletedInBranch) {
  // User chooses:
  // 1. Keep modified version (stage the file)
  // 2. Accept deletion (remove the file)
}

Completing Merge After Conflicts

Merge Commit Message

GitHub Desktop automatically generates merge commit messages:
Merge branch 'feature-branch' into main

# Conflicts:
#   src/file1.ts
#   src/file2.ts
The message includes:
  • Source and target branches
  • List of conflicted files (as comments)
  • Can be edited before committing

Cleanup Process

// From app/src/lib/git/commit.ts
const result = await git(
  [
    'commit',
    '--no-edit',        // Use existing merge message
    '--cleanup=strip',  // Remove comment lines starting with #
  ],
  repository.path,
  'createMergeCommit'
)
GitHub Desktop uses --cleanup=strip to remove Git’s default comment lines from the merge commit message.

Aborting Merge/Rebase

If you want to cancel the operation:

Abort Merge

1

Click Abort

Click Abort merge in the Changes tab
2

Confirm

Confirm you want to cancel the merge
3

Return to Previous State

Repository returns to state before merge started

Abort Rebase

1

Click Abort

Click Abort rebase in the banner
2

Confirm

If you’ve resolved conflicts, confirm you want to discard them
3

Restore Original State

Branch returns to state before rebase
Aborting discards all conflict resolutions. There’s no way to recover the work you’ve done resolving conflicts.

Preventing Merge Conflicts

Best Practices

Communicate

Coordinate with team members about who’s working on which files

Pull Frequently

Regularly update your branch from the base branch

Small Changes

Make smaller, more focused commits that are easier to merge

Merge Often

Integrate changes frequently instead of letting branches diverge

Proactive Strategies

  1. Update from Main Regularly
    Branch > Update from main
    
    Keep your feature branch synchronized with the base branch
  2. Create Focused Branches
    • Work on one feature or fix per branch
    • Avoid modifying too many files
    • Keep branches short-lived
  3. Use Pull Requests
    • Review changes before merging
    • Get early feedback on potential conflicts
    • Use draft PRs for work in progress
  4. Coordinate File Ownership
    • Establish file ownership conventions
    • Communicate before modifying shared files
    • Use code review to catch potential conflicts early

Advanced Conflict Scenarios

Multiple Sequential Conflicts (Rebase)

During a rebase, you may encounter conflicts in multiple commits:
1

Resolve First Conflict

Resolve conflicts in the current commit
2

Continue Rebase

Click Continue rebase
3

Handle Next Conflict

If another commit conflicts, repeat the process
4

Complete Rebase

Continue until all commits are applied

Submodule Conflicts

When submodules conflict:
  1. GitHub Desktop shows the submodule as conflicted
  2. You must resolve by choosing which submodule commit to use
  3. Or update the submodule to a new commit that works for both branches

.gitattributes and Line Endings

Line ending conflicts can be prevented:
.gitattributes
* text=auto
*.ts text eol=lf
*.md text eol=lf
*.sh text eol=lf
*.bat text eol=crlf
Configuring .gitattributes ensures consistent line endings across platforms.

Conflict Resolution Tools

External Merge Tools

Configure external tools for complex conflicts: Popular Merge Tools:
  • Visual Studio Code
  • Beyond Compare
  • KDiff3
  • P4Merge
  • Meld
Configure in Git:
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
Then open from GitHub Desktop:
  1. Right-click conflicted file
  2. Select Open in external merge tool

Viewing Conflict History

After resolving conflicts:
  1. Switch to History tab
  2. Find the merge commit
  3. Review what conflicts existed
  4. See how they were resolved

Troubleshooting

If the merge won’t complete:
  • Unresolved files: Check all conflicted files are resolved
  • Unstaged changes: Ensure resolved files are staged
  • Git state: Repository might be in an inconsistent state
  • Try: Abort and restart the merge
If you see <<<<<<< in your code after “resolving”:
  • You didn’t remove all conflict markers
  • Search for <<<<<<<, =======, >>>>>>> in the file
  • Remove markers and save
  • Stage the file again
If you accidentally aborted:
  • Resolution work is lost (not recoverable)
  • Must restart and resolve again
  • Consider using git reflog in terminal if you committed mid-resolution
For images, PDFs, or other binary files:
  • Cannot merge binary files automatically
  • Choose one version or the other
  • Or replace with a newly created file
  • Consider using Git LFS for large binary files
If facing overwhelming conflicts:
  • Abort the merge/rebase
  • Break changes into smaller chunks
  • Update from base branch more frequently
  • Consider alternative merge strategies

Tips for Resolving Complex Conflicts

Take your time: Complex conflicts require careful thought. Don’t rush—understand what both sides are trying to accomplish.
  1. Understand Both Changes: Read the code from both branches carefully
  2. Test After Resolution: Always test that the merged code works
  3. Consult Original Authors: Ask teammates if you’re unsure about their changes
  4. Use Git History: Check git log to understand why changes were made
  5. Resolve Incrementally: For multiple conflicts, resolve one at a time
  6. Document Decisions: Add comments explaining non-obvious resolutions

Build docs developers (and LLMs) love