5 ms·
Merge commits do so much harm, it's outrageous that anyone would think they're any good (save for git merge --no-ff a branch that has already been rebased onto
by erso 14y ago
Merge commits do so much harm, it's outrageous that anyone would think they're any good (save for git merge --no-ff a branch that has already been rebased onto the branch it's being merged into).
If I'm working along on a branch and someone commits something remotely, I can:
git pull and get their changes as a merge commit
or
git rebase origin/master and get their changes below mine
The big difference here is that if I have a conflict with their changes and I do a merge, I resolve those conflicts in the merge commit. This is terrible for a few reasons:
* It means my commits are inherently broken. They're only made un-broken by the merge commit
* When anyone else looks at my commit history, they have to look not only at the commits that I made but at the merge commit that resolved the conflicts from the prior commit, otherwise they're using a bad commit as a reference
* When I do eventually merge my branch in, there will be a mess of commits from master splayed all throughout my commits, so that nobody can easily see what commits were actually mine without doing a git log origin/master..my_branch to see just what my branch is adding
Now, if I decide to use rebase instead of merge, I resolve those conflicts at the point in which they would have occurred on my branch, thereby making my commits conflict-free. My history is also compact as it isn't spread over time with (possibly multiple) merge commits from master.
If you happen to do merge commits you cannot easily rebase that branch without ripping out the merges first using something like git rebase --onto (http://pivotallabs.com/users/khicks/blog/articles/2118-git-rebase-onto http://pivotallabs.com/users/khicks/blog/articles/2118-git-r...). You can have git try to replay the merges at the point they occurred via git rebase -p (preserve merges), but that's dangerous and not useful territory to be in.
The brunt of your argument seems to be that you'd prefer people to be constantly pushing to master features that are incomplete or otherwise don't work, all for the sake of having other people have your broken or incomplete features available for them to start writing code against. This is madness. You have to manage that mess with feature flags or other song-and-dance nonsense that you could avoid entirely by using rebase instead of merge and only putting your stuff on top of master (either via rebasing your commits onto master as the OP notes or by --no-ff merging the branch, as I noted earlier). In addition to that, you can no longer easily even tell what a feature was. Maybe you use commit messages that have a story/card/bug ID that you can use to track, but man, I'd hate to rely on that.
I've used the rebase strategy for multiple years now with teams of 20-60 people, distributed across countries with great success. I have yet to hear a reasonable argument for merging other than "but, but.. you can't silo your work!" The hell I can't. I'm going to work on the feature branch until, at minimum, the feature is passed by QA as being feature-complete. Until the point of me putting my work onto master I have absolute control over squashing/rearranging commits, messages, deleting commits, and doing whatever the hell else I want to do to make sure my commits are all green (passing all tests), conflict-free, and sensible. Hell, I've even done talks on my rebase-based Git workflow. Until that point, my commits aren't useful to anyone because the work is by definition incomplete. I care more about a clean, readable, green commit history than someone's idea that having all code pushed to master as soon as it's written is somehow better.
- j_baker 14y agoYou know, I can respect people who choose to use rebase instead of merge, but your arguments against merging borderline on hysteria. I mean, plenty of teams of equal or larger size have dealt with merge commits that it's just silly to say things like "Merge commits do so much harm, it's outrageous that anyone would think they're any good". Having code pushed to master sooner rather than later is better. It means that you have fewer developers stepping over each other to make changes. When you have 20-60 (or more) developers working on many different things at many different times, this is important. Also, I think you're painting an extreme picture of merging where everyone always uses a merge commit for everything. It's silly to expect that with a team of 20-60 people, everyone should be doing git pull every time they update and then pushing that back to master. We have git pull --rebase for that. There are even options to make git do that by default. I vastly prefer merge commits when dealing with feature branches. It makes it much easier to see a logical grouping of merge commits, and makes it so I don't have every commit interspersed between.
- erso 14y agoThe thing is, what you're saying directly contradicts reality. You have fewer developers stepping over each other to make changes when they aren't constantly merging in things that have a high likelihood of changing. If someone makes a change and pushes it to master I can just as well rebase my work on top of their commit, make any changes I might need to should there be a conflict, and go on my way without having to merge anything. If I use merge in that same situation I can end up with a string of useless merge commits that contain conflict resolution practically hidden away from the real work. Logical grouping of commits is still completely possible with merging as I said, when you use --no-ff merging into the branch after having rebased on top of it. For example, if I have a branch topicA, I can, having fast-forwarded master and being on topicA, git rebase master, git checkout master, and then git merge --no-ff topicA. This will give you the only acceptable merge commit, with a history that shows where your branch diverged from master and what commits it contains.