skip to content

questions

5

In Git, what does creating a branch with git branch feature actually do?

level: juniorimportance: must knowfreq 82%

answer

  1. Think about how much data is written
  2. Measure it in bytes, not megabytes
  3. It stores one commit hash
  4. HEAD does not move

basics

~20 s

It writes one new ref holding the hash of the commit you branched from. No files are copied and no history is duplicated, which is why branching is instant in a repository of any size.

solid answer

~40 s

`git branch feature` creates a single reference: a name under `refs/heads/` whose value is the commit hash that `HEAD` currently resolves to. In a fresh repository that is literally a file, `.git/refs/heads/feature`, containing the hash plus a newline — roughly 41 bytes. Nothing else changes: no objects are written, no working-tree files are touched, and `HEAD` still points at the branch you were on, so `git branch feature` does **not** switch you to it. Use `git switch -c feature` (or the older `git checkout -b feature`) to create and switch in one step. Committing on a branch moves that one ref forward to the new commit; the commit itself records its parent, so the branch name is just a movable label on the commit graph, not a container of commits.

code

bash · 6 lines
bash
git branch feature
cat .git/refs/heads/feature
# 9f2b6c1a... (one commit hash plus a newline)
git rev-parse feature HEAD
# both print the same hash: creating a branch did not move HEAD
git switch -c feature2   # create AND switch in one step

go deeper

for a junior

Be able to say a branch is a pointer to a commit, and that git branch <name> creates it without switching. Know git switch -c <name> as the create-and-switch command.

for a middle

Explain what is written on disk — one ref under refs/heads/ containing a commit hash — and how committing rewrites that ref to the new commit while HEAD stays attached to the branch.

for a senior

Show that you reason about refs when things go wrong: compare git rev-parse output across names, know that commits are reachable from many branches or none, and that branch names carry no ownership of history.

for a principal

Frame cheap branching as the property that makes short-lived branches, per-task isolation, and disposable experiments affordable, and be ready to say where branch proliferation stops being free — in review load and integration lag, not in Git.

## The one-sentence model A Git branch is a **named pointer to a single commit**. It is not a copy of the code, not a directory of changes, and not a container that "holds" commits. The commit graph exists independently in the object database; a branch is one mutable name attached to one node in that graph. ## What the command writes When you run `git branch feature`, Git resolves the start point (by default whatever `HEAD` currently points to), verifies it is a commit, and records that commit's hash under the name `refs/heads/feature`. In a repository whose refs are unpacked, this is a plain text file at `.git/refs/heads/feature` containing the 40 hex characters of the hash and a trailing newline. Git may also store refs in a packed form or in an alternative ref backend; either way the logical content is the same — one name, one hash. You can create a branch pointing anywhere, not just at `HEAD`: - `git branch feature <commit>` — start from an explicit commit, tag, or another branch name. - `git branch -f feature <commit>` — move an existing branch to a different commit (dangerous if someone is standing on it). Because the operation writes one small ref, it is O(1). This is the concrete reason "branching is cheap in Git" — a claim interviewers like to hear justified rather than repeated. ## What the command does not do `git branch feature` does not change `HEAD`, does not touch the index, and does not modify a single file in your working tree. Candidates who create a branch, keep committing, and then find their commits on the old branch have usually missed exactly this. The switching commands are separate: - `git switch feature` — move `HEAD` to point at the existing branch and update the working tree to match. - `git switch -c feature` / `git checkout -b feature` — create it and switch in one step. ## How committing moves it When `HEAD` points at `refs/heads/feature` and you commit, Git writes a new commit object whose parent is the old tip, then rewrites `refs/heads/feature` to the new commit's hash. That is the whole of "the branch advanced". The previous commit is untouched and still reachable through the new commit's parent link. Because `HEAD` is normally a symbolic reference to a branch, the phrase "the current branch" simply means "the branch `HEAD` names". ## Consequences worth stating in an interview **Deleting a branch does not delete commits.** It removes one name. The commits stay in the object database until they become unreachable and are eventually pruned by garbage collection. **Two branches at the same commit are indistinguishable in content.** `main` and `feature` pointing at the same hash means both names describe the same snapshot and the same history; nothing is duplicated on disk. **"Which branch is a commit on?" is the wrong question.** A commit is reachable from zero or many branches. `git branch --contains <commit>` answers the reachable-from question, which is what people usually mean. **Cheap branching drives Git workflow.** Because a branch costs a ref, creating one per task, per experiment, or per bug reproduction is normal, and throwing branches away is equally cheap. ## Inspecting it `git rev-parse feature` prints the commit a branch resolves to. `git branch -v` lists branches with their tip commit and subject. `git branch --show-current` prints the name `HEAD` is attached to. These are the checks to run when someone insists their branch "lost" work: compare the hashes, and you almost always find the commits are still there under a different name or in the reflog. ## Common confusion: branches versus tags A lightweight tag is also a name pointing at a commit, but tags are meant to stay put while branches are meant to move. Committing while on a branch advances the branch; nothing advances a tag. If you remember "branch = moving label, tag = pinned label", most of the surface behavior follows.

  • If a branch is just a pointer, what makes the history under it?
    Each commit object records its own parent (or parents). The branch names one tip commit; walking parent links from there produces the history. Git reconstructs "the commits on this branch" by traversal at read time — nothing is stored per branch.
  • What happens to the commits when you delete a branch?
    Nothing immediately. Removing `refs/heads/feature` removes one name; the commit objects remain in the object database and can still be recovered through the reflog while their entries survive. They are only discarded once they are unreachable and garbage collection runs.
  • Why does git branch feature not switch you to the new branch?
    `git branch` only writes refs; it never touches `HEAD` or the working tree. Switching is a separate operation because it has to update the index and files on disk. `git switch -c feature` combines both, which is why it is the usual command.

A branch is a sticky note with a commit's address on it, not a photocopy of the building. Moving the note is instant; the building never moves.

saying these in an interview costs you the question

  • Says a branch stores a copy of the files
  • Thinks git branch also switches to the new branch
  • Claims deleting a branch deletes its commits
  • Believes each commit belongs to exactly one branch
  • Says branching a large repository is slow or expensive

context

open as a page

In Git, what is a detached HEAD and how do you rescue commits made in one?

level: middleimportance: must knowfreq 68%

basics

~20 s

HEAD is detached when it names a commit directly instead of a branch, so commits you make advance nothing. Rescue them by creating a branch at that commit — git switch -c <name> before leaving, or git branch <name> <hash> from the reflog afterwards.

open as a page

In Git, what is the difference between git branch -d and git branch -D?

level: juniorimportance: should knowfreq 58%

basics

~20 s

git branch -d refuses to delete a branch whose commits are not already merged into its upstream or into HEAD; git branch -D is the forced form that deletes regardless. Both only remove the ref, never the commits.

open as a page

In Git, how does git switch differ from git checkout for changing branches?

level: middleimportance: should knowfreq 50%

basics

~20 s

git switch only moves HEAD between branches or commits; git checkout does that plus restoring files from a commit into the index or working tree. Switch was added with git restore to split one overloaded command into two focused ones.

open as a page

In Git, how do you list which branches are already merged into main before deleting them?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Use git branch --merged main to list branches whose tips main can reach, and --no-merged main for the rest. The test is pure reachability, so squashed or rebased work shows as unmerged; git cherry compares by patch instead.

open as a page