All posts
·13 min read· git· merge-conflicts· errors· index· troubleshooting

You need to resolve your current index first: the Git fix

Git says 'you need to resolve your current index first', 'needs merge', or 'you have not concluded your merge'. All of them mean one thing: an unmerged index. Here is the safe fix.

You started a merge. It hit a conflict. You decided to deal with it later, so you tried to switch branches. Git refused:

error: you need to resolve your current index first
config.js: needs merge

So you tried to commit instead. Git refused again, with a different message. You tried git pull. Refused, different message again. Every command you know gives you a new error, and none of them tell you what to actually do.

Here is the good news. Those are not four problems. They are one problem wearing four masks. Your repository is in a single, specific state, and once you can name that state, every one of those errors becomes obvious and the fix takes about ten seconds.

This post names the state, shows you how to see it directly, and gives you two safe ways out. Every command and every error message here was reproduced against Git and checked against the official documentation.

The one state behind all of it

When Git merges two versions of a file and cannot decide the result on its own, it does not give up and it does not pick for you. It records all three versions of that file in the index and waits for you.

The index is the staging area — the list of files that will go into your next commit. Normally each file has exactly one entry. During a conflict, a conflicted file has three entries instead, called stages:

StageWhat it holds
1The common ancestor — the version both sides started from
2"Ours" — the version on the branch you are currently on
3"Theirs" — the version from the branch you are merging in

A file with more than one stage is called unmerged. That is the state. Every error in this post is Git saying, in different words, "a file in your index is unmerged, and I refuse to do this while that is true."

You can see the stages yourself. This is the single most useful command in this whole post:

git ls-files -u
100644 df967b96a579e45a18b8251732d16804b2e56a55 1	config.js
100644 ba2906d0666cf726c7eaadd2cd3db615dedfdf3a 2	config.js
100644 a7453f07505c42ea8d6fdda75fa91710c81c53d6 3	config.js

Three lines, one file, stages 1, 2 and 3. The -u flag means "show unmerged files only", per the git-ls-files docs. If this command prints nothing, your index is clean and none of the errors below apply to you.

You can read any stage directly, which is useful when you want to see what the other side actually wrote:

git show :1:config.js    # the common ancestor
git show :2:config.js    # ours
git show :3:config.js    # theirs

Git also has a shorter summary. git status --short prints a two-letter code for each file:

UU config.js

UU means both sides modified the file. AA means both sides added a file that did not exist before — that is the state people search for as "git both added". Both are unmerged. Both are the same underlying problem.

The error messages, decoded

Here is the part that saves time. Each message below is Git refusing the same thing for the same reason. The command differs, so the wording differs.

What you ranWhat Git says
git checkout <branch>error: you need to resolve your current index first then config.js: needs merge
git commiterror: Committing is not possible because you have unmerged files.
git merge <branch>error: Merging is not possible because you have unmerged files.
git pullerror: Pulling is not possible because you have unmerged files.
git cherry-pick <commit>error: Cherry-picking is not possible because you have unmerged files.
git rebase <branch>config.js: needs merge

That family of four is not a coincidence. In Git's own source they are generated from one place, in advice.c, as four variations of the same sentence. When you see any of them, the fix is identical.

The git checkout case is worth pausing on, because it prints the two most-searched phrases at the same time:

error: you need to resolve your current index first
config.js: needs merge

People search for those as if they were two different errors. They are one error, two lines.

There is one more message that looks different but belongs here:

fatal: You have not concluded your merge (MERGE_HEAD exists).
Please, commit your changes before you merge.

This one appears at a slightly later point. You have already fixed the conflict markers and run git add, so your index is no longer unmerged — but you never finished the merge with a commit. Git records an in-progress merge in a reference called MERGE_HEAD, and while that exists, it will not start a second merge on top of the first. The fix is in the next section: conclude the merge.

Fix it: two safe ways out

You have exactly two choices. Finish the merge, or abandon it. Pick based on what you want, not on panic.

Path 1: finish the merge

Use this when the conflict is real work you want to keep.

Step 1 — see what is conflicted.

git status --short

Step 2 — open each conflicted file and edit it. Git has written conflict markers into the file:

<<<<<<< HEAD
const timeout = 3000;
=======
const timeout = 5000;
>>>>>>> feature-api

Everything between <<<<<<< and ======= is your side. Everything between ======= and >>>>>>> is theirs. Delete the markers and leave the code you want. That may be one side, the other, or a combination you write yourself.

Step 3 — mark it resolved.

git add config.js

This is the step people miss. git add on a conflicted file collapses those three stages back into one normal entry. That is what "resolving" means to Git — not that the markers are gone from the text, but that the file has a single stage again. Check it:

git ls-files -u

Silence means you are done.

Step 4 — conclude the merge.

git merge --continue

The git-merge documentation describes the sequence exactly this way: "Resolve the conflicts. Git will mark the conflicts in the working tree. Edit the files into shape and git add them to the index. Use git commit or git merge --continue to seal the deal. The latter command checks whether there is a (interrupted) merge in progress before calling git commit."

Both work. git merge --continue is the safer habit, because it verifies a merge is actually in progress first.

One trap, and it catches people constantly: --continue takes no arguments.

git merge --continue --no-edit
fatal: --continue expects no arguments

This is not a bug and it is not about your repository. --abort and --quit reject arguments the same way. Run git merge --continue on its own. If you want to change the message, let the editor open, or commit with git commit instead.

The same state during a rebase

