What is a Feature Branch in Git?

Greg Foster
Greg Foster
Graphite software engineer

What is a Feature Branch in Git?

![What is a Feature Branch in Git](/images/content/guides/what-feature-branch-git/1713212369-feature-branch.jpg

Whenever you see discussions of Git and how it all works, you’re very likely to come across the phrase “feature branch.” A feature branch is a common fixture of projects that are large enough to have multiple groups or developers working on different parts of them at the same time. It’s important to understand what it is on both a conceptual and a mechanical level, so let’s get started.

Where do you begin with a discussion of feature branches? The easiest answer is to begin with the concept of branches entirely. What is a branch? What makes a feature branch different from the main branch? How do you implement adding a feature branch to the main when the development of the feature is complete? Read on as we discuss all of this and more.

The general concept behind the workflow involving feature branches is a way to segment development and protect a central code base.

Say you have a project, and that project is stored on GitHub as a repo named Main. This Main repository is the home of your code as it stands. For in-development projects, this may not be functional, but the modules and elements that exist are in as close to a stable form as possible. In an established project, the Main branch is your stable, public release, with features that are complete and tested alongside each other and the core of the code, so there are no bugs, conflicts, or other issues.

![Review of branches](/images/content/guides/what-feature-branch-git/1713212440-review-of-branches.jpg

When you want to develop a new feature, you have two options. You can work on it in situ, and when you have code to push, you commit it to the Main. This is potentially fine for single-dev, private projects. Unfortunately, it causes all kinds of issues for public and active projects. If your developer does work on a feature and commits to Main, and someone else tries to download and use the project, they’ll end up with buggy, incomplete, or partially overwritten code that simply won’t work properly.

Until the development of the feature is complete and committed, the project will be unstable and unusable.

The other way to handle this situation is by creating a branch. A branch is essentially a copy of the code and repository, where development on a feature can happen and be committed to the branch. When the feature is under development, commits go to the feature branch. When the feature is complete, the entire branch can be merged back into the Main, integrating that new feature into the project as one stable whole.

Feature branches also enable the use of another Git feature called the pull request. Pull requests are a request sent to other collaborators on a project, asking for permission to pull the branch’s code into the main or into another branch. The request is reviewed by other developers and, if it is granted, the branch is pulled into the main. Pull requests are also a venue where comments and collaboration can occur.

Feature branches are a specific kind of workflow that can be leveraged in Git and many Git-adjacent tools. Using the feature branch workflow means structuring your project around a Main central repository while working on any individual feature in its own feature branch.

Feature branches, when created, should be given descriptive names. These names are meant to be a clear description of what the purpose of the branch is. It can be descriptive of the feature, such as adding a new way to handle user data or an update to an existing feature. Alternatively, it can be a specific issue identified elsewhere, such as “Issue#56” or “BugReport#12”. The goal is that any developer working on the project can see feature branches and know what they are about, both so that duplicate feature branches aren’t created and so that collaborators on the same branch can keep it identified.

![How they work](/images/content/guides/what-feature-branch-git/1713212556-how-they-work.jpg

On a purely technical level, mechanically speaking, there’s no difference between a feature branch, a personal branch, the Main branch, or any other branch. They’re all simply branches of code controlled by Git. The only tangible difference is when they are given specific associations, such as the main branch having the name Main and the feature branches having the names of features. A project can have any number of branches, all stored in the same repository, and only the Main branch is flagged as the actual code product of the repository.

Creating branches is relatively simple, but there are a lot of optional additional flags that can be used when you initiate the command. These range from copying existing branches to color-coding branches to many different configuration options. You can read a complete rundown of all of the flags, parameters, and options you can set here. Be warned, though; there’s a lot on this page, and if you aren’t well-versed in parameters and data structures, much of it may go over your head. Fortunately, that’s fine; most of the time, you won’t need to care about pretty much any of it.

To get started with using a feature branch, the first thing you need to do is to sync up your local copy of the main branch with the origin.

$ git checkout main

$ git fetch origin

$ git reset –hard origin/main

This set of commands switches your current repository to the main branch, pulls any recent commits, and resets the local copy of the main branch to match the latest version of that branch from the origin repository.

Once this is done, you’re operating on a clean, updated slate, where you can create your new feature branch.

$ git checkout -b Feature-Branch-Name

This command is a two-parter. Checkout checks to see if there is already a branch named after the name you specify, in this case, Feature-Branch-Name. If that branch already exists, you will be moved to that branch; if it doesn’t, the -b flag is a secondary directive that instructs Git to create that branch.

![Creating and Using](/images/content/guides/what-feature-branch-git/1713212568-creating-and-using.jpg

This is the point where you get to work on the feature using the feature branch as your local repository for development of that branch. You create and edit files, and you commit your changes and new files to the feature branch as you go. Over time, you reach milestones or, as the project development protocol dictates or as your organization demands, you finish the feature and are ready to implement it into the main.

Optionally, but recommended, you can create a remote tracking branch in the origin repository, used for tracking changes and updates to the feature branch, without committing to the main branch. You can do this using a command such as:

$ git push -u origin Feature-Branch-Name

Push requests directly deposit the feature branch’s information in the central repository, and the -u flag sets it as a tracking branch rather than a standard commit. Push is ideal for individual tracking, as it doesn’t require input from others but creates a record of updates in the tracking branch so that collaborators can see that work is being done. If other collaborators want to make comments on the remote branch and push requests, they can do so, and you can take and resolve them.

One of the greatest risks of collaborating on a project is that each developer or team is off in their own feature branch working on their own elements, and there’s generally relatively little communication across teams when there otherwise doesn’t have to be. However, it’s very rare that any given project or code base is so clean and segmented that you can work on a feature while another team works on another feature, and there will be no overlap in the files or code addressed.

That means two situations can arise.

  • You finish your feature and commit it to the main, which makes changes that the other team now has to integrate into their feature, possibly overwriting or undoing some of their work.

  • The other team finishes their feature and commits it to the main, overwriting files and changing code that affects your feature and requires you to redevelop or change your work.

These are conflicts, and they need to be resolved, ideally proactively, before they become problems. This is a common problem, and it’s one that Git has features to help with. The primary feature is the pull request.

To use a pull request, the feature branch is pushed to the central repository. It’s still a separate branch, but once it’s in the same location, a pull request can be initiated. This pull request invites other collaborators to comment on the code and identify possible conflicts before the feature branch is merged into the main. Essentially, a pull request is designed to be a discussion forum for that particular feature’s code. This can be for a milestone or for the completion of the feature, though it is most commonly the latter.


Once a pull request has been validated, the feature branch commits to its own local main, and then that main is merged into the central repository’s main, creating a new main with the feature integrated. Conversely, if there are changes that need to be made, other collaborators can discuss them via the pull request, the developer can work on and implement those changes, and a new pull request can be made to discuss, review, and commit.

There are many different ways to manage merging, pull requests, and branches. There are also numerous additional tools that integrate with Git and GitHub, with the goal of adding features, streamlining the system, or facilitating discussion. For example, Graphite is a way to create parallelized pull requests, streamline discussion and code reviews, and facilitate better merging. You can read more about what it is and how it works here.

Another discussion that frequently comes up is whether to use merging or rebasing to add a feature to the main.

If you think of creating a feature branch as splitting code into two and creating two development chains, merging is when the two are ready to be joined back up; they are joined at the current point in time. This creates something of a circle, sort of like two paths diverging at a fork in the road, only to join back together later.

(Note that despite the use of the word fork, a branch is not a fork; Forks are specific things in the world of Git.)

The other option is to rebase. A rebase, rather than taking the feature code and merging it into the current main, staples the entire feature branch’s development path onto the tip of the main. The end result is the same – the feature added to the main – but instead of a divided history with two paths through it, there’s one single linear history instead.

There are pros and cons to both options and much has been said about them both. In fact, we have a whole guide to using them both, and when you might want to pick one over the other, which you can read here.

Functionally, the end result is the same, so a lot of it comes down to the kind of history of your project you want to keep and how well you grasp the organization of one or the other. There are also a lot of details about how you perform merges and what kind of merge strategies you choose to use, for example, which can make a significant difference in the way your project is handled.

Regardless of how you choose to manage your project, we highly recommend using Graphite.


Every experienced developer knows two things: Git is aging and awkward, and Git is the best tool to do what it does. We created Graphite to be a Swiss army knife for managing everything you could need to do with Git to make it faster, more effective, and easier to manage for projects of all sizes. We highly encourage you to check it out and see what it can do for you.!

Stay unblocked. Ship faster.
Experience the new developer workflow - create, review, and merge code continuously. Get started with one command.
Get started

Give your PR workflow
an upgrade today

Stack easier | Ship smaller | Review quicker

Or install our CLI.
Product Screenshot 1
Product Screenshot 2