Free Ebook cover Git for Programmers: Version Control for Small Projects

Git for Programmers: Version Control for Small Projects

New course

7 pages

Branching in Git for Small Features: Isolated Changes and Faster Reviews

Capítulo 4

Estimated reading time: 6 minutes

+ Exercise

Branches as Lightweight Pointers (Why They’re Cheap and Useful)

A Git branch is a movable pointer to a commit. Creating a branch does not copy files or duplicate your project; it simply creates a new name that points at the current commit. As you commit on that branch, the pointer moves forward. This makes branches ideal for small projects: you can isolate a small feature or fix without disturbing main, and you can review changes as a focused series of commits.

What “isolated changes” means in practice

  • main stays stable: you can keep running the app from main while experimenting elsewhere.
  • Reviews are faster: a feature branch can be compared directly to main to see exactly what changed.
  • Context switching is easier: you can pause a feature and switch back to main for a quick hotfix.

Viewing and Switching Branches

List branches

git branch

The current branch is marked with *. If you want to see the last commit on each branch:

git branch -v

Switch branches

git switch main

If you’re used to older commands, git checkout can also switch branches, but git switch is clearer for day-to-day branching workflows.

Creating a Feature Branch from main

A common small-project workflow is: keep main releasable, and do each change (feature, fix, maintenance) on its own branch.

Start from a clean main

git switch main
git status

You want a clean working tree (no uncommitted changes) before branching, so the branch starts from a known point.

Continue in our app.

You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.

Or continue reading below...
Download App

Download the app

Create and switch to a new branch

git switch -c feature/add-config-loader

This creates the branch at the current main commit and switches to it immediately.

Meaningful branch names (small project friendly)

Use a short prefix to communicate intent. This helps even if you’re the only developer, because it keeps your local branch list readable.

  • feature/... for user-visible or functional additions
  • fix/... for bug fixes
  • chore/... for maintenance (refactors, tooling, formatting, dependency bumps)

Good examples:

  • feature/export-csv
  • fix/null-user-crash
  • chore/update-eslint

Avoid vague names like test, stuff, or new—they make it harder to understand what’s safe to delete or merge later.

Making a Sequence of Small Commits on the Branch

On a feature branch, aim for 2–3 commits that each represent a coherent step. This makes review and debugging easier than one large commit.

Example commit breakdown

  • Commit 1: add the new module/function with minimal integration
  • Commit 2: wire it into the app and update configuration
  • Commit 3 (optional): add tests and small cleanup

As you work, keep checking what will be committed:

git status

Stage and commit each step when it’s internally consistent:

git add path/to/file1 path/to/file2
git commit -m "Add config loader module"

Repeat for the next step(s):

git add path/to/integration-file
git commit -m "Wire config loader into startup"
git add path/to/tests
git commit -m "Add tests for config loader"

Comparing Branches (What Changed vs main)

Before merging, you’ll often want to answer two questions: “What commits are on my branch that aren’t on main?” and “What file changes will be introduced?”

Compare commit history

Show commits that are on feature/add-config-loader but not on main:

git log main..feature/add-config-loader

This is useful for checking that your branch contains only the intended commits (no accidental work).

Compare file changes

See the net diff your branch introduces compared to the common base with main:

git diff main...feature/add-config-loader

The triple-dot form (main...feature) compares your branch to the merge base (the point where the branch diverged). This is usually what you want when preparing a merge, because it shows the changes introduced by the branch itself.

When to Branch vs Commit Directly to main

For small projects, branching is still valuable, but you don’t need ceremony for every change. Use this rule of thumb.

Branch when…

  • The change spans multiple commits or will take more than a few minutes.
  • You might abandon or rework the change after trying it.
  • You want a clean reviewable unit (even if you’re reviewing your own work later).
  • The change could break the build temporarily while you iterate.

Commit directly to main when…

  • The change is tiny and low risk (e.g., a one-line typo fix) and you can keep main working.
  • You’re doing an immediate, obvious fix and you don’t need a separate review unit.

Even then, if you’re unsure, branching is cheap: creating a branch is fast and keeps options open.

Hands-On Flow: From Clean main to Merge-Ready Feature Branch

This walkthrough shows a complete, small-feature workflow you can repeat for most changes.

1) Verify main is clean

git switch main
git status

If you see modified files, either commit them (if they’re ready) or revert them (if they’re accidental) before proceeding. The goal is to start the feature branch from a known clean state.

2) Create the feature branch

git switch -c feature/add-config-loader
git branch -v

Confirm you’re on the new branch and it points at the expected commit.

3) Implement the change in 2–3 commits

Commit 1: add the core implementation

# edit files (example paths; use your project structure)
git status
git add src/config/loader.js
git commit -m "Add config loader"

Commit 2: integrate it

git add src/app.js src/config/index.js
git commit -m "Use config loader during startup"

Commit 3 (optional): tests and cleanup

git add test/config-loader.test.js
git commit -m "Add tests for config loader"

4) Compare your branch to main

Check that the branch contains only the intended commits:

git log main..feature/add-config-loader

Review the actual code changes as they will appear when merged:

git diff main...feature/add-config-loader

5) Prepare for merging: status, tests, and readable history

Working tree should be clean (no half-finished edits):

git status

Run your tests or checks using your project’s commands (examples):

# choose what applies to your project tooling
npm test
pytest
go test ./...

Make sure commit messages tell a story: each commit should describe a single step. If you read the list from top to bottom, it should be obvious how the feature was built. A quick way to scan:

git log --oneline --decorate -n 10

If the history looks confusing (e.g., “wip”, “try again”, “oops”), consider cleaning it up before merging so future-you can understand why the change exists and how it was introduced.

Now answer the exercise about the content:

Why is it usually recommended to run git diff main...feature-branch (triple-dot) when preparing to merge a feature branch into main?

You are right! Congratulations, now go to the next page

You missed! Try again.

The triple-dot diff compares your branch against the common base with main (the merge base), so you see the net changes your branch introduces for the merge.

Next chapter

Merging with Confidence: Fast-Forward, Merge Commits, and Conflict Resolution

Arrow Right Icon
Download the app to earn free Certification and listen to the courses in the background, even with the screen off.