A rebase produces the same unmerged index, so the same rules apply — only the command name changes. The git-rebase docs define four exits:

FlagWhat it does
--continue"Restart the rebasing process after having resolved a merge conflict."
--skip"Restart the rebasing process by skipping the current patch."
--abort"Abort the rebase operation and reset HEAD to the original branch."
--quitStops the rebase but leaves HEAD, the index and the working tree where they are.

So the finish-it path during a rebase is:

git add <file>
git rebase --continue

--skip deserves a warning. It does not skip the conflict — it drops the entire commit Git was applying when the conflict appeared. That is right when the commit's changes are already present some other way, and wrong the rest of the time. If you are not sure, use --abort and start again rather than --skip.

Path 2: abandon the merge

Use this when you started the merge by mistake, on the wrong branch, or the conflict is far bigger than you expected.

git merge --abort

Per the docs, this "abort[s] the current conflict resolution process, and try[ies] to reconstruct the pre-merge state." For a rebase, git rebase --abort "abort[s] the rebase operation and reset[s] HEAD to the original branch."

There is a real caveat here, and most articles about this error do not mention it. Straight from the git-merge docs:

"If there were uncommitted worktree changes present when the merge started, git merge --abort will in some cases be unable to reconstruct these changes. It is therefore recommended to always commit or stash your changes before running git merge."

So --abort is safe for the merge itself. It is not a guarantee for unrelated work you had lying around uncommitted when the merge began. The same docs put it plainly: "Running git merge with non-trivial uncommitted changes is discouraged."

There is also a third, rarer option. git merge --quit will "forget about the current merge in progress. Leave the index and the working tree as-is." That leaves the mess in place and only clears Git's record of the merge. It is for unusual recovery situations, not everyday use.

What not to do

This matters more than usual here, because the advice you find for these errors is frequently destructive. Several pages that rank well for these exact error messages recommend the following. Do not run them to fix an unmerged index.

git reset --hard HEAD — this throws away every uncommitted change in your working tree, including the conflict resolution you may have already done by hand, and including unrelated edits to other files. It does clear the error. It also deletes work, and Git will not ask you to confirm.

git checkout -f <branch> — the -f flag means "discard local modifications" and forces the switch. It silences the message by destroying the state that caused it.

Deleting .git/MERGE_HEAD by hand — this makes Git forget a merge is in progress while leaving your index in whatever state it was. You have removed the warning, not the problem.

Compare those with git add plus git merge --continue, or a single git merge --abort. The correct fixes are shorter than the destructive ones. There is no situation where an unmerged index requires --hard or -f to escape.

If you have already run one of them and lost work, the reflog is often able to recover committed work — see git reflog: the undo button you didn't know you had. Uncommitted changes are usually gone for good, which is exactly why the safe path matters.

How to not end up here so often

You cannot avoid conflicts — they are a normal part of working with other people. But you can make them far less painful, and the advice comes straight from the documentation rather than from habit.

Start merges from a clean tree. The git-merge docs state it directly: "Running git merge with non-trivial uncommitted changes is discouraged: while possible, it may leave you in a state that is hard to back out of in the case of a conflict." Commit or stash first. This is the same reason --abort cannot always restore uncommitted work — if there is nothing uncommitted, there is nothing at risk.

git status              # clean?
git stash               # if not, park it
git merge feature-api

Check what you are about to merge. Before merging a long-lived branch, look at how far the two have diverged:

git log --oneline main..feature-api    # commits they have that you do not
git diff main...feature-api            # the combined change

A merge of four commits touching two files is very different from a merge of sixty commits touching two hundred, and knowing which one you are starting changes whether you set aside ten minutes or an afternoon.

Merge more often, in smaller pieces. Conflicts grow with the distance between branches. A branch that pulls from main daily produces small conflicts you can resolve in a minute. A branch that has not been updated in three weeks produces the kind that generates every error message in this post at once.

Common myths

Myth 1: "Removing the conflict markers resolves the conflict."

Editing the file is only half of it. Git does not scan your file for <<<<<<< to decide whether you are finished. It looks at the index. Until you run git add on the file, it still has three stages and Git still calls it unmerged — even if the text looks perfect. This is why people fix a file, try to commit, and get the same error again. Run git ls-files -u after adding; empty output is the real confirmation.

Myth 2: "git merge --abort always restores exactly what I had."

It reliably undoes the merge. It does not promise to restore uncommitted changes that existed before the merge started. The official documentation says it "will in some cases be unable to reconstruct these changes" and recommends committing or stashing first. Treat --abort as safe for the merge, not as a general undo for your working tree.

Myth 3: "These are different errors that need different fixes."

"Needs merge", "Committing is not possible", "Pulling is not possible", "you need to resolve your current index first" — different commands, one cause. Git generates that family of messages from a single place in its source, changing only the verb. Learn the state, and you have learned every one of these errors at once, including the ones you have not met yet.

A short checklist

When Git refuses and you see any message from this post:

git ls-files -u          # 1. confirm: unmerged files?
git status --short       # 2. see which ones (UU, AA)
# 3. decide: keep this merge, or drop it?

# keeping it:
#   edit each file, remove the markers
git add <file>           #   mark resolved
git merge --continue     #   conclude (no arguments!)

# dropping it:
git merge --abort        #   back to pre-merge state

That is the whole thing. The errors are loud, but the state behind them is simple, and both exits are one command.

What to read next

Reading about a conflicted index is one thing. Being in one, with the errors in front of you, is another. You can practice in a real terminal, on a real repository, with nothing at stake: