Continue, skip or abort a conflicted Git rebase
For a conflicted Git rebase, continue after resolving and staging the current conflict, skip only when deliberately omitting the current commit, or abort to return to the pre-rebase branch state. These are different outcomes, so identify the stopped operation and preserve any work you need before choosing.
Choose a rebase conflict path
Continue a conflicted rebase after resolving and staging the conflict, skip only to omit the current commit, or abort to return to the pre-rebase state. The rebase reference distinguishes git rebase --continue, git rebase --skip and git rebase --abort1. Those verbs do not mean “try again,” “ignore the warning” and “close the window”: each can leave a materially different history.
Before acting, read the current operation and the affected files. A merge conflict and a rebase conflict can look similar in a file but have different operation-specific commands. Decide whether the current commit’s change is needed, whether a correct resolution is known and whether the work done during the stop should be retained. A backup of valuable work can matter even when the intended choice is abort.
Understand the controlled conflict
The example creates three separate cases with the same starting history. In each case a topic branch changes a line to one value, while the main branch changes that same line to another. The rebase stops when Git tries to replay the topic change on the new base. The branch’s original topic commit is recorded before the operation, making the abort check concrete rather than relying on an imprecise description of “going back.”
Each case has a local bare remote and pushes the main branch to it. The conflict itself occurs in the local working repository. No network service or collaborator is involved. The script expects the rebase to stop; if it unexpectedly succeeds, the script fails instead of describing a conflict that did not occur. This is a deliberately small fixture, not an estimate of how a larger history will behave.
Continue after a deliberate resolution
In the continue case, the example replaces the conflicted file with an explicit chosen line, stages it and supplies a small editor script for the continuation. It checks that the resulting file has the chosen content, the new tip differs from the original topic commit and the main tip is an ancestor. Those assertions demonstrate both a content choice and the history relationship for this single case.
In real work, the chosen resolution needs to preserve the intended behavior of both lines of development where appropriate. Removing conflict markers alone is not a proof of correctness. Read the whole relevant change, stage only the intended resolution and check what remains before continuing. Git may stop again on another commit; a successful continuation of one step does not establish that the rest of the sequence will be conflict-free.
Skip or abort are not equivalents
The skip case deliberately omits the conflicting topic commit. In this fixture, that leaves the branch at the upstream tip with the upstream text. It is appropriate only if the current patch is unnecessary or has been handled elsewhere. Skipping a needed commit can remove a change the author intended; the command cannot decide that question from the existence of a conflict.
The abort case returns the branch to its recorded original topic tip and restores the topic line in this controlled starting state. It also discards edits made to tracked files during the conflict, including a staged resolution, so don’t rely on abort as a backup for resolution work you still need. Save that work separately before abandoning the operation.
The test checks three separate repositories so that one outcome does not become the starting point for another. Continue, skip and abort therefore correspond to distinct decisions, not a sequence of commands to run one after another on the same stopped rebase. Once an operation has completed or been aborted, the other choices are no longer instructions for that same stop.
Check the result before sharing
After the chosen operation, inspect status and the branch history. Confirm that the intended changes remain, unwanted changes are absent and the new ancestry is understood. A rebase generally creates replacement commit identities; other work that refers to the earlier commits may need coordination. The test demonstrates a changed tip, not a general procedure for rewriting a branch already used by other people.
If the branch has been shared, agree on the history strategy before publishing replacement commits. A successful local rebase does not imply that updating a remote is permitted or that a force operation is safe. The example never pushes its rebased topic branches. It limits its claims to one stopped patch in each local case and keeps the three outcomes visible for comparison.
Run the complete local example
Before running: Continue, skip and abort produce different histories. Preserve needed resolution work before running any of them in a real repository. Run this complete MIT-licensed example with Git 2.56.0 in an empty directory. It creates rebase-example/, including its own local bare remote. It performs no network access and refuses to reuse an existing example directory.
Download the complete example. The printed file is the one that ran.
#!/bin/sh
# SPDX-License-Identifier: MIT
set -eu
export TZ=UTC LC_ALL=C
export GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null
export GIT_AUTHOR_NAME='Example Author' GIT_AUTHOR_EMAIL='author@example.invalid'
export GIT_COMMITTER_NAME='Example Author' GIT_COMMITTER_EMAIL='author@example.invalid'
export GIT_AUTHOR_DATE='2026-10-27T12:00:00+00:00'
export GIT_COMMITTER_DATE='2026-10-27T12:00:00+00:00'
test "$(git version)" = 'git version 2.56.0'
mkdir rebase-example
cd rebase-example
printf '#!/bin/sh\nexit 0\n' > editor.sh
chmod +x editor.sh
case_setup() {
mkdir "$1"
cd "$1"
git init --template= --bare -q --initial-branch=main origin.git
git init --template= -q --initial-branch=main repo
cd repo
printf 'base\n' > note.txt
git add note.txt
git commit -qm 'Base'
git remote add origin ../origin.git
git push -q -u origin main >/dev/null
git switch -qc topic
printf 'topic\n' > note.txt
git commit -qam 'Topic change'
original=$(git rev-parse HEAD)
git switch -q main
printf 'upstream\n' > note.txt
git commit -qam 'Upstream change'
git push -q origin main
git switch -q topic
if git rebase main >../rebase-log 2>&1; then
printf 'Expected a conflict\n' >&2
exit 1
fi
}
case_setup continued
printf 'resolved\n' > note.txt
git add note.txt
GIT_EDITOR=../../editor.sh git rebase --continue >/dev/null 2>&1
test "$(cat note.txt)" = resolved
test "$(git rev-parse HEAD)" != "$original"
git merge-base --is-ancestor main HEAD
printf 'Continue: resolved commit replayed on main\n'
cd ../..
case_setup skipped
git rebase --skip >/dev/null 2>&1
test "$(cat note.txt)" = upstream
test "$(git rev-parse HEAD)" = "$(git rev-parse main)"
printf 'Skip: conflicting topic commit omitted\n'
cd ../..
case_setup aborted
git rebase --abort
test "$(git rev-parse HEAD)" = "$original"
test "$(cat note.txt)" = topic
printf 'Abort: original topic commit and content restored\n'
Both runs produced:
Continue: resolved commit replayed on main
Skip: conflicting topic commit omitted
Abort: original topic commit and content restored
The script leaves its example directory and its repositories in place. Remove that newly created directory when it is no longer needed; inspect the name first so cleanup does not remove another project. The assertions stop the run if the demonstrated state differs. No command in the example connects to an external remote.
Not covered on this page
- Interactive todo editing, multi-commit conflicts and empty-commit policy.
- Recovery of unrecorded edits made during an aborted rebase.
- Publishing rewritten shared history or resolving project-specific conflicts.
Sources
-
Git 2.56.0 rebase reference. Git v2.56.0; checked 27 October 2026 UTC. ↩
How we test: methodology. Found a mistake? Corrections.