Hacker News new | ask | show | jobs
by thesis 3731 days ago
We tried Gerrit. We ran as fast as possible away. It seemed to hate merge commits, and would hang up often. I'm not sure if it's changed at all, but I think the only option was to review every commit individually inside of a branch. It seemed to really be pushing us towards squashing a branch and pushing that up.
2 comments

Gerrit does favor rebasing over merging but that's hardly a reason to run away from it
Rebasing is great for version history but is hell for collaborating on a feature. If anything is the Achilles' heel of Git (aside from the groundbreaking levels of inconsistency in the CLI) it's this.

the moment someone creates a new version control system that has most of what Git does but fixes parallel histories, I'll switch. And I don't mean that the way people say "if Bush wins again I'm moving to Canada." I say that as someone who has administered CVS, SVN and Perforce repositories on behalf of my teammates but wants nothing to do with administering Git.

Would you care to elaborate what you find wrong/bad about "parallel histories"? I'm curious.
This is related to the conversation about squash that happened last week.

Basically, the moment two or more people try to work on something outside of the trunk line of code (trunk/master/whatever), there is no version of their commit history that will be pretty, and so squashing the branch at the end seems like a good idea, even though it produces objectively worse code over the long run.

To wit: There comes a point where the branch and merge structure of the code N months ago is no longer relevant to my day. However, the contents of 'blame' could contain code from years ago every time I use it. [edit] How it was merged is irrelevant. When it was merged, by whom and with what commit message is what survives into the future. By squashing the who and the message are lost. But we think that's okay because it's a lesser evil than having a bunch of commits in trunk. Which is bullshit.

What's hard to stomach is a bunch of merge commits back and forth and back again, and so I sympathize with people eager to sweep those under the rug. But at the same time I know that one of the most common ways a bug makes it into the code is via a bad merge. Keeping them is more honest even if we don't want to think about all the little human things we do that make our code worse.

I want to tell one little white lie with the code: I want to pretend like Joe and Tim wrote their entire feature after my bug fix and before Steven's, even though they worked on it all week. I want them to be able to commit it as a single transaction but with all the intermediate steps.

When I say 'parallel history' I mean I want Joe to be able to rebase the branch on top of my changes, without having to go apologize to Tim for making his snapshot into mincemeat.

Or, I want us to stop pretending like feature branches fix all of our problems, with no serious consequences. Maybe we should just go back to the roots of Continuous Integration and merge on every commit, and rely on things like feature toggles and test automation to control the reach of our in-progress changes.

I think the real issue at hand here is the one-size-fits-most mentality we maintain. As a maintainer of a FOSS project I want to reserve the right to reject contributions out of hand. If I don't like your code I tell you no and you go away. I will also enjoy getting medium units of work that were a team effort without ever having to coordinate with any of those team members. As a volunteer effort, this scales like nobody's business. But just because it's working great for open source doesn't mean it's the rational answer for commercial code.

In commercial code, all changes can be tracked to either human error or a requirements change, and knowledge of the project often is locked in someone's head because archived public forums aren't the dominant form of communication or negotiation. When, how, and why every line changed matters because every fix I undo while making another one alienates a paying customer. So verifying why the code is the way it is now is fairly important.

And let's be perfectly honest here. If, as your dev lead, I don't like the quality of your contribution, guess what, it's going in anyway. I can push back and make you do it better, but 9 times out of 10 your change is going in. Maybe not today, but soon, unless I'm in the process of getting you fired for incompetence. So being able to drop it on the floor at no cost to me isn't really a useful feature. For Linus that and an insulting email are how he 'fires' bad contributors. As coworkers our relationship would be a little more complex.

Pretending that these constraints fit the exact same development pattern as what works for Linux, NPM, Mocha, or probably even Docker is just nuts. We can share a lot of tools, but we can't use exactly the same development process. And Git bends in one direction but has no give in the other.

> By squashing the who and the message are lost. But we think that's okay because it's a lesser evil than having a bunch of commits in trunk. Which is bullshit.

Well, don't erase the message when squashing. My policy is that we take the pull request and use the message title and description as the actual message of the squashed commit, which works great.

Having a bunch of commits IS really bad. One idea = one commit is so much better than some bullshit three commits of "refactored" "made mistake" "back to normal" those are just as worthless to keep in the history as recording your typos+backspaces+fixes into the history.

> This is related to the conversation about squash that happened last week.

> Basically, the moment two or more people try to work on something outside of the trunk line of code (trunk/master/whatever), there is no version of their commit history that will be pretty, and so squashing the branch at the end seems like a good idea, even though it produces objectively worse code over the long run.

I don't like squashing at all, unless you're squashing commits locally because you fixed a bug in a previous commit that only exists in your local branch. Because in that case, it doesn't make sense to pollute the history with commits that were known to be broken when merged (this causes issues with bisecting).

> I want to tell one little white lie with the code: I want to pretend like Joe and Tim wrote their entire feature after my bug fix and before Steven's, even though they worked on it all week. I want them to be able to commit it as a single transaction but with all the intermediate steps.

> When I say 'parallel history' I mean I want Joe to be able to rebase the branch on top of my changes, without having to go apologize to Tim for making his snapshot into mincemeat.

I had to read your comment several times and I still don't think I understand what you mean by "parallel history". Are you saying that A and B are working on a feature concurrently (but not by merging into a central place)? If they were merging into a central place than that central place can be rebased to get in line with C's bugfix. Then A and B can rebase their local branches with the central branch.

It's also possible to do all of the rebasing locally, then once one pushes the other needs to rebase. But I don't think that works well.

Essentially you need to treat people collaborating on a branch the same way you consider it as collaborating on a project.

But maybe I misunderstood what you meant.

> Or, I want us to stop pretending like feature branches fix all of our problems, with no serious consequences.

Looks like I did misunderstand.

consider mercurial. You may be pleasantly surprised.

edit: spelling

What do you mean by "fixes parallel histories"? What is a parallel history and how do you fix it?
> I'm not sure if it's changed at all, but I think the only option was to review every commit individually inside of a branch. It seemed to really be pushing us towards squashing a branch and pushing that up.

The author mentions this as being a feature of Gerrit in the post.