Creating, Switching, and Deleting Branches

8 min read

The previous lesson was about what a branch is. This one is about the four things you'll actually do with one — create it, switch to it, rename or delete it. There are old commands (git checkout) and new ones (git switch) that do the same job; you'll meet both in any team because the old ones still work and people's muscle memory dies hard. By the end of this lesson, branching will feel like a five-second operation.

Creating a branch

The fundamental command:

git branch feature/login-tests

This creates a new branch called feature/login-tests pointing at the commit you're currently on. It does not switch to it — you're still on main.

git branch
  feature/login-tests
* main

The asterisk is still on main. The new branch exists but you're not standing on it yet.

Switching branches

Two commands do the same thing — modern Git split checkout into two narrower commands (switch for branches, restore for files) because checkout was overloaded.

Modern (preferred):

git switch feature/login-tests

Old (still works everywhere):

git checkout feature/login-tests

Either way:

Switched to branch 'feature/login-tests'
git branch
* feature/login-tests
  main

The asterisk moved. Your working directory now reflects the contents of feature/login-tests — same files for now (the branch was just created), but every commit you make from here lives on this branch, not on main.

Create AND switch in one step

The most common move: make a branch and immediately start working on it. Two equivalent shortcuts:

# Modern
git switch -c feature/login-tests
 
# Old, still in every example you'll read online
git checkout -b feature/login-tests

The -c (create) and -b (branch) flags say "make this branch and switch to it." Use whichever feels natural — they produce identical results.

Branch naming conventions

Branch names are visible to your whole team for the lifetime of a PR. Treat them like filenames in a shared folder. Most teams use a prefix/short-description pattern:

PrefixUsed forExample
feature/New features or test suitesfeature/checkout-regression-tests
bugfix/Fixing a defectbugfix/flaky-login-on-firefox
test/Test-only work (fixtures, framework)test/upgrade-cypress-to-13
chore/Maintenance, dependency bumpschore/bump-node-to-20
hotfix/Urgent production fixeshotfix/disable-broken-payment-test

Mechanical rules:

  • Lowercase, hyphens, no spaces. feature/login-tests, not Feature/Login Tests or feature_login_tests.
  • Short but specific. feature/search is too vague; feature/search-fuzzy-matching-tests reads itself.
  • No issue numbers buried mid-name. feature/JIRA-1234-fix-search is fine; feature/fix-JIRA-1234-search puts the noise in the middle.

A complete walkthrough

Watch the asterisk move as you go. Starting on main:

git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

Create and switch to a branch:

git switch -c feature/search-tests
Switched to a new branch 'feature/search-tests'

Confirm:

git branch
* feature/search-tests
  main

Do some work and commit:

echo "describe('search', () => {})" > tests/search.spec.js
git add tests/search.spec.js
git commit -m "Scaffold search test file"
[feature/search-tests 3a7b2c1] Scaffold search test file
 1 file changed, 1 insertion(+)
 create mode 100644 tests/search.spec.js

Switch back to main:

git switch main
Switched to branch 'main'
ls tests/

search.spec.js is gone. It still exists — but only on the feature/search-tests branch. On main, it never existed. Switch back and it returns:

git switch feature/search-tests
ls tests/
search.spec.js

That's the magic of branches: the file system reflects whichever branch you're on, instantly.

Deleting branches

Once a branch has been merged to main, delete it. Lingering branches clutter git branch -a and confuse new joiners.

Safe delete (refuses if there are unmerged commits):

git branch -d feature/search-tests
Deleted branch feature/search-tests (was 3a7b2c1).

Force delete (discards unmerged work — use with care):

git branch -D feature/abandoned-experiment

The capital -D says "I know this has unmerged commits, throw them away anyway." Reserve it for genuine throwaways.

You can't delete the branch you're currently on — switch off it first.

Delete the branch on the remote too. Local delete only removes your local copy; the GitHub branch keeps existing.

git push origin --delete feature/search-tests
To github.com:acme/webapp-tests.git
 - [deleted]         feature/search-tests

Renaming a branch

If you misspelled the branch name or the scope changed:

git branch -m feature/serach-tests feature/search-tests

-m means move. Drop the first argument to rename the current branch.

The full create-switch-delete cycle

Step 1 of 6

Start on main

git switch main && git pull — make sure you branch from the latest code, not yesterday's.

⚠️ Common mistakes

  • Forgetting to switch after creating. git branch foo makes the branch but leaves you on the old one. Your next commit lands where you didn't intend. Use git switch -c foo (or git checkout -b foo) unless you have a specific reason to create without switching.
  • Branching from a stale main. If you don't git pull first, you branch from yesterday's code. Two days later your "fresh" branch is already behind. Make git switch main && git pull the first two commands every time you start new work.
  • Force-deleting (-D) when you meant safe-delete (-d). Capital -D discards unmerged commits forever. If you typo'd a D and the branch had unique work, that work is gone. Default to lowercase -d and only escalate when Git tells you the branch is unmerged and you're sure.

🎯 Practice task

Make and unmake several branches. 20-25 minutes. Use the qa-sandbox repo from Chapter 1, or any practice repo you don't mind churning.

  1. On main, create three branches in different ways:
    • git branch feature/login-tests (create only)
    • git switch -c feature/search-tests (create + switch)
    • git checkout -b feature/checkout-tests (create + switch, old syntax)
  2. Run git branch after each. Track which one has the asterisk.
  3. On feature/search-tests, create a file tests/search.spec.js, commit it, then switch to main. Confirm the file disappears (ls tests/). Switch back — confirm it returns.
  4. Switch to main and run git branch -d feature/login-tests. Safe delete works because the branch had no unique commits.
  5. Try git branch -d feature/search-tests. Git refuses — that branch has unmerged work. Read the error carefully; it tells you to use -D to force.
  6. Force-delete it: git branch -D feature/search-tests. The branch and its commit are gone.
  7. Stretch: rename feature/checkout-tests to test/checkout-suite with git branch -m feature/checkout-tests test/checkout-suite. Confirm with git branch.

You can now create, switch between, and delete branches with confidence. The next lesson is the part where two branches need to come back together — merging.

// tip to track lessons you complete and pick up where you left off across devices.