Skip to content
GitTree

Lesson 9 · Everyday work

Create a feature branch and retire only the disposable ref

Add workflow cards on feature/pricing-cards while keeping main unchanged. Rename a throwaway branch and delete it only after proving its commit is already reachable from main.

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

  • Separate creating a branch name from checking it out.
  • Commit the workflow section on a feature without moving main.
  • Rename/delete a disposable local ref without inventing a merge.
  • Distinguish native safe-delete checks from GitTree's protected deletion.

Before you start

You start where lesson 8 ended: main has the five documented commits, a clean work tree and index, CSS-02-WORKING committed and no remote. Keep generated dist ignored. The video was recorded with Git 2.52.0 and GitTree 2.0 on Ubuntu 24.04: the branches were created, renamed, deleted and switched in the app, the file was saved and committed there, and the terminal checks ran against what the app created, or against separate copies for the create-only and renamed states. Nothing was run on macOS or Windows, and Ubuntu is the only Linux system recorded. GitTree's inspected minimum is Git 2.39.0. Once you are signed in, local branching is on the Free plan and needs no host or Pro/trial.

All branch mutations below are written steps for the isolated GitTree Features demo, never instructions to branch this website checkout. The author's source branch stays unchanged.

Concept

A branch is a movable local name for a commit, not a copy of every file. Creating a name alone does not move HEAD. Switching attaches HEAD to that branch and updates index/working files as needed. A subsequent commit advances only the checked-out branch. Native branch semantics, switch semantics.

At the start, main names H5. A disposable branch created at H5 adds a second label to the same circle, not another commit. Renaming changes the label. Removing that already-reachable label does not remove main's history. Later feature/pricing-cards starts at H5 and advances to F1; main stays H5. No remote is created or deleted.

Native git branch -d checks mergedness (normally relative to upstream/current HEAD). GitTree's inspected local deletion adapter uses -D after protecting the selected tip in its trash/journal. It is not the same refusal rule. Never assume the app will stop an unmerged deletion just because native -d did. In this course we prove the disposable tip is an ancestor of main before either path, keep the feature, and never select a remote-delete action.

Full feature file

Only index.html changes on the feature. Replace it with the full HTML-03; existing styling/scripts/history stay exactly as lesson 8 left them. The topic branch name is literal, but the section contains no prices or promotions.

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">
    <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.</p></footer>
  <script type="module" src="site.js"></script>
</body>
</html>

In GitTree

  1. Confirm the original is on main, clean, at the history-document commit. Open Command Palette… (Command/Ctrl+Shift+P) → Create Branch… (repo.branch.create). Expect Create a branch at HEAD.
  2. Set Branch name = practice/rename-me. Uncheck Check out the new branch. Choose Create Branch. Expect the new ref at the same commit while main stays checked out.
  3. In the local branch list, right-click practice/rename-me → Rename practice/rename-me…. In Rename practice/rename-me, set Branch name to practice/renamed, then Rename. Expect old name absent, new name at the same tip; no file changes.
  4. In the terminal, prove the ancestor condition below. Then right-click practice/renamed → Delete practice/renamed…. Review Delete practice/renamed in gittree-features?, ensure only the local ref is targeted, then Delete practice/renamed. Cancel if the name/tip differs. The source promises a pre-mutation trash/journal entry, not remote restoration; capture the actual operation/evidence before calling that runtime-proven.
  5. Palette Create Branch… again, name feature/pricing-cards, leave Check out the new branch checked, then Create Branch. Expect the feature checked out at the same H5. This checkbox makes the operation create and switch, unlike step 2.
  6. Show Files (Command/Ctrl+Shift+E), focus index.html and Enter. Replace its working text with full HTML-03 and Save (Command/Ctrl+S). Do not stage generated dist.
  7. Back to Graph → palette Show Working Changes. Review index.html and use Stage File. Summary feat: add workflow cards; ordinary options off; Commit Changes to 1 File / Command/Ctrl+Enter once.
  8. Right-click main in the local branch list → Checkout main. Expect the document-era hero without workflow section and clean work. Right-click feature/pricing-cards → Checkout feature/pricing-cards to return; its section reappears because the branch's committed tree differs.
  9. If a dirty-switch dialog appears, Cancel and inspect your actual work. The canonical switch points are clean; do not choose a discard option to match the film.
  10. End on feature/pricing-cards. Confirm main has five commits and the feature has one additional commit. Do not merge it yet or delete it to obtain a single-line graph.

Context actions on named refs are not generic palette commands without arguments. The top-level palette Create Branch… is a separate current-HEAD action. Use actual menu labels; default direct branch-create/switch shortcuts are not invented.

In the terminal

Native equivalent, at the clean main input; do not repeat mutations after app success:

Command · bash
git branch practice/rename-me
git symbolic-ref --short HEAD
git branch -m practice/rename-me practice/renamed
git merge-base --is-ancestor practice/renamed main

The branch/rename/ancestor checks were silent successful; symbolic-ref prints:

Output
main

Exit 0 from the ancestor query proves this disposable tip is already reachable. A nonzero result means stop; do not substitute force deletion.

