Skip to content
GitTree

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.

Progress saved in this browser.

Playing loads the video from YouTube (privacy-enhanced mode).

English narration · English and Arabic captions

Open the video pageWatch on YouTube

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.

ChoiceThe resultWhat it costs
ContinueMerge commit made, or the next commit replayednothing, once everything is resolved
SkipThe current commit's change is left outthat change, until you find it again
AbortThe repository is back at the startthe 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

File excerpt · html
<!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

File excerpt · html
<!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

File excerpt · html
<!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

File excerpt · html
<!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.

  1. Build the three copies as the next section shows. In each, conflict/sara is checked out and the status is empty. Note the full ID of conflict/sara in the abort copy.
  2. Continue copy. Open gittree-continue. Right-click conflict/omar and choose Merge conflict/omar into conflict/sara, with Always a merge commit. It stops. On the banner choose Resolve, open index.html, choose Edit Output, write Review each change with confidence. and choose Save and Mark Resolved.
  3. 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.
  4. 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.")
  5. Check the abort: conflict/sara is still the ID you noted, the page is Sara's full heading and there is no banner.
  6. Skip copy. Open gittree-skip. Right-click conflict/omar and 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.
  7. 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."
  8. Check the skip: the page shows Omar's heading, conflict/sara now 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:

Command · bash
git switch --create conflict/sara
BASE_SHA="$(git rev-parse HEAD)"

Save SARA as index.html, then:

Command · bash
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:

Command · bash
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/sara

Make three clean copies of this state (gittree-continue, gittree-abort, gittree-skip). First, see what is active whenever you are unsure:

Command · bash
git status

Continue copy. The merge stops with exit code 1. Save RESOLVED as index.html, then:

Command · bash
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 --short

The last two commands print nothing. Abort copy:

Command · bash
git rev-parse conflict/sara
git merge --no-edit conflict/omar
git merge --abort
git rev-parse HEAD conflict/sara
git status --short

The 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:

Command · bash
git rebase conflict/omar
git rebase --skip
git rev-parse HEAD conflict/omar
git status --short

The 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 --hard to escape, instead of git merge --abort or git 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.

  1. Question 1 of 6

    A rebase stopped on a conflict. You resolved the file and staged it. Which command carries the rebase on?

    Choose one answer.

  2. Question 2 of 6

    What does git rebase --skip do?

    Choose every answer that applies.

  3. Question 3 of 6
    Required

    In the skip copy you choose Skip once. What do the page and the branch look like afterwards?

    Choose one answer.

  4. Question 4 of 6

    Change the input: in the continue copy you resolve the file and mark it resolved, then choose Abort… instead of Continue. What happens to your resolution?

    Choose one answer.

  5. Question 5 of 6
    Required

    You are in the middle of a merge and look for a Skip button on the banner, but it is not there. Why?

    Choose one answer.

  6. Question 6 of 6
    Required

    After aborting the merge in the abort copy, which readbacks show you are back at the start?

    Choose every answer that applies.

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.

Glossary terms introduced

Continue — متابعة; skip — تخطّي; abort — إيقاف; operation — عملية.

Video transcript

The narration of the video, cue by cue.

Show the transcript
  1. A merge or a rebase stops. You have three ways out.
  2. Continue finishes it. Skip leaves one commit out. Abort goes back.
  3. First, always find out which operation is active.
  4. The banner names it. In a terminal, git status does.
  5. Build Sara's and Omar's branches, and three identical copies.
  6. Same start, three different endings.
  7. Copy one: we continue. Start the merge, and it stops.
  8. Resolve, open the file, and write the combined heading.
  9. Save and Mark Resolved, so Git sees the file as done.
  10. Continue is available now. Choose it once.
  11. Done. The new commit has two parents, and the banner is gone.
  12. Copy two: we abort. Start the same merge.
  13. Leave the conflict alone, and choose Abort.
  14. The dialog explains what comes back, and what is kept first.
  15. The repository is back where it was before.
  16. The branch tip is the same ID, and the page is Sara's again.
  17. Copy three: we skip. This one is a rebase.
  18. Rebase Sara's branch onto Omar's. It stops with a conflict.
  19. Now the banner has a Skip button. A merge never had one.
  20. Skip leaves Sara's commit out of the result. Say that out loud.
  21. Choose Skip once.
  22. The page shows Omar's heading. Sara's branch now sits on his commit.
  23. Skip is not a resolution. It deleted Sara's change from this result.
  24. In the terminal, git status shows what is active, and the commands.
  25. The merge: add the resolved file, then git merge continue.
  26. The abort: the branch tip is the same before and after.
  27. The skip: git rebase skip, and the branch sits on Omar's commit.
  28. In every copy, the status is empty, and nothing is left unmerged.
  29. Change the input: resolve the file, then choose Abort instead.
  30. Your resolution is dropped, after a recovery snapshot is saved.
  31. Never use reset hard to escape. Abort is the safe way out.
  32. If you skipped by mistake, the commit is still in the reflog.
  33. Practice: name the operation, the choice, and the proof, for each copy.
  34. Next, copy a single commit onto another branch with cherry-pick.