# Git branches: parallel versions of the project

> What a Git branch is, why work happens on short-lived branches next to main, and how to read branches on GitHub: the branch selector, ahead and behind, stale branches, naming conventions and graphs with several lanes.

- Course: [Git and GitHub for Product People](https://productovi.com/courses/git-for-product.md)
- Module: Branches and merges
- Lesson 4/15, ~34 min
- Source: https://productovi.com/courses/git-for-product/branches

## A week of work the site never saw

**Alex Tutor:** Back on CatChow's product team, you've got a question for Daniel, one of the website's developers.

**Sofia:** Daniel, I have to ask. How exactly did you break the checkout button?

**Daniel:** Fair question. In March I redesigned it. I spent a week on a separate **branch**, `feature/checkout-redesign`, and all that week the live site stayed exactly as it was.

**Sofia:** So nothing you did on the branch reached customers?

**Daniel:** Nothing, until the branch was merged into `main`. That's when the button broke, and ten minutes later we reverted the merge. I'll confess the details at the end of the lesson.

**Alex Tutor:** That's today's topic: what is a Git branch? A **branch** is a parallel version of the project, its own line of commits. Work on it can be unfinished or even broken, and `main` doesn't notice.

![A side track curves off a railway main line; a worker builds and tests a new carriage in a shed while trains on the main line keep reaching the station.](https://productovi.com/courses/git-for-product/inline/branches-illustration-2.webp)

*Unfinished work lives on its own line until it's merged into main.*

**Alex Tutor:** `main` is a branch too: the **default branch**. GitHub opens it first, and at CatChow it's the version that gets deployed to the site. In older repositories it's often called `master`.

> **Exercise:** Daniel adds a new commit to `fix/checkout-button`. Customers on the CatChow site see the change right away.

## A name that moves

**Sofia:** When Daniel creates a branch, does GitHub copy the whole project? That sounds heavy.

**Alex Tutor:** No copying. A branch is just a name that points at one commit, the newest on its line. Add a commit, and the name moves forward to it.

**Alex Tutor:** Compare it with a tag from module 1. A tag stays on its commit forever. A branch name keeps moving as long as people commit to the branch.

**Alex Tutor:** A quick check on that moving name before we look at Daniel's branch.

> **Exercise:** Daniel adds a new commit to `fix/checkout-button`. What happens to the branch name?

**Alex Tutor:** Here's what Daniel is working on right now. Support reported a bug: after a customer edits the cart, the checkout button stays grey. He started `fix/checkout-button` from the latest commit on `main`.

```text
Commit graph, oldest first: main and the branch fix/checkout-button
1. commit e7c3b19 on main "Add summer promo banner"
2. commit f02a6d4 on main "Update FAQ answers"
3. branch fix/checkout-button starts from commit f02a6d4
4. commit 3a9d1c4 on fix/checkout-button "Reproduce bug in a test"
5. commit 8be2f70 on main "Add cat treats bundle"
6. commit b7e4a05 on fix/checkout-button "Re-enable button after cart edits" (highlighted)
```

*The branch starts at f02a6d4 and has two commits of its own. 8be2f70 reached main after the branch had started.*

**Sofia:** Two lanes. The left one is `main`. The right one curves out of "Update FAQ answers" and has two commits of its own.

**Alex Tutor:** Right. And notice that `main` didn't wait: "Add cat treats bundle" landed there while Daniel was working. The two lines now differ in both directions.

> **Exercise:** You switch the branch selector to `feature/gift-wrap`. Which commits are in the history of that branch? Select all that apply.

## Switching branches on GitHub

**Alex Tutor:** Now find it on GitHub. On the repository page, click the branch selector, the button that says `main`. It lists the branches, and the search field filters them by name.

**Sofia:** I'm picking `fix/checkout-button`. The file list looks the same, but the latest commit bar now says "Re-enable button after cart edits".

**Alex Tutor:** You're looking at the project as it exists on that branch. The address changed too: it now contains `/tree/fix/checkout-button`. Switching only changes what you see. It edits nothing.

**Daniel:** A classic trap: someone sends you a link to a file on a branch, and you think that's what the site says. Always check which branch the selector shows.

**Alex Tutor:** Under the selector GitHub adds a hint. As of 2026 it reads roughly like this: "This branch is 2 commits ahead of, 1 commit behind `main`".

> **Exercise:** A colleague sends you a link to `config/prices.json`. The address contains `/blob/feature/subscription/`, and the file says delivery costs 69 UAH. What can you conclude?

## Ahead and behind

**Sofia:** Ahead and behind... compared with what?

**Alex Tutor:** With the default branch. **Ahead** counts the commits the branch has and `main` doesn't: Daniel's two. **Behind** counts the commits `main` has and the branch doesn't: the cat treats bundle.

**Sofia:** So ahead is the work waiting to be merged, and behind is how far `main` has moved on without the branch.

**Alex Tutor:** Exactly. A big ahead number means a large change that someone will have to review. A big behind number means the branch was built on an old version of the project.

**Daniel:** Behind isn't a disaster. I can bring fresh `main` into my branch whenever I want. But the longer I wait, the more surprises pile up.

> **Exercise:** What will GitHub show for `feature/subscription` compared with `main`?

## The branches page: active and stale

**Alex Tutor:** Next to the selector there is a branch counter. Click it, or `View all branches` inside the selector, and you get the branches page: every branch with its last update, its behind and ahead numbers and its pull request.

**Alex Tutor:** The page sorts branches into tabs. `Active` holds branches with recent commits. `Stale` holds the ones that haven't had a commit for about three months.

```text
Branches of catchow/website
- [Branch] main: Default branch. Updated yesterday
- [Branch] feature/free-delivery-1000: Updated 3 hours ago · 0 behind, 3 ahead
- [Branch] fix/checkout-button: Updated yesterday · 1 behind, 2 ahead
- [Branch] content/delivery-copy: Updated last week · 2 behind, 1 ahead
- [Branch] feature/loyalty-points: Updated 5 months ago · 86 behind, 12 ahead
```

**Sofia:** `content/delivery-copy` is Emma's! So our content marketer did move her texts into the repository.

**Alex Tutor:** Your note from module 1 worked. Now look at the last row.

**Sofia:** `feature/loyalty-points`: twelve commits ahead, 86 behind, untouched for five months. Is that an abandoned project?

**Daniel:** Paused, officially. Honestly, it's abandoned. Merging it now would hurt: `main` has changed too much since then.

**Alex Tutor:** For a PM a stale branch is a question worth asking: is this work still planned? If not, the team can delete the branch and close the topic.

![An overgrown side track with weeds and a dusty abandoned carriage sits far behind a busy main line where new trains keep passing.](https://productovi.com/courses/git-for-product/inline/branches-illustration-3.webp)

*A stale branch is a product question: is this work still planned?*

> **Exercise:** Which of these branches will GitHub list under `Stale`? Select all that apply.

## Branch naming conventions: what a name tells you

**Sofia:** The names follow a pattern: `fix/`, `feature/`, `content/`. Is that a GitHub rule?

**Daniel:** No, a team habit. The prefix says what kind of work it is, the rest says what it's about. Lowercase, hyphens instead of spaces. Git itself allows almost any name.

**Daniel:** You'll meet other styles too: an issue number up front, like `131-checkout-button`, or the author's name, like `daniel/checkout-button`. And names GitHub generates itself, such as `revert-97-feature/checkout-redesign`.

**Sofia:** That last one is your ten-minute rescue from March, isn't it?

**Daniel:** Guilty. The `Revert` button created that branch for me.

**Alex Tutor:** One more pattern for later: the prefixes `hotfix/` and `release/` belong to git flow, a workflow we'll compare with ours in module 4.

> **Exercise:** Match each branch name with what it most likely tells you.

**Alex Tutor:** Now flip it around: given a task, pick the name.

> **Exercise:** Support reports a bug: the promo code field rejects codes with spaces. Daniel will fix it. Which branch name fits CatChow's habits best?

## A short life and a quiet end

**Alex Tutor:** Healthy branches live for days, not months. One branch, one task: start from fresh `main`, make a few commits, open a pull request, merge, delete.

**Sofia:** Delete? After all that work?

**Alex Tutor:** Deleting a branch removes the name, not the work. Once the changes are merged, they live in `main`. The branch name was only a pointer, and its task is finished.

![A healthy branch starts from fresh main, gets a few commits, goes through a pull request, is merged and deleted: the name goes, the work stays in main.](https://productovi.com/courses/git-for-product/diagrams/m2-l1-branch-lifecycle.png)

![A worker pulls a small signpost out of the ground where a side path has joined a wide paved road; the road carries on intact.](https://productovi.com/courses/git-for-product/inline/branches-illustration-4.webp)

**Alex Tutor:** After a merge GitHub offers a `Delete branch` button on the pull request page. And if someone needs the branch back, the same page has `Restore branch`.

**Daniel:** Many teams switch on automatic deletion of merged branches in the repository settings. We did. Otherwise the branch list turns into an attic.

> **Exercise:** The pull request is merged, and Daniel clicks `Delete branch`. What happens to the fix from commit f1?

## Daniel's confession

**Alex Tutor:** Time for Daniel's confession, with a graph. This is March: `main` on the left, his redesign branch on the right.

```text
Commit graph, oldest first: March: the checkout redesign before the merge
1. commit 4d2a8e1 on main "Add order tracking link"
2. branch feature/checkout-redesign starts from commit 4d2a8e1
3. commit 61b9f3c on feature/checkout-redesign "New checkout button styles"
4. commit d18e6a0 on main "Add cookie notice bar (#95)" (highlighted)
5. commit 92c4b1f on feature/checkout-redesign "Move button to sticky footer"
6. commit 0a7f5e3 on feature/checkout-redesign "Update button texts"
```

*The branch is 3 commits ahead of main and 1 behind: it does not have the cookie notice bar.*

**Daniel:** I branched off, made three commits and tested everything on my branch. Meanwhile a colleague's cookie notice bar was merged into `main`. My branch was one commit behind, and I never looked.

**Sofia:** So you tested a version of the site that had your new button but no cookie bar.

**Daniel:** Exactly. After the merge, `main` had both for the first time. On phones the bar sat right on top of my button, and nobody could tap it. Hence the revert.

**Alex Tutor:** Git had no objections, because the two branches changed different files. That's why "behind" deserves a glance before a merge, and why short-lived branches are safer.

**Daniel:** The redesign went back in a few days later, from a branch updated with fresh `main`. It has worked ever since.

> **Exercise:** Which statements about this graph are true? Select all that apply.

## Explain it to support

**Alex Tutor:** Last task. Support writes: "Daniel says the checkout fix is ready, and I can see his commits on GitHub. Why do customers still get a grey button?"

**Sofia:** Because the commits sit on `fix/checkout-button`, two ahead of `main`, and the site shows `main`.

**Alex Tutor:** Now say that without the words "branch" and "commit". Two or three sentences that a support agent can pass on.

**Daniel:** And don't promise a date. The fix still has to pass review.

> **Exercise:** Support asks: "Daniel says the checkout fix is ready, and I can see his commits on GitHub. Why do customers still get a grey button?" The fix is on `fix/checkout-button`, 2 commits ahead of `main`, and not merged yet. Write a 2–3 sentence answer for support without Git jargon.

**Alex Tutor:** Next lesson: what exactly happens when a branch is merged, and why GitHub's merge button has three options.

**Sofia:** Three ways to press one button. Of course.

- Previous lesson: [Reading history: messages, diffs and blame](https://productovi.com/courses/git-for-product/reading-history-diffs-and-blame.md)
- Next lesson: [Merging on GitHub: merge commit, squash and merge, rebase](https://productovi.com/courses/git-for-product/merging.md)

---
Productovi Learning. Free, no sign-up needed to read.
