Why I maintain my private changes to upstream projects via rebasing
I recently wrote an entry on VCS history versus large open source development, where I argued that mostly requiring contributors to rebase their changes was a sensible approach there. Recently this came up on Twitter and I said also that I used rebasing for carrying private changes on top of upstream projects. So let's talk about that.
If you carry private changes for an upstream repository, you have
three broad approaches. First, you can maintain your changes outside
of the VCS and "rebase" them when pulling upstream updates. Second, you can commit your changes
into the VCS and merge whenever you pull updates from upstream.
Third, you can commit your changes into the VCS and use '
rebase' or the equivalent when pulling updates to rebase your
local changes within the VCS.
Maintaining your changes outside of the VCS has various pain points, especially if you're maintaining multiple changes that you want to keep separate from each other. I've worked this way in the past and after trying both ways, I find that committing my changes is better when I can do it, especially when I have multiple separate changes. Sure, I could use quilt to maintain a patch series, but that's essentially using a VCS on top of another VCS and I'd rather use only one.
(In practice, I just don't bother to keep the changes separate because it's too much work. I count on my fallible memory to keep straight what I've done and what code change is part of what modification.)
Combining your changes and upstream's changes through VCS merges has the primary downside that your local repository history gets increasingly messy. Every time you pull, you get an extra merge, and these merges persist forever. If you want to use the VCS's commit history to look at the upstream development, you need to carefully prune out these merges and all of your side excursions off of them.
Rebasing in your VCS avoids both sets of pain points. The VCS history remains clean, you get to use the VCS to manage your own changes, and you can often capture a better history of your changes (if you care) than you can when you maintain them outside of the VCS through means like adding a local tag for your post-rebase state after every pull.