Feature Branch Workflow
Once you've got the hang of the Centralized Workflow, adding feature branches to your development process is an easy way to encourage collaboration and streamline communication between developers.
The core idea behind the Feature Branch Workflow is that all feature development should take place in a dedicated branch instead of the master
branch. This encapsulation makes it easy for multiple developers to work on a particular feature without disturbing the main codebase. It also means the master
branch will never contain broken code, which is a huge advantage for continuous integration environments.
Encapsulating feature development also makes it possible to leverage pull requests, which are a way to initiate discussions around a branch. They give other developers the opportunity to sign off on a feature before it gets integrated into the official project. Or, if you get stuck in the middle of a feature, you can open a pull request asking for suggestions from your colleagues. The point is, pull requests make it incredibly easy for your team to comment on each other’s work.
How It Works
The Feature Branch Workflow still uses a central repository, and master
still represents the official project history. But, instead of committing directly on their local master
branch, developers create a new branch every time they start work on a new feature. Feature branches should have descriptive names, like animated-menu-items
or issue-#1061
. The idea is to give a clear, highly-focused purpose to each branch.
Git makes no technical distinction between the master
branch and feature branches, so developers can edit, stage, and commit changes to a feature branch just as they did in the Centralized Workflow.
In addition, feature branches can (and should) be pushed to the central repository. This makes it possible to share a feature with other developers without touching any official code. Since master
is the only “special” branch, storing several feature branches on the central repository doesn’t pose any problems. Of course, this is also a convenient way to back up everybody’s local commits.
Pull Requests
Aside from isolating feature development, branches make it possible to discuss changes via pull requests. Once someone completes a feature, they don’t immediately merge it into master
. Instead, they push the feature branch to the central server and file a pull request asking to merge their additions into master
. This gives other developers an opportunity to review the changes before they become a part of the main codebase.
Code review is a major benefit of pull requests, but they’re actually designed to be a generic way to talk about code. You can think of pull requests as a discussion dedicated to a particular branch. This means that they can also be used much earlier in the development process. For example, if a developer needs help with a particular feature, all they have to do is file a pull request. Interested parties will be notified automatically, and they’ll be able to see the question right next to the relevant commits.
Once a pull request is accepted, the actual act of publishing a feature is much the same as in the Centralized Workflow. First, you need to make sure your local master
is synchronized with the upstream master
. Then, you merge the feature branch into master
and push the updated master
back to the central repository.
Pull requests can be facilitated by product repository management solutions like Bitbucket Cloud or Bitbucket Server. View the Bitbucket Server pull requests documentation for an example.
Example
The example included below demonstrates a pull request as a form of code review, but remember that they can serve many other purposes.
Mary begins a new feature
Before she starts developing a feature, Mary needs an isolated branch to work on. She can request a new branch with the following command:
git checkout -b marys-feature master
This checks out a branch called marys-feature
based on master
, and the -b
flag tells Git to create the branch if it doesn’t already exist. On this branch, Mary edits, stages, and commits changes in the usual fashion, building up her feature with as many commits as necessary:
git status
git add <some-file>
git commit
Mary goes to lunch
Mary adds a few commits to her feature over the course of the morning. Before she leaves for lunch, it’s a good idea to push her feature branch up to the central repository. This serves as a convenient backup, but if Mary was collaborating with other developers, this would also give them access to her initial commits.
git push -u origin marys-feature
This command pushes marys-feature
to the central repository (origin
), and the -u
flag adds it as a remote tracking branch. After setting up the tracking branch, Mary can call git push without any parameters to push her feature.
Mary finishes her feature
When Mary gets back from lunch, she completes her feature. Before merging it into master
, she needs to file a pull request letting the rest of the team know she's done. But first, she should make sure the central repository has her most recent commits:
git push
Then, she files the pull request in her Git GUI asking to merge marys-feature
into master
, and team members will be notified automatically. The great thing about pull requests is that they show comments right next to their related commits, so it's easy to ask questions about specific changesets.
Bill receives the pull request
Bill gets the pull request and takes a look at marys-feature
. He decides he wants to make a few changes before integrating it into the official project, and he and Mary have some back-and-forth via the pull request.
Mary makes the changes
To make the changes, Mary uses the exact same process as she did to create the first iteration of her feature. She edits, stages, commits, and pushes updates to the central repository. All her activity shows up in the pull request, and Bill can still make comments along the way.
If he wanted, Bill could pull marys-feature
into his local repository and work on it on his own. Any commits he added would also show up in the pull request.
Mary publishes her feature
Once Bill is ready to accept the pull request, someone needs to merge the feature into the stable project (this can be done by either Bill or Mary):
git checkout master
git pull
git pull origin marys-feature
git push
First, whoever’s performing the merge needs to check out their master
branch and make sure it’s up to date. Then, git pull origin marys-feature
merges the central repository’s copy of marys-feature
. You could also use a simple git merge marys-feature
, but the command shown above makes sure you’re always pulling the most up-to-date version of the feature branch. Finally, the updated master
needs to get pushed back to origin
.
This process often results in a merge commit. Some developers like this because it’s like a symbolic joining of the feature with the rest of the code base. But, if you’re partial to a linear history, it’s possible to rebase the feature onto the tip of master
before executing the merge, resulting in a fast-forward merge.
Some GUI’s will automate the pull request acceptance process by running all of these commands just by clicking an “Accept” button. If yours doesn’t, it should at least be able to automatically close the pull request when the feature branch gets merged into master
Meanwhile, John is doing the exact same thing
While Mary and Bill are working on marys-feature
and discussing it in her pull request, John is doing the exact same thing with his own feature branch. By isolating features into separate branches, everybody can work independently, yet it’s still trivial to share changes with other developers when necessary.
Where To Go From Here
For a walkthrough of feature branching on Bitbucket, check out the Using Git Branches documentation. By now, you can hopefully see how feature branches are a way to quite literally multiply the functionality of the single master
branch used in the Centralized Workflow. In addition, feature branches also facilitate pull requests, which makes it possible to discuss specific commits right inside of your version control GUI.
The Feature Branch Workflow is an incredibly flexible way to develop a project. The problem is, sometimes it’s too flexible. For larger teams, it’s often beneficial to assign more specific roles to different branches. The Gitflow Workflow is a common pattern for managing feature development, release preparation, and maintenance.