Hacker News new | ask | show | jobs
by baryphonic 777 days ago
> Rebase workflows are awful and unintuitive. Leave the rebasing to the git wizards who actually know what they're doing, in no circumstances should this be part of your day-to-day work.

Hard disagree. I hardly consider myself a "rebase wizard," but I've been a near-exclusive practitioner of rebase workflows since I can remember. I find rebasing much more intuitive than workflows with merge commits. Squash merges are fine, but with proper intuition, they appear like a special case of rebase.

In my experience, the resistance to rebasing comes down to fears about "rewriting history" and false intuitions about how git works. I usually allay the former by pointing out that squash merges - which almost everyone approves of - also rewrite history. The latter issue seems to arise from arrows in popular git visualizations pointing in the wrong direction, e.g. in Gitflow.[0] In git, the child commit points to its parent, because each node is immutable. The git data structures are extremely simple (hence why git is so named), consisting of blobs, trees, commits, tags and references. Once you understand how these work in practice, rebase becomes intuitive.[1][2]

IMO, the only thing unintuitive about git is the CLI. Translating the graph operation I want into the commands is sometimes a challenge. Maybe that makes me a (frustrated) wizard after all?

[0] https://nvie.com/img/git-model@2x.png

[1] https://speakerdeck.com/pbhogan/power-your-workflow-with-git...

[2] https://eagain.net/articles/git-for-computer-scientists/

1 comments

> In my experience, the resistance to rebasing comes down to fears about "rewriting history" [...]

There is 'git bisect' which only gives you detailed answers if your commit history is as fine-grained as possible while still being compileable and testable. Also, changing commit IDs on branches that are visible to others are a problem.

Which is why my approach is as follows: Work on private branches, one per feature/fix/..., then do interactive rebase to create a compilable and testable patch series out of those onto a for-review branch. While developing, rebasing onto whatever public branch you want to merge with next is of course OK and necessary. When you think the feature in the for-review branch is ready, do a merge-request into the public target (mostly devel) branch as usual, and either merge or rebase, whatever you like best.

But: Whatever branches are public are only ever merged. Never squash-merged, never rebased, never force-pushed, never filter-branched (except maybe after a court order). Because all commits on those branches are necessary to trace what people were doing with the code. All those commits and their relations are necessary for git-blame, bisect, sloccount and other things. Any commit ID there could wind up in some test binary, release ID or stuff, and you absolutely truly need those later on. And while a simple rebase might keep some of the necessary details intact (the other branch will still be there after all), only a plain merge will also preserve all the relations between the branches properly.