What Causes Merge Conflicts and How to Resolve Them

A merge conflict occurs when Git cannot automatically combine changes from two branches because both branches have modified the same lines of the same file differently or when one branch deletes a file that another branch modifies.

Git pauses the merge and asks you to manually resolve the conflicting changes before the merge can be completed.


Advertisement

Interview Answer

"A merge conflict occurs when Git cannot automatically merge changes because two branches modify the same lines of a file differently or when one branch deletes a file that another branch modifies. I resolve conflicts by identifying the conflicting files using git status, editing the files to remove the conflict markers, staging the resolved files, and completing the merge with a commit."


Common Causes of Merge Conflicts

Merge conflicts typically occur when:

  • Two developers modify the same lines of the same file.
  • One branch deletes a file while another branch edits it.
  • Long-lived branches diverge significantly.
  • Developers do not pull the latest changes before merging.

Merge Conflict Workflow

Feature Branch
      │
      ├─────────────┐
      │             │
      ▼             ▼
Modify File     Modify Same File
      │             │
      └──────┬──────┘
             ▼
        Git Merge
             │
             ▼
      Merge Conflict
             │
             ▼
 Manual Conflict Resolution
             │
             ▼
      Commit Merge

Conflict Markers

When a conflict occurs, Git inserts conflict markers into the file.

<<<<<<< HEAD
Current branch changes
=======
Incoming branch changes
>>>>>>> feature-branch

Steps to Resolve a Merge Conflict

Step 1: Check Conflicting Files

git status

Step 2: Edit the File

  • Remove the conflict markers.
  • Keep the correct code.
  • Save the file.

Step 3: Stage the Resolved File

git add <resolved-file>

Step 4: Complete the Merge

git commit

Real-Time Example

While merging a feature branch into the development branch, another developer had modified the same method. Git reported a merge conflict. I reviewed both implementations, merged the required logic, removed the conflict markers, staged the resolved file using git add, and completed the merge with a commit.


Best Practices to Avoid Merge Conflicts

  • Create small feature branches.
  • Pull the latest changes frequently.
  • Merge regularly.
  • Keep commits small and focused.
  • Avoid working on the same files simultaneously whenever possible.

Detached HEAD State

A Detached HEAD state occurs when Git's HEAD points directly to a specific commit instead of pointing to a branch.

In this state, any commits you create are not attached to any branch and may become inaccessible if you switch branches without saving them.


Interview Answer

"A detached HEAD state occurs when HEAD points directly to a commit instead of a branch. If I need to preserve my work, I create a new branch from the current commit. Otherwise, I simply switch back to an existing branch."


How Does Detached HEAD Happen?

Examples:

git checkout <commit-hash>

or

git checkout tags/<tag-name>

Detached HEAD Workflow

Branch
   │
   ▼
Commit A
   │
   ▼
Commit B
   │
   ▼
Commit C
   │
   ▼
Checkout Commit B
   │
   ▼
Detached HEAD

How to Fix Detached HEAD

Option 1: Create a New Branch

git checkout -b <new-branch-name>

This preserves your work.


Option 2: Return to an Existing Branch

git checkout <branch-name>

Real-Time Example

If I accidentally enter a detached HEAD state while investigating an old commit and decide to keep my changes, I immediately create a new branch from that commit. Otherwise, I simply switch back to the appropriate working branch.


Best Practices

  • Avoid committing work while in a detached HEAD state unless you intend to create a branch.
  • Create a branch immediately if valuable work has been done.
  • Verify your current branch using:
git branch

Recovering a Deleted Branch or File

Git maintains a history of commits, making it possible to recover deleted branches and files in most situations.

Recovery depends on whether the branch or file had been committed before deletion.


Recovering a Deleted Branch

Step 1: View Reference Log

git reflog

Step 2: Recreate the Branch

git checkout -b <branch-name> <commit-hash>

Branch Recovery Workflow

Deleted Branch
       │
       ▼
git reflog
       │
       ▼
Locate Commit
       │
       ▼
Create Branch
       │
       ▼
Branch Restored

Recovering a Deleted File

File Deleted Before Commit

git checkout -- <file-name>
# newer equivalent (Git 2.23+):
git restore <file-name>

File Deleted After Commit

git checkout <commit-hash> -- <file-name>

Real-Time Example

If a teammate accidentally deletes a branch, I first use git reflog to locate the commit where the branch previously pointed. I then recreate the branch using git checkout -b. For deleted files, I restore them from the appropriate commit without affecting the rest of the project.


Best Practices

  • Check git status before attempting recovery.
  • Use git reflog to identify recent branch history.
  • Avoid deleting branches until they have been merged successfully.
  • Verify restored files before committing.

Force Push: What Happens and When Is It Safe?

A force push replaces the remote branch history with your local branch history.

Command:

git push --force

or

git push -f

Since force push rewrites Git history, it should be used carefully.


Interview Answer

"Force push overwrites the remote branch with my local branch history. I use it only on my private feature branches. For shared branches such as main or develop, I avoid force push and prefer safer approaches like git revert or git push --force-with-lease."


When Is Force Push Safe?

Force push is generally safe when:

  • Working on a private feature branch.
  • No other developers are using the branch.
  • The team has agreed to rewrite history.

When Should You Avoid Force Push?

Avoid force pushing on:

  • main
  • master
  • develop
  • Shared release branches

Force pushing to shared branches may overwrite teammates' commits and cause data loss.


Safer Alternative

git push --force-with-lease

Unlike --force, this command refuses to overwrite the remote branch if new commits have been pushed by someone else.


Force Push Workflow

Local Branch
      │
      ▼
Force Push
      │
      ▼
Remote Branch History
      │
      ▼
History Rewritten

Real-Time Example

During feature development, I occasionally rewrite commit history using interactive rebase. Before merging, I use git push --force-with-lease on my own feature branch to safely update the remote without risking other developers' work.


Recovering from a Bad Merge

Sometimes a merge introduces compilation errors, broken functionality, or incorrect code.

Git provides several ways to recover, depending on whether the merge has already been shared.


Interview Answer

"If the merge is local and hasn't been pushed, I use git reflog to identify the previous commit and git reset --hard to restore the branch. If the merge has already been pushed to a shared repository, I use git revert to safely undo the merge without rewriting Git history."


Local Merge Recovery

Step 1: Find Previous Commit

git reflog

Step 2: Reset

git reset --hard <commit-hash>

Shared Repository Recovery

Instead of resetting shared history, use:

git revert -m 1 <merge-commit-hash>

This creates a new commit that reverses the merge while preserving project history.


Recovery Workflow

Bad Merge
     │
     ▼
Already Pushed?
     │
 ┌───┴────┐
 │        │
No       Yes
 │        │
 ▼        ▼
git reset   git revert

Best Practices

  • Use git reset --hard only for local branches.
  • Use git revert for shared repositories.
  • Verify the previous commit using git reflog.
  • Communicate with teammates before undoing shared merges.

Try It: Two Recoveries, Real Output

1. Reverting a merge needs -m 1

A merge commit has two parents, so Git needs to know which side to keep. Without -m, the revert fails:

$ git revert <merge-id>
error: commit <merge-id> is a merge but no -m option was given.
fatal: revert failed

$ git revert -m 1 <merge-id>
[main <id>] Revert "Merge branch 'feature/cart'"

-m 1 means "keep the first parent" — the branch you were on when you merged (usually main) — and undo what the feature branch brought in. After the revert, the feature's cart.txt was gone and main's own hotfix stayed. One catch: if you later want to merge the same branch again, Git thinks those commits are already merged; you'll need to revert the revert first.

2. Bringing back a deleted branch with reflog

$ git branch -D experiment
Deleted branch experiment (was <id>).

$ git reflog | head -4
<id> HEAD@{0}: checkout: moving from experiment to main
<id> HEAD@{1}: commit: Experiment work
<id> HEAD@{2}: checkout: moving from main to experiment
...

$ git branch experiment <id of "Experiment work">
$ git log --oneline -1 experiment
<id> Experiment work

Deleting a branch only deletes the label; the commits stay until Git's garbage collection removes unreachable ones (by default after about 90 days for reflog entries, 30 for unreachable ones). The reflog is local, though — it can't recover commits that only ever existed on someone else's machine.

Automation failures after a merge are often not Git problems at all but broken locators or waits — look up any Selenium exception's usual causes and fixes in the Selenium Exception Lookup. More Git recovery: Rebase, Cherry-Pick & Bisect.

From Real Projects

In my automation roles I maintained test scripts that several people reviewed and extended — POM classes, the business library and data files all changing at once. That's exactly the situation version control is built for: every change reviewed, traceable and easy to undo. On Canolog, the many forms and screens across sales, inventory, finance and service are where keeping page details in POM classes and reusable steps in a business library paid off. Read the error message carefully — Git usually tells you exactly what to do next.


📚 Official documentation: Git documentation

Frequently Asked Questions (FAQs)

1. What causes merge conflicts and how do you resolve them?

Merge conflicts occur when Git cannot automatically merge changes because multiple branches modify the same lines of a file differently or when one branch deletes a file that another branch modifies.

To resolve them:

  1. Run:
git status
  1. Open the conflicting files.
  2. Remove the conflict markers.
  3. Save the correct code.
  4. Stage the resolved files.
git add <file-name>
  1. Complete the merge.
git commit

2. What is a Detached HEAD state and how do you fix it?

A Detached HEAD occurs when HEAD points directly to a commit instead of a branch.

To fix it:

Create a new branch:

git checkout -b <new-branch-name>

or return to an existing branch:

git checkout <branch-name>

Creating a new branch preserves any work performed while in the detached HEAD state.


3. How do you recover a deleted branch?

Use the Git reference log:

git reflog

Locate the commit and recreate the branch:

git checkout -b <branch-name> <commit-hash>

4. How do you recover a deleted file?

If the file was deleted before committing:

git checkout -- <file-name>

If the deletion was committed:

git checkout <commit-hash> -- <file-name>

5. What happens if you force push, and when is it safe?

A force push replaces the remote branch history with your local history.

It is generally safe only when:

  • Working on your own feature branch.
  • No one else is using that branch.
  • The team agrees to rewrite history.

Avoid force pushing to shared branches like main, master, or develop, as it may overwrite teammates' commits.


6. How do you recover from a bad merge?

For a local merge that has not been pushed:

git reflog
git reset --hard <commit-hash>

For a merge that has already been pushed:

git revert -m 1 <merge-commit-hash>

git revert safely undoes the merge by creating a new commit without rewriting Git history, making it the preferred approach for shared repositories.