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?