Resolving git rebase CONFLICT: A Complete Guide to continue, abort, and skip
Ever been rebasing a feature branch onto main when the terminal suddenly froze like this?
CONFLICT (content): Merge conflict in src/app.js
error: could not apply a1b2c3d... feat: add login
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".The first questions that usually pop into your head are: "Do I need to commit here? If I hit abort, will all my work vanish?" Let's cut to the chase: running git rebase --abort restores you 100% to the exact state just before you started the rebase. Your work will not disappear. So take your hands off the keyboard and read this slowly.
Why rebase "stops": start with the mental model
The biggest difference between merge and rebase is the unit at which conflicts are handled.
- merge: Both branches are combined at once, so every conflict hits you in one shot.
- rebase: Your commits are replayed one by one on top of main. Conflicts therefore pause one commit at a time.
In other words, a stopped rebase is a signal that says: "I hit a conflict applying the Nth commit—fix just this one and I'll keep applying the rest." Think of it as a pause button, not a scary error.
As of 2026, more teams on GitHub and GitLab default to a "Rebase and merge" policy, so even junior developers hit this screen far more often. VS Code or Cursor's merge editor and AI assistants can help with the markers, but when to run --continue is still a human decision.
Where did you stop? How to read git status
When you're panicking, the first command to run is just one: git status.
$ git status
interactive rebase in progress; onto 9f8e7d6
Last command done (1 command done):
pick a1b2c3d feat: add login
Next commands to do (2 remaining commands):
pick b2c3d4e feat: add logout
pick c3d4e5f refactor: auth util
You are currently rebasing branch 'feature/auth' on '9f8e7d6'.
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: src/app.js
no changes added to commit (git add will track these changes)Here's a table of what each line means.
| Actual output | Meaning | What to do next |
|---|---|---|
interactive rebase in progress | You're paused in the middle of a rebase | Don't create a new commit; figure out the state first |
Last command done (1 command done) | The commit that just failed to apply | Resolve this commit's conflicts |
Next commands to do (2 remaining) | How many commits still need to be applied | Be aware more conflicts may appear after this one |
Unmerged paths: | Files that still have conflicts | Edit these files yourself |
both modified: src/app.js | Both main and your commit changed the same place | Open this file and resolve the markers |
(use "git add <file>...") | Mark resolution with git add | After editing, git add |
The key takeaway: you only need to touch files marked both modified.
The standard fix: resolve conflict markers → add → --continue
Open src/app.js and you'll see markers like this.
function getUser() {
<<<<<<< HEAD // ⬆️ = main
return fetchUser({ cache: true });
======= //
return fetchUser({ cache: false, retry: 3 });
>>>>>>> a1b2c3d (feat: add login) // ⬇️ =
}Remember just two things when reading the markers.
<<<<<<< HEAD~=======: code already on main (the side that's already been applied)=======~>>>>>>> a1b2c3d: your commit that's being applied now
Manually combine them into the final form you want, then delete all three marker types (<<<, ===, >>>).
function getUser() {
return fetchUser({ cache: true, retry: 3 }); // Result
}Here's the full workflow, ready to copy-paste.
# 1) check
git status
# 2) both modified file (<<<, ===, >>>)
# (VS Code/Cursor )
# 3) file '' when — commit add!
git add src/app.js
# 4) rebase
git rebase --continue
# 5) ? → 2~4 as-isWhy you must not run git commit here
A common mistake is habitually running git commit after resolving conflicts.
# ❌
git add src/app.js
git commit -m "fix conflict" #
# ✅
git add src/app.js
git rebase --continue #During a rebase, Git is "replaying the original commit," so --continue finishes that commit for you. If you commit yourself, an extra stray commit appears and the history gets messy.
Escape hatches: 100% restore with --abort, and the danger of --skip
--abort: safely back to the start anytime
If the merge is too messy, or you think "this isn't the time," don't hesitate—abort.
git rebase --abortThis command fully restores the state just before the rebase started (ORIG_HEAD). It doesn't matter if you've already --continued two or three times. No matter where you paused, one abort puts everything back as it was. There's zero reason to panic-force-push because you're afraid of losing work.
--skip: a dangerous command that can drop code
git rebase --skip--skip discards the entire changeset of the currently conflicting commit and moves on to the next one. That commit's code can disappear from the result. Use it only in these two cases:
- The commit's changes are already on main, so it became an empty commit
- You deliberately decided to drop that commit
If you're not sure, --abort is always safer than --skip.
3-way comparison table
| Command | What it does | Does work get lost? | When to use |
|---|---|---|---|
git rebase --continue | After resolving conflicts, proceed to the next commit | No | After you resolve markers and add |
git rebase --abort | Fully restore to just before the rebase started | Not at all | When it's messy or you're unsure; start over |
git rebase --skip | Drop the current commit's changes and move on | They can be discarded | Empty commits / changes already applied only |
Wrap-up: use rerere for repeated conflicts, plus a never-do list
On a long rebase you may resolve the same conflict more than once. Turn on rerere (reuse recorded resolution) and Git remembers how you resolved it and auto-applies it next time.
git config --global rerere.enabled trueFinally, a checklist of things you must never do during a rebase.
- ❌ Running
git commityourself after resolving conflicts → ✅git rebase --continue - ❌ Creating a new branch or starting other work mid-rebase → Finish or abort first
- ❌ Blind
git push -f→ you can overwrite teammates' commits - ✅ If you truly need a force push, use
--force-with-lease
# ❌ :
git push -f
# ✅ : after
git push --force-with-leaseA note from the field: As a junior I was so scared of the conflict screen that I force-pushed instead of aborting—and wiped a teammate's commits. After that I made one rule: "If you're not sure, always --abort." Abort costs nothing, and you can retry a rebase as many times as you want. Don't flee to a dangerous command just because you're afraid.
FAQ
Q. Does git rebase --abort delete all the code I've been working on?
A. No. Abort only restores the exact commit state from just before the rebase started. Work already committed on the branch is preserved. You can press it with confidence.
Q. I resolved the conflicts but I still see You have unmerged paths.
A. You probably edited the files but didn't mark them resolved with git add. Run git add <file>, check git status again to confirm unmerged paths are gone, then run git rebase --continue.
Q. If I'm unsure between git rebase --continue and git rebase --skip, which should I use?
A. If you need to keep the changes, resolve the conflict and --continue. If it's OK to drop that commit, --skip. If you're not sure, press neither—--abort back to the start and try again slowly.
Sources and checks vary by article. Only articles with a recorded check date, scope and sources below were checked, and only within that scope. For other articles, verify against the current docs for your version before applying anything, and email us about errors. Editorial policy · email us
This article has no recorded human check (date and scope) yet.
Comments
Be the first to comment.