How to Resolve Git Merge Conflicts: A Step-by-Step Fix

How do you resolve a git merge conflict?
A git merge conflict happens when two branches change the same lines and Git cannot decide which version wins. To resolve it, run git status to find the conflicted files, edit each one to keep the right content, remove the markers, stage the files with git add, and finish the merge. Abort if you want to start over.
Do not panic. A conflict does not mean Git is broken. In other words, Git is telling you that a human decision is needed here. Your work is safe in most cases, because you can still back out before any commit.
In this guide we follow the diagnostic order we see in the field. We start with the most common situation, then move to the rarer ones. Also, the commands are short, and we explain why each step matters.
What is the quick fix for a git merge conflict in 7 steps?
First, follow a calm sequence. The list below works for merge, pull and rebase alike. The small rebase difference comes later in this guide.
- Run
git statusand note the files listed under "Unmerged paths". - Open the first file in your editor and look for the conflict markers.
- In each conflict block, decide which content should stay. Sometimes one side is right, and sometimes a mix of both is right.
- Then delete the marker lines completely. Only the final code should remain in the file.
- Save the file, then run
git add file-nameto mark it as resolved. - When all files are done, finally run your tests or your build. Resolving a conflict does not guarantee working code, so verify.
- For a merge, run
git commitorgit merge --continue. For a rebase, rungit rebase --continue.
Whenever you get stuck, simply run git status again. That way, the output usually tells you the next step.
Why does a git merge conflict happen?
A conflict starts when Git cannot combine two changes automatically. Also, Git works line by line. If two people edit different files, or distant parts of the same file, nothing goes wrong. However, if both edit the same lines, Git cannot know which one is correct.
The most common causes are these:
- Two developers changed the same function or configuration line.
- Next, a long-lived branch drifted far away from the main branch.
- One person deleted or renamed a file while another edited it.
- An automatic formatter changed the indentation of a whole file.
- Commands such as
git stash pop,git cherry-pickorgit revertreplayed old changes on top of new code.
For example, two people can set the same price constant to different values. Git cannot keep both, because there is one line and two candidates. So it stops and asks you.
One point matters here: a conflict is not an error. It is a normal workflow event. Also, as the team grows, you will see it more often. The real goal is not zero conflicts. The goal is to keep them small and easy.
What do the git merge conflict markers mean?
Git writes the conflicting region into the file itself. First, three marker lines show you what happened. The block below is a conceptual example:
<<<<<<< HEAD
price = 100
=======
price = 120
>>>>>>> feature-branchHere is how to read it:
- Everything between the first marker and the
=======line is the content of your current branch (HEAD). - Everything between
=======and the last marker is the content of the branch you are bringing in. - The last marker line carries the branch or commit name, so you know where that content came from.
However, these three lines are not part of your file. If you leave them in, the build will fail, because the syntax breaks. Even worse, the markers could reach production. So always remove them.
If you want more context, set git config merge.conflictStyle diff3. Then you also see the common ancestor content. As a result, the question "what did each side change?" becomes easier to answer. The Git merge documentation explains the details.
How do you see which files have a git merge conflict?
Start by seeing the scope. Knowing whether the job is small or large keeps you calm. Then the git status output shows two groups: files that merged automatically and files under "Unmerged paths".
To list only the conflicted file names, this command helps:
git diff --name-only --diff-filter=UThe status labels matter too:
- "both modified": both sides changed the file. This is the most common case, so check it first.
- "deleted by us" or "deleted by them": one side deleted the file while the other edited it.
- "both added": both sides added a different file with the same name.
However, in a delete conflict you will not see marker lines. The decision is simple but must be deliberate: keep the file or remove it. To keep it, use git add. To remove it, use git rm.
Also note any other pending changes in your working tree. Also, that note helps if you decide to abort later. Otherwise you may confuse what belongs to you after the abort.
How do you choose the right content in a conflicted file?
Each conflict block gives you three options: keep your side, keep the other side, or combine both. However, the right choice requires reading the code. Do not automate this step.
In the field we ask these questions in order. The reason is that the right answer often lives in intent, not in syntax:
- Do both changes serve the same goal, or do they cover two different needs?
- Which side answers a newer requirement?
- If both are needed, does the order or naming collide?
- Do you need to talk to the author?
Still, the last question is the one people skip most. If you do not know why the other side changed that line, do not guess. Check the commit message instead. git log --merge -p file-name shows the commits that touch the conflict.
Example scenario: one developer renamed a function, and another added a new condition inside the same function. The correct result combines both, so the new name and the new condition stay together. Picking only one side, however, would silently drop a feature.
How do you finish the resolution with git add and commit?
After you edit and save the file, you must tell Git that the file is ready. git add does this. First, it stages the file and clears the conflict state.
Once you do this for every file, run git status again. If you see a message like "all conflicts fixed", you are close to the end. Then:
git add file-name
git commit
# or: git merge --continueThe commit message is usually prefilled. For example, it may list the conflicted files. You can keep it, or add one sentence about why you resolved it that way. As a result, the team will not have to ask later why a line looks this way.
However, there is one trap. Typing git add . is easy, but it also stages a file that still contains markers. First run git diff --check. The command warns you about leftover marker lines. So you stop a bad commit before it happens.
How do you resolve a git merge conflict during a rebase?
Rebase replays your commits one by one on top of a new base. Therefore a conflict can appear for each commit separately. The logic stays the same: resolve the file, then run git add. However, the difference is that you do not write a commit at the end.
The right command during a rebase is:
git add file-name
git rebase --continueThis moves on to the next commit. Then, if another conflict appears, repeat the process. When the last commit applies, the rebase ends. If a commit becomes completely unnecessary, git rebase --skip drops it. Still, use that only when you are sure.
Also, "ours" and "theirs" swap meaning during a rebase. The reason is that Git moves your own commits onto another branch one at a time. In practice, "ours" points to the base branch, and "theirs" points to your commits being replayed. The Git rebase documentation covers this.
If you expect many conflicts, a single merge may cause fewer surprises than a rebase. The comparison table below summarizes the difference.
How do you abort a merge or rebase if you want out?
If the resolution gets messy, you can go back. Before the commit, for instance, you can cancel the whole operation. The right command depends on what you started:
- For a merge, run
git merge --abort. Git tries to return to the state before the merge. - For a rebase, run
git rebase --abort. The branch returns to how it was before the rebase. - For a cherry-pick, run
git cherry-pick --abort.
However, one warning is important. If you had uncommitted changes before the merge started, the abort may not restore them in every case. The Git documentation says so clearly. Therefore keep your working tree clean before a merge, or commit or stash first.
After an abort your branch returns, but the conflict itself does not disappear. Also, if you try the same merge again, you will see the same conflict. Instead, it can help to pull the main branch into your branch first and resolve the conflict in smaller pieces.
How does an editor merge tool help with a git merge conflict?
You do not have to delete markers by hand. For example, most modern editors color the conflict blocks. They also give you clickable options to accept the current change, the incoming change or both.
Visual Studio Code is one of them. See the VS Code source control documentation for details. For extensions and settings, our VS Code vs Visual Studio comparison can help.
Git also has its own tool: git mergetool. It opens an external merge program of your choice. You define your preferred tool with the merge.tool setting. The tool often leaves backup files with an .orig extension. Make sure you do not commit them.
However, visual tools carry one risk. One click on "accept this side" is very easy. That ease can turn into carelessness. Read both sides before you accept each conflict. Also remember to run the tests afterward.
Is it safe to take one side with --ours or --theirs?
Sometimes only one side of a file is right. A build output that you will regenerate from source is an example. In that case you can pick a side with one command:
git checkout --ours -- file-name
git checkout --theirs -- file-nameThe first brings your current branch version. The second brings the incoming version. Afterward, do not forget git add. In a merge, "ours" is your branch. In a rebase, it is the opposite.
Here is the risk, though. When you take a whole file, you lose every change from the other side in that file, including the parts that did not conflict. In other words, a one-line conflict can erase hundreds of lines of work. So use this path deliberately, for one file at a time.
Two similar names are often confused:
git merge -X ourskeeps your side only in the conflicting hunks. Non-conflicting changes still merge.git merge -s oursignores all changes from the other branch, but records the branch as merged in history.
The second one is very powerful and often not what you want. So if you are not sure, do not use it.
How do you resolve a lock file conflict such as package-lock?
Lock files such as package-lock.json or yarn.lock come from tools. Therefore merging their lines by hand is error-prone. The dependency tree is interconnected, so one wrong line breaks it.
The general approach is this:
- First, resolve the conflict in
package.jsonwith human judgment. Decide which packages both sides want. - For the lock file, take the version from one side, for example
git checkout --theirs -- package-lock.json. - Then run
npm install. The tool brings the lock file in line with the currentpackage.json. - Stage the new lock file with
git addand run your tests.
The npm package-lock documentation is a good reference. If you hit a dependency tree error while doing this, see our guide on the npm ERESOLVE error.
An important rule: deleting the lock file and regenerating it from scratch is a last resort. It may shift every version your team relies on.
How do you handle a git merge conflict in binary files?
Binary files such as images, PDFs, design files or compressed packages cannot merge line by line. Also, Git does not write markers into them. It only says that both sides changed the file and waits for you to pick one.
The fix is simple but needs care:
- Decide which version is correct. If needed, open both versions and compare them manually.
- Bring the right side with
git checkout --ours -- fileor--theirs. - Mark the file with
git add.
If both sides made different, needed changes, Git cannot combine them. In that case you must merge the changes by hand in the proper tool, such as a design program. Therefore an ownership rule for binary files helps a lot: only one person edits at a time.
Also, storing large binary files in the repository causes other problems. If possible, consider a separate storage setup for them.
What is the difference between merge and rebase conflicts?
Both methods produce the same markers, but the timing differs. The difference lies in when and how often the conflict appears. The table below gives a summary.
| Criterion | Merge | Rebase |
|---|---|---|
| Number of conflicts | Usually once, for the whole branch | Can appear for each commit separately |
| Command after resolving | git commit or git merge --continue | git rebase --continue |
| Aborting | git merge --abort | git rebase --abort |
| Meaning of "ours" | The branch you are on | The base branch you are replaying onto |
| Meaning of "theirs" | The branch you bring in | Your own commits being replayed |
| Effect on history | Adds a merge commit | Rewrites commits |
| Risk on a shared branch | Low | High, because history changes |
In short, merge is more predictable on shared branches. On your own private branch, however, rebase leaves a cleaner history. Your team rules should decide which one to use.
How do you tell what each cause, symptom and fix looks like?
Recognizing the type of conflict early saves time. The table below pairs the most common situations with their causes and fixes. The order runs from most likely to least likely.
| Symptom | Likely cause | Fix |
|---|---|---|
| Marker lines in the file, status "both modified" | Both sides changed the same line | Choose the content, remove markers, run git add |
| Status "deleted by us" or "deleted by them" | One side deleted, the other edited | Decide with git add to keep or git rm to remove |
| Status "both added" | Two different files with the same name | Compare contents and rename one |
| Many markers in a lock file | Dependencies updated differently on two branches | Resolve package.json, regenerate the lock file with the tool |
| Binary file warning | An image or package changed on both branches | Take the right version with ours or theirs |
| Rebase stops at every commit | Many commits touched the same area | Resolve one by one, or use a single merge |
This table is a starting point. Of course, because every project brings its own details. Still, the right order is to read the marker first, identify the type second, and choose the command last.
How do you verify that your resolution is correct?
Resolving a conflict and resolving it correctly are different things. However, even when Git considers the file merged, logic errors can remain. So build a short verification routine before the commit.
- Search for forgotten markers with
git diff --check. - Next, build or start the project. A syntax error may have survived the conflict.
- Also, run the existing tests, especially those that touch the conflicted files.
- Review the final result with
git diff --staged. - If possible, ask the other author for a quick look.
A debugging habit helps here. If something breaks, go step by step with the methods in our debugging techniques guide.
You can also undo a finished merge after the commit. However, on a shared history, tell your team before you do it.
How can you reduce git merge conflict frequency from the start?
First, you cannot reach zero conflicts. You can, however, reduce their frequency and size. These habits work in the field:
- Merge small and merge often. A branch that lives for weeks is a pile of conflicts.
- Also, update your branch from the main branch regularly. You resolve conflicts while they are small.
- Then make small commits. One commit should serve one purpose.
- Also, put formatting changes in a separate commit. Then meaning changes and indentation noise do not mix.
- Define code ownership. Make it clear who owns which module.
- If you will work in the same file at the same time, talk first.
Consider git rerere as well. If you resolve the same conflict again and again, which is common on long-lived branches, Git can remember your earlier resolution and apply it. You turn it on with the rerere.enabled setting.
If you are new to Git commands, our Git and GitHub essential commands guide is a good start. For collaboration rules, see our guide to contributing on GitHub.
What should you do about a git merge conflict during git pull?
git pull combines two jobs. First it downloads remote changes. Then it merges them into your current branch. So a conflict during pull is an ordinary merge conflict, and you follow the same steps.
Depending on your settings, pull can also rebase instead of merge. So read the output. If you see "rebase in progress", you must run git rebase --continue after the fix. Otherwise you mix up the process with the wrong command.
If a pull shows a warning like "local changes would be overwritten", that is a different case. In this case, Git stopped before it even reached a conflict. First commit your changes or stash them for now, then try again.
There is also a safe habit. Before an important pull, run git fetch and look at git log to see what arrives. So you can predict the conflict.
How do stash, cherry-pick and revert conflicts differ?
Conflicts are not limited to merge and rebase. Any command that carries changes from history can produce one. For instance, the markers look the same. What differs is how you finish.
- Stash: if
git stash popconflicts, Git keeps the saved stash. After you finish, you remove the stash yourself. - Cherry-pick: after the fix, run
git cherry-pick --continue. To quit, use--abort. - Revert: the same logic applies with
git revert --continueand--abort.
The git status output often tells you which operation is unfinished and what comes next. So reading the output is safer than memorizing commands.
Example scenario: you cherry-picked a bug fix onto a release branch. That file looks different on the release branch, so a conflict appeared. The right approach is to keep the purpose of the fix without breaking the existing release code.
How do you see the three versions of a conflicted file?
During a conflict, Git actually stores three versions: the common ancestor, your version and the other side's version. The markers you see are a mix of them. However, sometimes the mix becomes unreadable.
In that case, look at each version separately. git show :1:file-name shows the ancestor, :2: shows your side, and :3: shows the other side. The Git documentation calls these index stages. This way you can read all three side by side.
So you can answer the question "what was the original, and who changed what?" clearly. In large files and long functions, this approach saves you from wasting time.
If you cannot reach a result, drop the attempt with git merge --abort. Update your branch first, then merge again in smaller pieces.
Which small habits make conflict resolution easier?
Technical commands matter, but so does your working routine. The habits below raise both speed and confidence. In addition, none of them needs extra tools.
- Open a backup branch before you start:
git branch backup-branchkeeps the current point. If things go wrong, you have somewhere to return. - Run
git addright after you finish a file. Then you never forget which file is ready. - Resolve files one at a time. Keeping three files open at once raises the chance of mistakes.
- Do not skip a line you do not understand. Read the commit message first and ask the author if needed.
- Read the diff once more when you finish. Because a missed marker or the wrong side shows up here.
These steps look slow, but they pay off. Still, they save time overall. A wrong resolution comes back days later as a surprise bug, and finding its cause is much more expensive.
Which mistakes make a git merge conflict worse?
Because habits matter as much as technical knowledge, watch for them. These are the common mistakes we see:
- Forgetting to remove the markers and committing anyway.
- Choosing one side everywhere ("always mine") and deleting the other person's work.
- Sending the resolution to the branch without testing it.
- Rebasing a shared branch without warning and rewriting history.
- Keeping a large feature on one branch for weeks.
- Running an automatic formatter across the whole project at once.
Most of these are process problems, not tool problems. Short-lived branches, clear ownership and a required test step solve most of it.
Example scenario: a team of three merges all branches on the same day at the end of the month. Every month they live through a heavy conflict day. When they switch to weekly merges, the conflicts shrink and spread across the week. This is a conceptual example, not a measurement.
When should you ask for help with a git merge conflict?
Most conflicts yield to the steps in this guide. However, some cases need deeper analysis. For example, a conflict on a critical production branch, or a tangled history, calls for care.
First stop and note the current state. Save the git status output and the command you ran. If needed, create a backup branch. Then decide.
If your repository structure, branching strategy or release process keeps producing conflicts, the problem is in the process, not the code. In that case you need to look at team workflow and software infrastructure together. We handle such workflow problems within our custom software development service. To get a quote that fits your needs, request one from the service page.
If you are dealing with neighboring errors such as SSH access or dependency problems, see our SSH publickey error guide.



