2.4 Branches, HEAD, and the Default Branch

Key Takeaways

  • A Git branch is a line of development; its tip is the latest commit on that line, and creating a branch is cheap (a movable pointer to a commit).
  • HEAD is the pointer to the current branch (or a detached commit if you check out a SHA that is not a branch tip).
  • GitHub has used main as the default branch name for new repositories since October 2020; the name is configurable, and existing repositories may still use master or another name.
  • Merge combines two lines and can create a merge commit that preserves both histories; rebase replays commits onto a new base and rewrites SHAs, so you do not rebase branches other people already use.
  • GitHub Flow depends on short-lived branches: create a branch from the default branch, commit, open a pull request, merge, then delete the feature branch.
Last updated: August 2026

A branch is a line of development. Git's glossary is precise: the most recent commit on a branch is the tip; that tip is referenced by a branch head, which moves forward as you commit. A repository can track many branches, but your working tree is associated with just one at a time — the current or checked-out branch. HEAD is the pointer to that current branch (or, in a special case, directly to a commit).

This is the second half of GH-900's compound Domain 1 bullet on repositories, commits, and branches. You cannot explain GitHub Flow, pull requests, or protected branches until you can explain a branch.

Why branches exist

GitHub Docs: branches let you develop features, fix bugs, or experiment in a contained area of the repository. You always create a branch from an existing branch, typically the default branch. Work on the new branch does not change the default branch until you merge (usually through a pull request).

A branch you create to build a feature is a feature branch or topic branch. GitHub flow guidance: use a short, descriptive name (increase-test-timeout, add-code-of-conduct) and a separate branch for each set of unrelated changes. That isolation is what makes review, revert, and CI tractable.

Creating a Git branch is cheap: Git writes a small ref (a name that points at a commit SHA). It does not copy the whole project. That is why teams create many short-lived branches instead of long-lived "dev copies" of the repo.

HEAD versus a branch head

Two similar words:

  • A head (lowercase in Git's glossary) is a named ref at refs/heads/<name> pointing at the tip commit of a branch (main, fix-timeout).
  • HEAD (uppercase) is the current branch. Your working tree is normally derived from the tree HEAD refers to. HEAD is a symbolic ref: it usually contains ref: refs/heads/main, not a raw SHA.

When you git switch feature-a (or git checkout feature-a), HEAD now points at feature-a. New commits advance feature-a's tip and move HEAD with it.

Detached HEAD means you checked out a commit that is not the tip of a branch (for example git checkout a1b2c3d to inspect history). New commits would not belong to any branch name unless you create one. GH-900 depth: know that detached HEAD is "not on a branch," which is why Git warns you. Day-to-day GitHub Flow stays on named branches.

PointerWhat it namesMoves when you commit?
Branch (main, feature-a)Tip commit of that lineYes, if that branch is checked out
HEADThe current branch (or a detached commit)Yes; it follows the current branch
TagA (usually) fixed commit, often a releaseNo, not by git commit

The default branch, and why it is often main

When you create a repository with content on GitHub, GitHub creates it with a single branch. That first branch is the default branch. GitHub Docs: the default branch is what GitHub displays when anyone visits the repository; it is the branch Git checks out locally on clone; and unless you specify otherwise, it is the base branch for new pull requests and code commits.

By default, GitHub names the default branch main in any new repository. GitHub switched new repositories from master to main in 2020 (announced 1 October 2020). The name is configurable:

  • Per repository: Settings → Default branch (requires admin; the repo must already have more than one branch to change which branch is default).
  • Per user or organization: default name for new repositories.
  • Enterprises can enforce a default-branch-name policy.

GH-900 traps:

  • The default branch is not required to be named main. Older repos, mirrors, and teams that opted out may still use master, trunk, or develop.
  • Git's own historical default when you git init locally was master; GitHub.com's default for new hosted repos is main. Do not claim Git itself renamed every repo in 2020.
  • Existing repositories were not bulk-renamed. Renaming master to main is a separate, explicit operation (and it updates pull request targets and some links).
  • "Default branch" is a role, not a magic name. Branch protection, GitHub Pages, and Actions on: push to the production line usually target that role.

Merge versus rebase (GH-900 conceptual depth)

You eventually combine a feature branch with the default branch. Two strategies:

MergeRebase
What it doesCombines two lines. If histories diverged, Git creates a merge commit with two parents. If the feature branch is a fast-forward, Git may just move the pointer.Replays your commits onto a new base, producing new commits with new SHAs.
History shapePreserves the exact parallel work (a join in the graph).Linear history along the new base.
SHA stabilityExisting feature commits keep their SHAs (non-rebase merge).Feature commits are rewritten.
Shared branchesSafe default for integrating through a pull request.Do not rebase a branch other people already based work on.

GitHub pull requests typically merge (merge commit, squash merge, or rebase-and-merge are GitHub options — the last two are rewrites of the PR's commits onto the base). For GH-900, remember: merge keeps both histories; rebase rewrites. Rebase is a cleanup tool for your unshared branch, not a way to "fix" main.

A fast-forward is a merge where the target has no unique commits: Git just moves the branch pointer. No merge commit is created. git pull is fetch plus merge (unless you configure pull to rebase).

Why branches enable GitHub Flow

GitHub Flow is a lightweight, branch-based workflow. GitHub uses it for code, docs, and even site policy. The loop is:

  1. Create a branch from the default branch (a safe workspace).
  2. Commit on that branch until the change is ready.
  3. Open a pull request to propose the branch for review (GitHub, not Git).
  4. Address review; checks run against the branch's commits.
  5. Merge into the default branch.
  6. Delete the feature branch. History remains in the pull request and in main.

Without cheap branches, that loop cannot exist: you would commit straight to main (unsafe) or copy the whole project (slow). Branch protection then enforces that main only moves through pull requests.

GitHub Flow is not Git Flow (the heavier model with long-lived develop, release/*, and hotfix/* branches). GH-900 names GitHub Flow. If a stem mentions develop and release as required, that is the other model.

Scenario: shipping a timeout fix

The default branch is main. You git switch -c increase-test-timeout from main. HEAD now points at increase-test-timeout. Commits stay off main. You push the branch and open a pull request. Reviewers comment; you add commits; the PR updates. After approval, you merge to main and delete increase-test-timeout. main is the default branch; HEAD on your laptop should switch back to main and pull. That entire story is why GH-900 treats branches, HEAD, and the default branch as one skill.

Loading diagram...
GitHub Flow depends on a default branch plus a short-lived feature branch
Test Your Knowledge

In Git, what does HEAD represent while you are working on a named feature branch?

A
B
C
D
Test Your Knowledge

Which statement about GitHub's default branch is accurate for GH-900?

A
B
C
D
Test Your Knowledge

A teammate wants a linear history on their unshared feature branch before opening a pull request. Another teammate wants to integrate a reviewed feature into main without rewriting commits other people already pulled. Which pair matches merge versus rebase at GH-900 depth?

A
B
C
D