Working Code
Example 1: Creating and switching branches
Start with a repository that has a commit:
git init
echo "# Project" > README.md
git add README.md
git commit -m "feat: initial commit"
Check the current branch:
git branch
Output:
* main
The * marks the current branch.
Create a new branch:
git branch feature-login
git branch
Output:
feature-login
* main
The branch is created but you're still on main. Switch to it:
git checkout feature-login
git branch
Output:
* feature-login
main
Example 2: Working on a branch
Add a file on feature-login:
echo "// Login feature" > login.js
git add login.js
git commit -m "feat: add login feature"
Switch back to main and login.js is gone:
git checkout main
ls
Output:
README.md
Branches are completely independent workspaces.
Example 3: Visualizing branch history
git log --oneline --graph --all
Output:
* a1b2c3d (feature-login) feat: add login feature
* e4f5g6h (HEAD -> main) feat: initial commit
--all shows commits from all branches. --graph draws the structure in ASCII.
Try It Yourself
Create and switch in one step
# git branch + git checkout in one command
git checkout -b feature-signup
git branch
Output:
feature-login
* feature-signup
main
Work on multiple branches:
# Work on feature-signup
echo "// Signup" > signup.js
git add signup.js
git commit -m "feat: add signup page"
# Switch to feature-login
git checkout feature-login
# Update login.js
echo "// Login complete" >> login.js
git add login.js
git commit -m "feat: complete login form"
Compare branches:
git log --oneline --graph --all
Output:
* f7g8h9i (feature-signup) feat: add signup page
| * j0k1l2m (feature-login) feat: complete login form
| * a1b2c3d feat: add login feature
|/
* e4f5g6h (HEAD -> main) feat: initial commit
The branching structure is clearly visible.
Deleting branches
# Switch to main first, then delete
git checkout main
git branch -d feature-signup
Output:
Deleted branch feature-signup (was f7g8h9i).
Deleting an unmerged branch:
git branch -d feature-unmerged
# error: The branch 'feature-unmerged' is not fully merged.
# Force delete (use with caution!)
git branch -D feature-unmerged
"Why?" -- Why branches matter
Without branches:
- You're stuck when a critical bug fix is needed while developing a new feature
- Multiple people editing the same file leads to conflicts
- Experimental changes risk breaking existing code
Branches provide independent workspaces:
main (stable, deployable)
|-- feature/login <- Login feature development
|-- feature/signup <- Signup feature development
+-- fix/typo <- Typo fix
Branches as pointers
A branch is just a pointer (label) to a specific commit. Creating a branch simply creates a new pointer, making it extremely lightweight.
Commit A <- Commit B <- Commit C
^
main (pointer)
Commit A <- Commit B <- Commit C <- Commit D (feature work)
^ ^
main feature-login (new pointer)
HEAD points to the branch/commit you currently have checked out:
Commit C <- Commit D
^
feature-login <- HEAD
Common Mistakes
Mistake 1: Switching branches without committing
echo "Work in progress" > file.txt
git checkout main # Warning or changes may carry over
# Safe approach: commit or stash before switching
git add file.txt
git commit -m "wip: save work in progress"
git checkout main
Or:
git stash # Temporarily save (covered in Lesson 8)
git checkout main
Mistake 2: Developing features directly on main
# Bad habit
git checkout main
echo "New feature" > feature.js
git commit -m "feat: new feature" # Committed directly to main
# Good habit
git checkout -b feature/new-feature
echo "New feature" > feature.js
git commit -m "feat: new feature" # Committed to a feature branch
Mistake 3: Spaces in branch names
# Wrong
git checkout -b "my feature branch"
# Correct: use hyphens or slashes
git checkout -b feature/my-feature
git checkout -b my-feature-branch
Deep Dive
Modern approach: git switch
Since Git 2.23, there's a dedicated branch-switching command called switch:
# Switch branches
git switch feature-login
# Create and switch in one step
git switch -c feature-new
# Return to main
git switch main
checkout is overloaded -- it handles both branch switching and file restoration. switch is dedicated to branch switching, making intent clearer.
Branch naming conventions
Conventions vary by team, but common patterns include:
feature/feature-name-- New featuresfix/bug-description-- Bug fixeshotfix/urgent-fix-- Production hotfixesrelease/version-- Release preparationchore/task-description-- Build, config, and other maintenance
Using slashes (/) for grouping displays branches as a tree in Git tools.
Examples:
feature/user-login
feature/payment-integration
fix/cart-item-count-bug
hotfix/security-patch
Customizing git log
# Detailed graph options
git log --oneline --graph --all --decorate
# Include dates
git log --oneline --format="%h %ai %s" --all
# Register as an alias for convenience
git config --global alias.lg "log --oneline --graph --all --decorate"
git lg # Now you can use the short form
- Create a repository and make 2 commits on main.
- Create a branch with
git checkout -b feature-about. - On feature-about, create
about.htmland commit it. - Switch back with
git checkout mainand runlsto confirmabout.htmlis gone. - Run
git log --oneline --graph --allto see the branch structure.
Q1. Which two commands are equivalent to git checkout -b feature-login?
- A)
git branch feature-login+git merge feature-login - B)
git create feature-login+git switch feature-login - C)
git branch feature-login+git checkout feature-login - D)
git init feature-login+git checkout feature-login