Hacker News new | ask | show | jobs
by andrewaylett 3203 days ago
`git rebase --exec {rebuild project}` solves the issue of invisible errors in commits. I'm a big fan of Gerrit's review workflow, which requires every commit to build in isolation. I also usually try to squash my changes into logical independent commits before review.

I like rebase because it's prettier, but I also think there's an issue with the non-rebase case that the OP has missed: unless you rebase, you're setting yourself up for failure in the `git bisect` case: when you step back to find the source of an bug you're tracking down, the worst possible case is that you find it's introduced by a merge and not present in either of the parents. That's much more likely if your merge commits contain fix-ups of their own, which in turn is much more likely if you've got overlapping branches. If you rebase-and-merge then the merge won't have any extra changes, and if you rebase-and-fast-forward then you won't have any merge commits at all.

5 comments

Yes, yes and yes. We had this issue on the Neovim project a while ago [1]. This caused us to switch workflows [2] (although I would have preferred the --exec approach that you mentioned).

Also see comment [3] by TheCorey mentioning you can use `git bisect --skip`. However, in the mentioned case with Neovim, very few commits actually built, making the process non-deterministic somehow (it kept going in cycles).

[1]: https://github.com/neovim/neovim/issues/6431

[2]: https://github.com/neovim/neovim/issues/6435

[3]: https://news.ycombinator.com/item?id=15264159

But that's exactly why I prefer merges - seeing that the problem wasn't in any individual branch, but resulted from the combination of changes in both is the most honest result that I would've wanted to see. Why do you label this as a 'failure'?
It sounds like rebasing this way ensures branches will not overlap at merge time. This presumably pushes the "combination of changes" into the rebased-before-merging branch, which (if nothing else) makes sure that one committer owns the bug, not two.
In case of merge that would be merge commit author.
Because it's really difficult to disentangle changes made legitimately in supporting a merge from unintended extra changes that break things.

It also separates changes you made to implement your functionality work relative to the branch point from the extra changes you need to have your functionality work relative to the merge point. With rebase, you get the opportunity to put all the code to implement a feature in one place.

Remember that the usual caveats about writing software apply: you're doing this for the future-you and future-team-mates who come along in a few months trying to make sense of it all. Make life easy for them.

Author of the article here. You bring up some interesting points, and I would not be much opposed to the workflow you describe. However, as others mention, if the problem results from a combination of changes, I would expect the merge commit to be the one that contains the error. Moving this errror to a commit that was originally part of a branch without errors is just confusing to me.
A merge should be just that: merging code without adding extra changes. If you need to make changes, they should be in a separate commit.

But if you had to resolve conflicts in a merge, you might also have had to make changes, and now you've got to work out whether the breakage was because of the combination of features that hadn't been tested together before or because someone changed something while resolving conflicts. Speaking from experience, that's really difficult.

If you rebase instead, the commit that breaks the build contains the code change that breaks the build, and if it's because of a rebase error you've got the opportunity _as you're rebasing_ to detect that.

My preferred solution is letting "robots" do the actual rebase back to master. In my GH repo I set a label that says 'ready to land' which means that the last CI run will assume that done stuff like proper commit messages and have reworked my commit into how I want them (atomicity, etc). If for whatever reason tests, the extra validations and ultimately trying to rebase to master doesn't pass I get notified as a PR status.

I like the separation between having full freedom in a feature branch without the extra hassle of having to consider timing (active repos usually suffers from this) or typo:ing in commit metadata.

This would probably be ok for smaller projects. My current codebase takes an hour and a half to build, so a rebase to master will involve anywhere from 10 to 100 rebuilds (1-10 days worth), not to mention the whole process stopping on each merge conflict, which will stretch out the rebase time even more as Murphy's Law will place every conflict outside of working hours.
What are you doing where a build takes that long (and can't be done incrementally)?
When doing anything with FPGAs for example, 90 minutes for a compilation is actually in the low side of things (and incremental builds with EDA tools have essentially never worked for me except in a tiny and unpredictable subset of cases).