Wandering Thoughts archives


My take on Git rebasing versus cherry-picking

As I've noticed recently, there's a number of git problems that can be solved by either git rebase or git cherry-pick. Because I love git rebase I started out feeling that I should solve all of my problems with it (and resorting to 'git cherry-pick' was a weakness), but I've wound up convinced that sometimes this is wrong. However, until very recently I didn't feel that I understood when I wanted to use one or the other; instead it felt like I was making it up as I was going along. In large part due to learning from Aristotle Pagaltzis's useful comments here, I've now wound up with my take on when I want to try to use one versus the other.

Put simply, my take is that:

Git rebasing is for moving commits while cherry-picking is for copying them.

An obvious case of moving commits is 'git pull --rebase'; I'm moving my commits from the old origin/master to the new one. Ultimately what makes something a move is that I don't really care about the old versions of the commits I'm rebasing; I'll only go back to them (via the reflog) if something goes badly wrong (for example, perhaps the new upstream version I pulled is broken).

(If I look at rebasing as moving commits, git rebase always updating the current or target branch makes sense. The kind of things where I'd want to leave the 'source' of the commits intact is not a move.)

Generally if I want to leave the old version of my local commits around as well as have a new version, that's a copy instead of a move. At a mechanical level I may use 'git rebase' after the 'git cherry-pick' to reorder commits and so on, but I'll start with a cherry-pick. One case that I've come to see as a copy instead of a move is transplanting my local changes on top of another branch in order to use it for various reasons. This covers both the 'switch from development to stable branch' and 'switch from mainline to someone's experimental changes' cases in my collection of git tree shuffles I was uncertain about.

I've also realized that this describes what I want to do when I'm working with Github pull requests. My old writeup used 'git rebase', but it was clearly awkward; any time I'm making a branch and then later changing its upstream is a warning sign. A much simpler approach is to pull down the PR(s), check the appropriate one out as a new (local) branch, and then simply cherry-pick my changes on to it with 'git cherry-pick origin/master..master'.

(This makes working with PRs the same as working with any other branch, which is really what I'd expect. If I want to cherry-pick when I'm moving from development to stable or stable to development, I want to cherry-pick for PRs too.)

programming/GitRebaseVsCherrypick written at 22:14:53; Add Comment

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.