WierdX — Programming Reference All tutorials →
Developer reference · Practical tutorials · CS fundamentals
Version Control

Git Branching Basics

Branches are how you work on something without breaking what already works. Understanding how Git tracks them — and when to merge versus rebase — is a foundation skill for any developer.

Published April 12, 2026

A branch in Git is nothing more than a lightweight movable pointer to a commit. When you create a branch, Git isn't copying your codebase — it's just creating a new label that points at the current commit. This makes branches nearly instant to create and free in terms of storage.

The basic commands

# Create a new branch and switch to it
git switch -c feature/user-login

# List branches (* marks current)
git branch

# Switch to an existing branch
git switch main

# Delete a branch after merging
git branch -d feature/user-login

The older git checkout -b syntax does the same thing as git switch -c. Both are valid; switch is cleaner in intent since it doesn't double as a file-restore command.

What a branch actually is

Every commit in Git stores a pointer to its parent commit. A branch is a named reference to one commit in this chain. HEAD is a special pointer that tracks which branch (or commit) you're currently on. When you commit on a branch, Git creates a new commit with the current commit as parent, then moves the branch pointer forward to the new commit.

This is why branching is "cheap" in Git but was expensive in older VCS systems like SVN, which copied files to a branch directory.

Merging branches

When your feature is done, you integrate it back into the main line with git merge:

git switch main
git merge feature/user-login

If main hasn't changed since you branched, Git does a fast-forward merge — it simply moves the main pointer forward to the tip of your branch. No new commit is created; the history is linear.

If main has moved on, Git creates a merge commit with two parents. This preserves the exact history of both lines of development. You can see both branches in git log --graph.

Rebase: rewriting history

Rebasing replays your commits on top of another branch, rewriting them with new parent pointers:

git switch feature/user-login
git rebase main

The result looks as if you started your work from the current tip of main, giving you a clean, linear history when you eventually merge. The trade-off: rebasing rewrites commit hashes. The golden rule is never rebase commits that have been pushed to a shared remote — it forces collaborators to reconcile diverged histories.

Use merge when you want to preserve the branching history exactly. Use rebase when you're cleaning up a local branch before sharing it, or want a linear history that's easier to read with git log.

Common branching strategies

GitHub Flow (recommended for most teams): keep main always deployable. All work happens on short-lived feature branches. Open a pull request to merge back to main, delete the feature branch after merging. Simple and effective for continuous deployment.

Git Flow: uses long-lived develop and main branches, plus feature/, release/, and hotfix/ branch types. More structure, more overhead. Useful for teams that ship versioned releases on a schedule rather than continuously.

Trunk-based development: everyone commits directly to main (or merges very short-lived branches daily). Requires feature flags to hide incomplete work. Favoured by high-velocity teams who want to minimise merge conflicts.

Resolving merge conflicts

When two branches change the same part of the same file, Git can't automatically decide which version to keep. It marks the conflict in the file:

<<<<<<< HEAD
return user.email
=======
return user.username
>>>>>>> feature/user-login

You edit the file to the correct state, removing the markers, then stage and commit:

git add src/auth.py
git commit    # Git pre-fills a merge commit message

The best way to minimise conflicts is to keep branches short-lived (days, not weeks) and sync with main frequently by merging or rebasing.

Practical habits

Name branches clearly: feature/, fix/, chore/ prefixes help at a glance. Keep feature branches focused on one thing. Delete them after merging — stale branches accumulate and become confusing. Use git log --oneline --graph --all regularly to understand where all branches stand.