Lesson 24 · Recovery
Continue, skip or abort an active operation
When a merge or a rebase stops, you have three ways out: continue, skip or abort. Learn which one fits, what each one throws away, and how to check the repository afterwards.
- Level: Intermediate
- 13 min read
- 7 min video
- Updated
- Before this lesson: Resolve merge and rebase conflicts
Progress saved in this browser.
Playing loads the video from YouTube (privacy-enhanced mode).
What you will learn
- Tell which operation is active before you touch anything.
- Continue only after every conflict is resolved and marked.
- Explain what Skip leaves out, and when it is the wrong tool.
- Abort an operation and check that you are back at the start.
Before you start
You use the divergence from lesson 23: conflict/sara (Sara's heading "Review changes with confidence.") and conflict/omar (Omar's heading "Understand each saved change."), both from the commit M. Make three clean copies of it, named gittree-continue, gittree-abort and gittree-skip. In each, conflict/sara is checked out and nothing is running. You will stop the same operation in all three and leave each one a different way.
Everything is local and on the Free plan (GitTree asks you to sign in): no hosting account, no provider, no internet. Every identity is fictional (example.com). Never run this lesson in a real project.
Make the changes in GitTree or with the native Git commands, not both in the same copy. Reading the result is always safe. The menu labels come from GitTree 2.0's own strings and the native commands were run with Git 2.43 in disposable copies. The GitTree steps were not run on macOS, Windows or Linux.
Concept and state effects
A stopped operation is a state of its own. Until it ends, the repository remembers what it was doing, and you must not start another merge or rebase on top of it. First find out what is active. GitTree's banner says it plainly: "Merging … into …", or "Rebasing … onto …" (with the step number when there are several), and the number of conflicts left. In a terminal, git status starts with "You have unmerged paths" and a hint for a merge, or "interactive rebase in progress; onto …" for a rebase, and then lists the commands you can use.
Continue carries on once every conflict is resolved and its result is staged. It is not a retry of the original merge or rebase: it finishes the merge commit, or moves a rebase on to its next commit.
Skip exists for operations that replay commits, such as a rebase. It leaves the current commit's change out of the result entirely. In this lesson Skip drops Sara's heading and the branch ends on Omar's commit. It is not a way to "accept the file" or to postpone a conflict, and it is the wrong tool whenever you still want that change. A merge has no Skip, because a merge is one step: you either finish it or abort it.
Abort goes back to where the operation began. Whatever you resolved so far is dropped. GitTree saves a recovery snapshot of what it drops first, and the repository returns to the exact commit, index and files it had before. It is the way out when you are not sure what you are doing.
| Choice | The result | What it costs |
|---|---|---|
| Continue | Merge commit made, or the next commit replayed | nothing, once everything is resolved |
| Skip | The current commit's change is left out | that change, until you find it again |
| Abort | The repository is back at the start | the work done during the operation |
Prepare the exact project state
Build Sara's and Omar's branches once, then make three copies. Start from a separate ordinary copy of the project as lesson 18 left it, and leave your original gittree-features untouched. The page versions: MERGED is the shared base, SARA and OMAR are the competing versions and RESOLVED is the result you save in the continue copy.
Complete file inputs
Save only at the phase named below. These are full UTF-8/LF bodies with a final newline; never paste Markdown fences. Unchanged runnable files inherit the named input. Versions in separate variants must not overwrite the original.
index.html — MERGED
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">See your work clearly.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>index.html — SARA
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Review changes with confidence.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>index.html — OMAR
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Understand each saved change.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>index.html — RESOLVED
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Review each change with confidence.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>In GitTree
Open the palette with Command+Shift+P (Ctrl+Shift+P on Ubuntu). Actions on a named branch use that branch's right-click menu.
- Build the three copies as the next section shows. In each,
conflict/sarais checked out and the status is empty. Note the full ID ofconflict/sarain the abort copy. - Continue copy. Open gittree-continue. Right-click
conflict/omarand choose Merge conflict/omar into conflict/sara, with Always a merge commit. It stops. On the banner choose Resolve, openindex.html, choose Edit Output, writeReview each change with confidence.and choose Save and Mark Resolved. - Check that no conflict is left, then choose Continue on the banner once. The notice says "Done." and the banner goes away. The new commit has two parents.
- Abort copy. Open gittree-abort and start the same merge. Leave the conflict unresolved. On the banner choose Abort…. The dialog "Abort the operation?" explains that the branch, index and files go back to what they were and that what is dropped is kept in the recovery snapshots first. Choose Abort. The notice says "Aborted. The change it dropped is kept under refs/ogt/trash/…; Undo brings it back." (when the abort drops nothing, it says "Aborted. The repository is back where it was before.")
- Check the abort:
conflict/sarais still the ID you noted, the page is Sara's full heading and there is no banner. - Skip copy. Open gittree-skip. Right-click
conflict/omarand choose Rebase conflict/sara onto conflict/omar. Leave the options off and choose Rebase conflict/sara. It stops. The banner now offers Skip next to Continue and Abort…; the merge banner had no Skip. - Read which commit is being replayed (Sara's), accept that skipping leaves out her heading, and choose Skip once. The notice says "Skipped the step."
- Check the skip: the page shows Omar's heading,
conflict/saranow points at Omar's commit and no banner is showing. Compare the three results and keep them apart.
For every ordinary commit in the course: Summary is the stated subject, Description is empty and the options Amend Previous Commit, Skip Hooks, Add Signed-off-by, Different Author, Push After Commit and Allow Empty Commit stay off.
In the terminal
In a separate clean copy of lesson 18's result:
git switch --create conflict/sara
BASE_SHA="$(git rev-parse HEAD)"Save SARA as index.html, then:
git add -- index.html
git -c user.name="Sara Lindqvist" -c user.email=sara@example.com commit --quiet -m "feat: Sara clarifies the hero"
git switch --quiet --create conflict/omar "$BASE_SHA"Save OMAR as index.html, then:
git add -- index.html
git -c user.name="Omar Haddad" -c user.email=omar@example.com commit --quiet -m "feat: Omar explains the hero"
git switch --quiet conflict/saraMake three clean copies of this state (gittree-continue, gittree-abort, gittree-skip). First, see what is active whenever you are unsure:
git statusContinue copy. The merge stops with exit code 1. Save RESOLVED as index.html, then:
git merge --no-ff --no-edit conflict/omar
git add -- index.html
git -c core.editor=true merge --continue
git ls-files --unmerged
git status --shortThe last two commands print nothing. Abort copy:
git rev-parse conflict/sara
git merge --no-edit conflict/omar
git merge --abort
git rev-parse HEAD conflict/sara
git status --shortThe merge stops, and git merge --abort ends it. The two IDs printed by git rev-parse HEAD conflict/sara are equal, index.html is Sara's full page and the status is empty. A stopped rebase is left the same way with git rebase --abort. Skip copy:
git rebase conflict/omar
git rebase --skip
git rev-parse HEAD conflict/omar
git status --shortThe rebase stops; git rebase --skip finishes it with "Successfully rebased". The two IDs are equal, so Sara's branch now sits on Omar's commit, the page is Omar's, and the status is empty. Sara's skipped commit is no longer on the branch, but Git still has it for a while (the reflog, lesson 29). Do not read that result as a resolution that kept both inputs.
Result
Where you end: three copies, three different outcomes. The continue copy has a two-parent merge commit with the combined heading. The abort copy is exactly where it started, with Sara's heading. The skip copy has Omar's heading and Sara's branch on Omar's commit. In all three the operation is over and the status is clean.
Common mistakes
- Using Skip to "get past" a conflict. It deletes that commit's change from the result.
- Starting another merge or rebase while one is still stopped.
- Using
git reset --hardto escape, instead ofgit merge --abortorgit rebase --abort. - Aborting when you are one click from finishing, or continuing when you are not sure what is staged.
If something goes wrong
If you are lost, read the banner or git status first and decide again. Abort is always the safe way back to the start. If you skipped by mistake, do not start over blindly: the skipped commit is still reachable for a while from the reflog (lesson 29), and lesson 30 shows what GitTree's Undo can put back.
Check your understanding
Answer each question, then read why. Questions marked “Required” count toward completing the lesson.
0 of 6 correct
Answer the required questions correctly to complete the lesson.
Checked in this browser.
Practice
In each copy, state the operation, the choice and the proof: for Continue the two parents and the empty unmerged list, for Abort the equal IDs and Sara's page, for Skip Omar's page and the branch on his commit. Then predict why Skip is not offered for a merge.
Your own confirmation: the site cannot see your computer.
To complete the lesson, answer the required questions correctly and confirm the practical exercise.
Recap
- Find out what is active before you act.
- Continue after resolving, skip only to leave a commit out, abort to go back.
- Check the commit, the files and the status afterwards.
Related
Glossary terms introduced
Continue — متابعة; skip — تخطّي; abort — إيقاف; operation — عملية.
Video transcript
The narration of the video, cue by cue.
Show the transcript
- A merge or a rebase stops. You have three ways out.
- Continue finishes it. Skip leaves one commit out. Abort goes back.
- First, always find out which operation is active.
- The banner names it. In a terminal, git status does.
- Build Sara's and Omar's branches, and three identical copies.
- Same start, three different endings.
- Copy one: we continue. Start the merge, and it stops.
- Resolve, open the file, and write the combined heading.
- Save and Mark Resolved, so Git sees the file as done.
- Continue is available now. Choose it once.
- Done. The new commit has two parents, and the banner is gone.
- Copy two: we abort. Start the same merge.
- Leave the conflict alone, and choose Abort.
- The dialog explains what comes back, and what is kept first.
- The repository is back where it was before.
- The branch tip is the same ID, and the page is Sara's again.
- Copy three: we skip. This one is a rebase.
- Rebase Sara's branch onto Omar's. It stops with a conflict.
- Now the banner has a Skip button. A merge never had one.
- Skip leaves Sara's commit out of the result. Say that out loud.
- Choose Skip once.
- The page shows Omar's heading. Sara's branch now sits on his commit.
- Skip is not a resolution. It deleted Sara's change from this result.
- In the terminal, git status shows what is active, and the commands.
- The merge: add the resolved file, then git merge continue.
- The abort: the branch tip is the same before and after.
- The skip: git rebase skip, and the branch sits on Omar's commit.
- In every copy, the status is empty, and nothing is left unmerged.
- Change the input: resolve the file, then choose Abort instead.
- Your resolution is dropped, after a recovery snapshot is saved.
- Never use reset hard to escape. Abort is the safe way out.
- If you skipped by mistake, the commit is still in the reflog.
- Practice: name the operation, the choice, and the proof, for each copy.
- Next, copy a single commit onto another branch with cherry-pick.