I am actively working on a two person project with very few longstanding feature branches (longest existing branch is 3 weeks).

I have spent the afternoon trying to understand merge vs rebase and what the advantages and disadvantages are. I've made some progress and plan on incorporating rebase to clean up my local commits before pushing to github for a code review. I like to commit often and I have automated testing so it seems like the main argument against rebase that it could introduce bugs to the rebased commits isn't as relevant. While I've seen some arguments against this type of rebasing it seems less controversial. My confusion is about rebasing vs merging a feature branch into master after the code review is complete. I know that noone else is relying on it and the code review process generated many small meaningless syntax commits. Both of these seem to suggest rebasing.

My understanding is that for my project rebase has the advantage of keeping the history clean which lets me see better summaries in git blame of why a change was introduced. It also helps keep the history linear which makes it easier to use git bisect (is it about the history being linear or about having every commit be complete and not intentionally-breaking). It also allows fixes to my current example where I forgot to rename and edit a file in separate commits before submitting a pull request, leading to a large unnecessary diff. For this project none of these seem like game-changing disadvantages to using the git-merge workflow (the codebase might just not be big enough yet to experience the real disadvantages) but they would be nice to have if there aren't large cons.

The disadvantages I see are that I'm no git expert and it seems much easier to really break things with rebase than with merge. Second, we do a lot of active commenting on pull requests in github and I'm hesitant to break or lose those comments by rebasing and changing the SHA (on second thought I don't think I'll lose the comments but they'll no longer refer to the correct commits so I would have to hunt down the commits referred to by other means). Third, it gives the illusion of each commit being a logical complete and working commit when in reality I probably will still have commits that are partially broken.

In this article about merge vs rebase they give the following advice about this situation:

Review is done and ready to be integrated into the target branch. Congratulations! You‘re about to delete your feature branch. Given that other developers won’t be fetch-merging in these changes from this point on, this is your chance to sanitize history. At this point you can rewrite history and fold the original commits and those pesky ‘pr rework’ and ‘merge’ commits into a small set of focussed commits. Creating an explicit merge for these commits is optional, but has value. It records when the feature graduated to master.

I'm very interested in knowing whether my above analysis is on the right track. Right now I'm leaning towards cautiously using rebase as described in the advice above. But I'm even confused how to actually do what they suggest. How do I create an explicit merge? Do I make a local branch that's a copy of feature and then rebase -i on that branch to make the history look like I want and then merge with master? Or do I rebase feature directly onto master and then use rebase -i to squash commits as appropriate. If this approach is what they are suggesting how do I then create an explicit merge at the end?

  • Just merge, it wont break stuff horribly. Which is more than you can say about rebasing – Ewan Feb 15 '16 at 21:43
  • If you never force push what is the worst that can happen? – emschorsch Feb 16 '16 at 2:28
  • if this, if that, Merging is always safe – Ewan Feb 16 '16 at 11:01

The solution I decided was simplest and kept the most advantages for me was to rebase and then merge. After using github to go back and forth on the pull request and committing a few minor changes it was time to merge it into the master branch. On my local setup I did:

git pull
git checkout feature
git rebase -i HEAD~8  # combine small commits and separate file moving
git checkout master
git merge --no-ff feature  # comment this with `close #<pull_request_number>`
git push

The advantages are:

  • On the master branch the history is cleaner and more concise
  • The explicit merge at the end links the pull request to the merging commit

The disadvantages are:

  • The rebased commits in the pull request no longer link to commits in the master which could be confusing.
  • I didn't actually go back and make sure each of rebased commits works in the new rebased context so small chance of bugs there

Not sure if this is a recommended approach or a little too hacky and I should stick to one or the other. But we'll see if any problems stem from this. Very flexible to different suggestions from other people though.

  • If you rebased after pushing the branch to github, you just broke it for everyone else who pulled the branch – Ewan Feb 15 '16 at 21:48
  • No I didn't push --force and overwrite the feature branch on github I just rebased it locally and used those rebased commits to merge into master. – emschorsch Feb 16 '16 at 2:28
  • so if i put a bug fix on the feature branch and merge in to master again I will get conflicts with all your commits – Ewan Feb 16 '16 at 10:57

I see you have already answered the question with your own answer, but I still feel like sharing this.

Until you push to the remote repository, it does not really matter whether you use merge or rebase. You have already pointed out yourself, that with rebase, the branch rails look cleaner, because they stay linear and do not extend in a way they do with merge.

Either way, by using both rebase and merge you are likely to be forced to fix conflicts and these conflicts can and may be completely different.

Therefore, if you are working alone on a branch (this branch cannot naturally be pushed to the remote repo just yet), I would suggest doing rebasing before the initial pull request. Should the branch stay on the repo and should you ever work on it again in the future, merge is the way to go, as rebase would mess with the history of discussed branch and different developers could have different code.

  • Does this apply even if it's a feature branch which will be deleted as soon as the feature is merged? It seems like if there's no conflicts then the decision of rebase vs merge isn't as consequential. Is that correct? – emschorsch Feb 13 '16 at 22:42
  • 1
    @emschorsch Not really. It is not about the conflict, but more about the branch workflow and commit management. By merging a master into your feature branch, you are introducing an extra commit, the master -> feature merge. Then there's also another comming when this branch gets merged to master. With rebasing, you're effectively avoiding the uneccessary comit the merge does. Generally speaking, merge is much safer to work with, but rebase can sometimes be the better alternative, as per my answer. – Andy Feb 14 '16 at 11:42

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.