Command · bash
git branch --delete --quiet practice/renamed
git switch --quiet --create feature/pricing-cards

Both succeeded silently. After saving full HTML-03:

Command · bash
git add -- index.html
git commit --quiet -m "feat: add workflow cards"
git switch --quiet main

All succeeded silently in the fixture. This main switch does not move the feature ref.

Intentional native refusal, while main is checked out:

Command · bash
git -c advice.forceDeleteBranch=false branch -d feature/pricing-cards

Observed stderr, exit 1:

Output
error: the branch 'feature/pricing-cards' is not fully merged

The feature remains. Do not attempt this as an app safety test: its protected deletion policy differs. Do not replace -d with -D to “fix” the lesson.

Return and inspect:

Command · bash
git switch --quiet feature/pricing-cards
git symbolic-ref --short HEAD
git branch --format='%(refname:short)'
git rev-list --count main..feature/pricing-cards
git log --format=%s main..feature/pricing-cards
git diff --name-only main feature/pricing-cards
git rev-list --count main
git status --short

Observed outputs after the silent switch, in order:

Output
feature/pricing-cards
feature/pricing-cards
main
1
feat: add workflow cards
index.html
5

Final short status is empty with exit 0. Both disposable names are absent. No remote output exists because none was configured.

Result

At the end of this lesson: feature/pricing-cards checked out and clean, one feature commit beyond main; main remains at the five-commit document checkpoint. Workflow cards contain no price. Disposable branches absent. No merge, remote, published branch or provider action.

Common mistakes

  • Counting branch labels as commits.
  • Assuming create-only moved HEAD.
  • Renaming the active source-web branch instead of the demo ref.
  • Believing app deletion has native -d's guard.
  • Deleting the useful feature to simplify the graph.

If something goes wrong

Invalid/duplicate names should keep the dialog open with the entered value. Read the error; do not resolve case-only ambiguity by renaming unrelated refs. If work blocks a switch, cancel and preserve it; later stash/commit lessons offer deliberate choices. A branch checked out in another worktree cannot simply be deleted.

A native unmerged refusal is protective. The app's pre-mutation snapshot is a different mechanism, not permission to ignore reachability or tip identity. A failed mutation must not be presented as success just because a label disappeared temporarily from a filtered view.

Check your understanding

Answer each question, then read why. Questions marked “Required” count toward completing the lesson.

  1. Question 1 of 6

    Creating another ref at H5 creates how much history?

    Choose one answer.

  2. Question 2 of 6

    Before deleting the disposable ref, what is required?

    Choose every answer that applies.

  3. Question 3 of 6
    Required

    Commit HTML-03 on feature/pricing-cards from H5. Where is main?

    Choose one answer.

  4. Question 4 of 6
    Required

    Uncheck Check out the new branch while on main. What changes?

    Choose one answer.

  5. Question 5 of 6

    Native -d refuses the unmerged feature. Does that prove GitTree refuses too?

    Choose one answer.

  6. Question 6 of 6
    Required

    Which evidence proves the finished checkpoint?

    Choose every answer that applies.

0 of 6 correct

Answer the required questions correctly to complete the lesson.

Checked in this browser.

Practice

Show main unchanged and the feature one commit ahead. Changed input: if Check out the new branch is off, predict HEAD remains main until an explicit switch. Test in a separate disposable replay, not by altering the finished checkpoint. Explain why the native refusal does not prove an app refusal.

Your own confirmation: the site cannot see your computer.

To complete the lesson, answer the required questions correctly and confirm the practical exercise.

Recap

  • Branch names and commits are different objects.
  • Create-only and create-and-switch have different HEAD effects.
  • Prove deletion scope and reachability; protected app deletion and native -d differ.

Glossary terms introduced

Branch — فرع; switch — تبديل; ref — مرجع; reachable — قابل للوصول; upstream — فرع متتبَّع; working tree — مجلد العمل.

Video transcript

The narration of the video, cue by cue.

Show the transcript
  1. Create a feature branch while preserving main.
  2. A new branch name does not create a commit.
  3. Create the disposable name without leaving main.
  4. Confirm that create-only did not switch your branch.
  5. Rename the disposable ref, not the website's source branch.
  6. Check the current disposable tip is already reachable from main.
  7. Delete only the prechecked disposable reference.
  8. GitTree's protected deletion is not native safe-delete refusal.
  9. This time, create the feature and check it out.
  10. Save the workflow section without prices or promotions.
  11. Review the feature's one changed file before committing.
  12. Commit on the feature, not on main.
  13. Only the checked-out branch advances with this commit.
  14. Switching selects main's committed tree.
  15. Native safe deletion refuses the unmerged feature.
  16. That refusal does not prove GitTree will refuse the same deletion.
  17. Return to the feature's recorded file contents.
  18. Verify one feature commit and only index dot H T M L changed.
  19. Main still has five commits and the feature is clean.
  20. With checkout off, the new name exists but HEAD stays on main.
  21. Cancel an unexpected dirty switch and inspect the work first.
  22. A protected local tip is not a promise of remote restoration.
  23. Keep the useful feature and verify the disposable names are gone.
  24. The next lesson introduces remotes; none was needed here.