Pull Requests with Rebase

Avatar

Edward

We’re excited to roll out another way to integrate your pull requests in Azure Repos. Arriving in the Sprint 150 update is an option to rebase your pull request into the target branch. This lets you keep a linear commit history in your master branch, which many people think is an elegant way to visualize history.

Like tabs vs spaces, the way code gets integrated is the subject of heated debates on teams. Some people prefer merges, some people prefer rebase, and some people prefer a hybrid approach or even a “squash”. Azure Repos supports each of these scenarios:

Merge (no fast-forward)

This is the default integration strategy in Azure Repos, GitHub and most other Git providers. It emulates running git merge pr from the master branch. All the individual commits in the pull request branch are preserved as-is, and a new merge commit is created to unite the master branch and the pull request branch.

This strategy is helpful because it illustrates exactly how a developer (or developers) worked on a pull request, including each individual commit along the way. It gives the most insight into how a branch evolves, but since it preserves every commit is may be very verbose.

Squash commit

Squashing will take the tree that’s produced in a merge and creates a single new commit with those repository contents. It emulates running git merge pr --squash from the master branch. The resulting commit is not a merge commit; those individual commits that made up the pull request are discarded.

When this strategy is used, history is reminiscent of a centralized version control system. Each pull request becomes a single commit in master, and there are no merges, just a simple, straight, linear history. Individual commits are lost, which is best for teams that use “fix up” commits or do not carefully craft individual commits for review before pushing them.

Rebase

Rebase will take each individual commit in the pull request and cherry-pick them onto the master branch. It emulates running git rebase master on the pull reuqest branch, followed by git merge pr --ff-only on the master branch.

When this strategy is used, history is straight and linear, like it is with the “squash” option, but each individual commit is retained. This is useful for teams that practice careful commit hygeine, where each individual commit stands on its own.

Semi-linear merge

This strategy is the most exotic – it’s a mix of rebase and a merge. First, the commits in the pull request are rebased on top of the master branch. Then those rebased pull requests are merged into master branch. It emulates running git rebase master on the pull request branch, followed by git merge pr --no-ff on the master branch.

Some people think of this as the best of both worlds: individual commits are retained, so that you can see how the work evolved, but instead of just being rebased, a “merge bubble” is shown so that you can immediately see the work in each individual pull request.

Branch Policies

Many teams want to choose a pull request integration strategy and standardize on it for the whole team. Regardless of whether you prefer the rebase approach or the merge approach, it’s often helpful to use same approach for each pull request.

Thankfully, you can configure a branch policy to enforce your preferred integration strategy (or strategies). Selecting only one will mean that pull requests into master will always use a single strategy.

And, of course, these branch policies that limit the merge types for a pull request are the perfect companion to the other branch policies. One that’s indispensible, of course, is the build validation branch policy, where you can set up an Azure Pipelines build for your master branch, and your build and tests must succeed before a pull request can be merged (or squashed, or rebased) into master.

Avatar
Edward Thomson

Principal Program Manager, Azure DevOps

Follow Edward   

6 Comments
Avatar
Heath Stewart 2019-07-10 20:55:36
In which strategies is the commit author(s) retained? If all commits in a squash are from the same author, is the author retained there as well? This information is often crucial to diagnosing certain types of defects that may require some context from the original author.
Avatar
Bruno Lima 2019-06-19 09:38:21
Recently, my team are using Squash in individual branch and rebase strategy in pull request to master. Thereby, the story of branch master is linear and straight besides keeping the history of branch clean 
Avatar
Bruno Lima 2019-06-19 07:00:15
Recently, my team are using Squash in individual branch and rebase strategy my pull request to master. Thereby, the story of branch master is linear and straight besides keeping the history of branch clean 
Avatar
Bart Sipes 2019-04-23 10:14:07
Any chance you can sync up the titles in the branch policies with what you have here? I assume that your blog post section of "Rebase" is the same as "Rebase and fast-forward" and the "Semi-linear merge" is the same as "Rebase with merge commit" but I'm not certain. For people who are new to git, it'd be nice if the descriptions can be consistent to help us understand what's what. Thanks
Avatar
Phillips 2019-04-22 20:29:30
I find that enforcement of some of these strategies to miss the importance of commits. I find the appropriate answer is what will provide safety and communication. A merge commit allows for rollback of a collection of changes  A squash commit prevents crafting good separation of changes (atomic commits)  https://dev.to/jessekphillips/git-is-a-communication-tool--2j9k
Gaurav Kanoongo
Gaurav Kanoongo 2019-04-22 20:19:55
I was waiting for this semi-linear merge fearure since very long - thanks for introducing it.