Git branches are one of the core features that make Git powerful. A branch in Git is a pointer to a specific commit. Imagine a project timeline as a sequence of snapshots (commits) of your code. A branch allows you to diverge from the main timeline and continue working on your project without affecting the main branch. This gives developers flexibility and safety to experiment, create features, fix bugs, and much more.
A Git branch is essentially a movable pointer to a specific commit. When you create a new commit, Git moves the branch you are currently working on to the new commit.
main
(or master
in older versions).main
branch points to the latest commit.
$ git init
$ echo "Hello, World!" > file.txt
$ git add file.txt
$ git commit -m "First commit"
At this point, the commit history looks like this:
main --> First commit
If you create a new branch, the new branch will point to the same commit initially but will diverge as you continue committing on it.
$ git branch new-feature
$ git checkout new-feature
$ echo "New feature" > feature.txt
$ git add feature.txt
$ git commit -m "Added new feature"
The commit history now looks like this:
main --> First commit
new-feature --> Added new feature
This illustrates how branches allow for isolated development of features or bug fixes.
To create a new branch, use the git branch
command:
$ git branch new-branch
This command only creates the branch, but it does not switch to it. The new branch will point to the same commit as the current branch.
To switch to another branch, use the git checkout
or git switch
command:
$ git checkout new-branch
# or
$ git switch new-branch
Now you’re working in the new-branch
branch, and any new commits will only affect this branch.
The git checkout -b
or git switch -c
command creates a new branch and switches to it in one step:
$ git checkout -b new-branch
# or
$ git switch -c new-branch
You can see all branches in your repository with:
$ git branch
The current branch will be highlighted with an asterisk (*
).
If a branch is no longer needed, you can delete it:
$ git branch -d new-branch
The -d
option will only allow you to delete a branch if it has been merged. If you want to force-delete an unmerged branch, use -D
:
$ git branch -D new-branch
Imagine you’re working on a project with a main
branch that represents the stable version of your code. You want to add a new feature, but you don’t want to affect the stable version. Here’s how you might approach it using branches:
$ git branch feature/new-ui
$ git checkout feature/new-ui
# or in one command:
$ git checkout -b feature/new-ui
Now, you’re on the feature/new-ui
branch.
$ echo "New UI Design" > ui.txt
$ git add ui.txt
$ git commit -m "Implemented new UI"
You can switch back to the main
branch and start working on a different feature without affecting your UI work.
$ git checkout main
$ git branch feature/other-feature
$ git checkout feature/other-feature
Once you’re done with the feature and are ready to incorporate it into the main project, you can merge the branches.
$ git checkout main
$ git merge feature/new-ui
The changes from feature/new-ui
will be merged into the main
branch.
After merging, the feature/new-ui
branch is no longer needed.
$ git branch -d feature/new-ui
Different teams and projects use different branching strategies based on their needs. Let’s explore some popular ones:
Git Flow is a branching model that introduces two main branches:
main
(or master
): Represents the stable version of the project.develop
: Represents the latest completed development work.Feature branches are created from develop
and merged back when the feature is complete.
$ git checkout -b feature/my-feature develop
$ git add .
$ git commit -m "My feature"
$ git checkout develop
$ git merge feature/my-feature
Git Flow also incorporates release branches and hotfix branches.
GitHub Flow is simpler. All development happens on feature branches, which are then merged into main
via pull requests.
In this model, all developers work on a single branch (main
or master
) and use short-lived feature branches that are quickly merged back into the trunk.
When merging two branches, conflicts can arise if the same part of a file was modified in both branches. Git will mark the conflict, and you will need to resolve it manually.
Let’s say the main
branch has this code:
Hello, World!
On the new-feature
branch, you modify the file to:
Hello, Git!
If you switch back to main
and modify the same file to:e
Hello, Universe!
When you try to merge new-feature
into main
, Git will detect the conflict.
$ git merge new-feature
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Git will insert markers in the file to show the conflicting changes:
<<<<<<< HEAD
Hello, Universe!
=======
Hello, Git!
>>>>>>> new-feature
You must manually edit the file to resolve the conflict and then commit the changes.
$ git add file.txt
$ git commit -m "Resolved merge conflict"
Rebasing is an alternative to merging that creates a cleaner commit history. Instead of merging branches, rebasing moves or re-applies your commits on top of another branch.
Example:
$ git checkout feature/new-feature
$ git rebase main
This takes all commits from feature/new-feature
and re-applies them on top of main
.
Note😁: We will explore Rebasing in more detail in upcoming dedicated topic.
Understanding Git branches is essential for effective collaboration and project management. Branches allow you to isolate work, experiment with new ideas, and collaborate with others without fear of breaking the main project.Git's powerful branch management, along with advanced features like merging, rebasing, and conflict resolution, makes it the tool of choice for version control in modern software development. By mastering branches, you unlock Git’s full potential, making your development process more efficient and structured. Happy coding !❤️