Rebase is not only useful, but necessary for a distributed VCS to be useful. To be precise, you need to be able to create new commits from old ones using the VCS itself, and if you can do that, you can also rebase.
One of the major reasons I use git for source control whenever I can is that 100% of its features are available at any time for me to use in any way I wish. Rebase allows me to make commits for whatever reason I want at any time, and it's useful because losing committed data is really hard.
When I'm writing code, I put very little effort into how to structure my changes into commits; That's done when I'm preparing a PR or a patch series, when I'm out of the coding mindset and in the "how do I make this reviewable" mindset. When you're contributing to a project, these are two separate tasks that require different approaches. Any false starts and experiments should be documented and expanded on in this phase, because you're communicating with other people. Pushing a series of crappy "asdf" commits on people because "it documents the development process" is lazy and rude.
A tool that requires me to have perfect commits immediately is useless, because getting commits perfect the first time you actually need to commit is not possible.
Agreed. And I very much disagree with this paragraph:
> When a developer can go back to the individual check-ins leading up to the current code, they can work out the answers to such questions using only the level of personal brilliance necessary to be a good developer.
When I have to investigate past commits, I hate it to have to dig through a history of WIP commits containing code that didn't make it into the final version.
Of course it's also difficult to dig through a single commit with hundreds or thousands changed lines of code.
But when a single commit includes a proper description and an issue reference, it much easier to investigate the developer's full intention than from multiple WIPs.
Realistically, a single commit is not going to contain hundreds of thousands of lines of changes unless they're generated code or something.
I'm not advocating that you should merge branches by squashing all commits into one lump; that's definitely wrong. I think in terms of patch series, where each patch is a single commit that does something, and each feature is a series of patches consisting of stand-alone refactorings, bug fixes and new APIs required to implement the final feature.
But how I actually end up with that clean set of 1-n final commits in a PR or mailing list submission is no-one's business but mine.
+1 rebase and merge aren't weird things that git does, they are fundamental to any version control system. They are pretty much necessary for collaboration or if you want to edit history.
> Removing a tool just invites developers to work around the gap.
This.
It's either a clean rebase, or messing the repo history with merge-commits, or merge with no ff and no commit onto HEAD followed by a local commit.
And rebase is far better and far cleaner and far simpler than any alternatives.
And rebase starts to become necessary as soon as two or more people start to work on the same mainline branch. After all, what rebase does is help get your branch (local or remote) updated and tied to the HEAD of a branch without screwing up the commit history. Isn't this one of the most basic usecases for a CVS?
> if you are using rebase as intended, that means you are keeping private branches. Or, to put it another way, you are doing siloed development.
My average PR represents maybe an afternoon of work before it's reviewed and merged and shipped. With such short-lived branches, siloing isn't a big deal.
I'd suggest that shipping multiple times a day renders rebase's harm pretty irrelevant.
But if we flip that around, are we shipping multiple times a day because we lack tooling and workflows for non-silo'd development? We ship PRs quickly because a long lived PR is hard to maintain and keep up to date. If that wasn't a problem, would we ship less often?
I too have thought about this stuff. In many instances, the correct solution depends on the context of the work being done. Are many people working on interrelated parts of the same project? Or, is there a small group of people jumping from one project to the next in any given day with multiple people collaborating in branches at the same time?
> 3.0 Rebase encourages siloed development
You need a strong culturally enforced habit of "commit early, commit often ... rebase early, rebase often, push early push often" with all development happening in branches that are visible to everyone (GitHub, GitLab etc) to avoid this.
I conceptually like a main branch with a clean straight-line history with no merge commits and clear commit messages. It takes discipline. The discipline is helped by a cultural environment where anyone can request changes in any PR, where teams, not individuals, own projects, where clarity of the commit message is equally important as the code, and where is a strong preference for short-lived branches and small PRs.
I also recommend opening a PR as soon as a single commit has been made in a branch and announcing the PR in a dedicated channel so everyone has a chance to follow the development.
This kind of thing is not going to work in every type of project in every organization, but I have developed a preference for it.
Personally, I like merge commits. I often merge feature branches even if I could do a fast-forward, because the merge commit explicitly documents the set of patches that made up a feature. The question isn't really about merge vs. rebase; you should use both.
There's absolutely nothing wrong with a merge commit that says "merge feature-xyz into master"; you get a neat side path in the commit graph that contains the changes that made up xyz. Once you merge a branch however, you should delete it. Don't merge branches multiple times, and don't merge master into your feature branches.
You want to think of features as sets of individual logical changes, ie. patch series. I nearly always rewrite the commits in a branch before I merge it, to create a clean patch series. That usually means I also rebase the changes, but it's not always necessary.
One of the major reasons I use git for source control whenever I can is that 100% of its features are available at any time for me to use in any way I wish. Rebase allows me to make commits for whatever reason I want at any time, and it's useful because losing committed data is really hard.
When I'm writing code, I put very little effort into how to structure my changes into commits; That's done when I'm preparing a PR or a patch series, when I'm out of the coding mindset and in the "how do I make this reviewable" mindset. When you're contributing to a project, these are two separate tasks that require different approaches. Any false starts and experiments should be documented and expanded on in this phase, because you're communicating with other people. Pushing a series of crappy "asdf" commits on people because "it documents the development process" is lazy and rude.
A tool that requires me to have perfect commits immediately is useless, because getting commits perfect the first time you actually need to commit is not possible.