WebDevNav
Technology

Git Branches Are Simpler Than You Think

Author

Naveen S

Date Published

Imagine you're working on a web application. The main application works perfectly, and your team is ready to release it.

Then someone asks:

"Can you try a completely different login page?"

You have two choices.

You could start changing the existing code and hope nothing breaks. Or you could create a separate line of development, experiment freely, and bring the changes back when they're ready.

Git branches make the second option possible.

But here's the interesting part: a Git branch isn't a separate copy of your entire project. It's a lightweight pointer to a commit.

Once you understand that idea, branching becomes much less mysterious.

1. First, let's look at commit history

In the previous articles, we learned how Git records commits.

Suppose our project has three commits:

A --- B --- C

Each letter represents a commit. Commit C is the latest commit in this simple history.

When you initialize a repository and make commits, Git maintains references that help identify important points in that history.

One of those references is your branch.

For example, if the current branch is main, its history might look like this:

A --- B --- C
^
|
main

The main branch points to commit C.

Now comes the important part.

The branch doesn't contain a separate copy of every file. It simply identifies a particular commit in the repository's history.

That makes branches inexpensive to create and useful for everyday development.

2. Create your first branch

Let's use a small example.

Imagine you have a repository with an initial commit:

A main

You're ready to work on a new login feature, so create a branch:

git branch feature/login

This creates a branch named feature/login pointing to the same commit as the branch you were on.

You can list your branches with:

git branch

The output might look like this:

feature/login
* main

The asterisk indicates the branch you're currently on.

Notice that creating a branch doesn't switch you to it. It only creates the new branch reference.

To start working on the login feature, switch to it:

git switch feature/login

Check the branch list again:

git branch

You should now see:

* feature/login
main

Your current branch has changed, but you haven't created a new commit yet.

Both branches still point to the same commit:

A
├── main
└── feature/login ← current branch

Think of the branches as two labels pointing to the same starting point. Their histories will diverge when you create different commits.

3. Make a change on your new branch

Let's pretend we're adding a login page.

Create a file called login.txt with this content:

Login page
Username field
Password field

Stage and commit the change:

git add login.txt
git commit -m "Add login page"

Your history now looks like this:

A --- B feature/login
|
└── main

More conventionally, we can draw it as:

A --- B feature/login
^
main

Commit B contains the new login page. The feature/login branch now points to B, while main still points to A.

This is what makes branches useful: the feature can progress without moving the main branch.

Nothing special happened to the files because they belonged to a branch. You used the same git add and git commit commands from the previous article.

The difference is which branch reference advances when the commit is created.

4. What happens when you switch branches?

Let's return to main:

git switch main

Your working directory will be updated to reflect the snapshot associated with main. Since login.txt was introduced only on the feature branch, it won't appear in the working tree on main in this example.

Now look at the history:

A --- B feature/login
^
main

The feature commit still exists. Switching branches didn't delete it.

It simply changed which branch you were working on and updated the working tree accordingly.

Switch back:

git switch feature/login

Your login page is available again.

This is not Git copying your entire repository into a new directory every time you switch branches. Git updates the working tree and its index to match the target commit, subject to the state of your current changes.

A useful rule: Commit or otherwise safely handle your changes before switching branches. Git can prevent a switch if it would overwrite local changes that aren't safely preserved.

5. A branch is a pointer, not a container

Let's examine what makes branching so lightweight.

When you create a branch:

git branch feature/login

Git creates a reference to a commit. It doesn't duplicate every file in the project.

When you commit while on that branch, Git creates a new commit and advances the current branch reference.

Consider this history:

A --- B --- C feature/login
|
└── main

Here:

main points to A.

feature/login points to C.

B and C are commits in the feature branch's history.

The branch name is simply a convenient way to refer to the latest commit on that line of development.

If you've ever wondered why Git can create branches so quickly, this is the reason.

It's not making another full project folder. It's creating and maintaining references to commits.

6. Meet HEAD: the pointer that tells Git where you are

You've probably encountered HEAD in Git output or documentation.

What does it actually mean?

