Understanding merge conflicts during pull requests

Sara Verdi
Sara Verdi
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


Merge conflicts in pull requests occur when Git cannot reconcile differences between branches during a merge. Understanding and resolving these conflicts is essential for smooth collaboration in software development. This guide covers the causes of merge conflicts, how to handle them in GitHub, and how Graphite's Merge Queue can help reduce conflicts altogether.

Merge conflicts happen when changes in two branches overlap or contradict each other, and Git cannot automatically decide which changes to keep. These conflicts often arise when:

  • Two developers modify the same lines in a file.
  • One branch deletes a file that another branch modifies.
  • Changes in one branch alter file structures or relationships in ways that conflict with another branch.

For example, if branch-A and branch-B both modify line 15 of file.txt, Git flags this as a conflict because it doesn’t know whether to keep the changes from branch-A, branch-B, or combine them.

When conflicts occur in a pull request, GitHub displays warnings like:

“This branch has conflicts that must be resolved.”

Conflicting files will be listed in the pull request details, and you can inspect the changes to resolve them manually.

In GitHub, the conflicting lines will look like this:

Terminal
<<<<<<< HEAD
// Changes from the main branch
console.log("Hello from main!");
=======
// Changes from the feature branch
console.log("Hello from branch-A!");
>>>>>>> branch-A

The <<<<<<<, =======, and >>>>>>> markers denote areas where the conflict occurs. Resolving the conflict involves editing the file to decide which changes to keep or how to combine them.

  1. Fetch the latest changes: Pull the latest version of the main branch to ensure you’re working with up-to-date code:

    Terminal
    git fetch origin main
    git checkout main
    git pull
  2. Merge your branch into main: Attempt to merge your branch. Git will alert you to conflicts:

    Terminal
    git merge branch-A
  3. Edit conflicting files: Open the conflicting files in your text editor or IDE, and modify them to resolve conflicts. Remove conflict markers (<<<<<<<, =======, and >>>>>>>) after deciding how to merge the changes.

  4. Add the resolved files: Mark files as resolved by adding them to the staging area:

    Terminal
    git add <file_name>
  5. Continue the merge process: Complete the merge with:

    Terminal
    git commit
  6. Push the changes: Push the resolved changes back to the repository:

    Terminal
    git push origin main

The Graphite Merge Queue simplifies the process of managing pull requests and minimizes merge conflicts. It does this by automating rebases and maintaining a “green trunk”—a state where the main branch remains functional.

  • Stack-aware merging: It processes stacked pull requests in parallel, ensuring that dependent changes are merged in the correct order.
  • Automated rebases: It automatically rebases branches onto the latest trunk version, reducing the risk of conflicts caused by outdated branches.
  • Continuous integration (CI) optimization: By validating stacks together, it avoids unnecessary CI reruns for already-tested changes.

For example, when a pull request enters the queue and conflicts arise, the merge queue comments directly on the PR in GitHub to notify you. You can then resolve the conflict and re-add the PR to the queue for reprocessing. Graphite’s fast-forward merge strategy eliminates redundant CI validations, speeding up the overall merge process.

  1. Sync your branch regularly: Regularly rebase your branch onto main to catch conflicts early:

    Terminal
    git rebase main
  2. Communicate with team members: Keep everyone informed about significant changes to shared files.

  3. Use smaller pull requests: Small, incremental changes reduce the risk of conflicts and make them easier to resolve.

  4. Leverage a merge queue: Tools like Graphite's Merge Queue automate conflict management, especially for complex stacks.

Understanding and resolving merge conflicts is a critical skill for developers. By combining best practices with tools like Graphite's Merge Queue, you can minimize disruptions and keep your development workflow efficient.

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2