In the usual case, HEAD identifies the branch you're currently on. That branch, in turn, points to a commit.

For example:

HEAD
|
v
main
|
v
A --- B --- C

Here, HEAD points to main, and main points to commit C.

When you create a new commit on main, Git advances the branch to the new commit. HEAD continues to identify the current branch.

You can inspect the current branch with:

git branch --show-current

Or inspect the commit that HEAD resolves to:

git log -1 --oneline

There's also a special situation called detached HEAD.

If you check out a specific commit rather than a branch, HEAD points directly to that commit instead of naming the current branch. You can inspect older snapshots this way, but new commits made in this state won't automatically advance a branch reference.

Don't worry if that sounds abstract right now. The important idea is that HEAD tells Git what your current position is in the repository.

7. Create and switch in one command

Earlier, we used two commands:

git branch feature/login
git switch feature/login

Modern Git lets you combine these operations:

git switch -c feature/login

The -c option creates the branch and switches to it.

If the branch already exists, use:

git switch feature/login

You can also use the older command:

git checkout -b feature/login

You'll still see checkout in existing projects and tutorials. It's a versatile command that handles several operations, including switching branches and checking out commits.

For everyday branch creation and switching, git switch is often easier to understand because its purpose is more specific.

8. What happens when the feature is ready?

We've added a login page on feature/login. Now suppose the feature is ready to integrate into main.

First, switch to the target branch:

git switch main

Then merge the feature branch:

git merge feature/login

If main hasn't moved forward since the feature branch was created, Git can often perform a fast-forward merge.

The history changes from:

A --- B feature/login
^
main

to:

A --- B
^
main, feature/login

Both branch names now point to B.

No merge commit is necessary for this fast-forward because main can simply move forward to the existing feature commit.

If both branches have developed independently, Git may need to create a merge commit or ask you to resolve conflicts.

We'll explore those cases in the next article.

One important distinction: merging does not automatically delete the feature branch. If you're finished with it, you can remove the branch separately:

git branch -d feature/login

This deletes the local branch reference, not the commits that are already part of the history of main.

9. A practical branch workflow

Here's a simple workflow you can use in your own projects:

# Start from the main branch
git switch main

# Create a branch for a new feature
git switch -c feature/login

# Make changes to your files
# Stage and commit those changes
git add .
git commit -m "Add login page"

# Return to the main branch
git switch main

# Integrate the feature
git merge feature/login

For a real project, review git status and your staged changes before committing. If you're working with a remote repository or a team, you may also need to update your local branch and push the feature branch for review.

The basic idea stays the same: create a separate line of development, make commits, and integrate the changes when they're ready.

10. Common misconceptions about branches

"A branch is a separate copy of my project."

Not in the way people often imagine. A branch is a reference to a commit. Switching branches updates your working tree to match the target branch.

"Creating a branch creates a new commit."

No. Creating a branch creates a reference. A new commit appears only when you record a new snapshot.

"Switching branches deletes my changes."

Not normally. Git updates the working tree to match the destination branch. If local changes would be overwritten, Git may refuse the switch. Commit or safely preserve important work first.

"HEAD is a branch."

Not quite. In the usual case, HEAD points to your current branch, which points to a commit. In a detached HEAD state, it points directly to a commit.

"Merging deletes the feature branch."

No. Merging integrates histories. You remove the local feature branch separately if you no longer need it.

The takeaway

Git branches are much simpler once you stop imagining them as separate copies of your project.

Remember these four ideas:

A branch is a movable reference to a commit.

Creating a branch doesn't create a new commit.

HEAD normally identifies your current branch.

Merging integrates work from one line of development into another.

With these concepts in place, branching becomes a practical way to experiment, build features, and collaborate without constantly disturbing your main line of development.

What's next?

We've learned how branches let us work independently. But what happens when two branches have different changes that need to come together?

In the next article, we'll explore fast-forward merges, merge commits, and conflicts—and see how Git brings independent histories together.

Next: Git Merge — Bringing Your Work Together.

Git Branches Explained: HEAD, Commits, and Branch Pointers | WebDevNav