Skip to content

Instantly share code, notes, and snippets.

@tylergaw
Last active February 13, 2019 20:02
Show Gist options
  • Save tylergaw/81a7a684ad8e3451cbf61137179293f2 to your computer and use it in GitHub Desktop.
Save tylergaw/81a7a684ad8e3451cbf61137179293f2 to your computer and use it in GitHub Desktop.

Example of a Git cherry-pick and rebase flow

Often when working on a feature branch, I'll make a commit or commits that are useful outside the immediate scope of work for that feature. And at the same time, that feature branch needs more time to get finish, but I need to get the commit(s) into master either to ship them or to help other feature branches.

Here's a flow I use to get those commits merged to master without trying to fast-track the original feature branch.

In this scenario I have a feature branch named new-feature-a. I've made a handful of commits related to feature-a and two that are useful for feature-a, but also useful for other work. I want to get those two into master now before I'm ready to merge feature-a.

Cherry Pick Flow

Make sure I have the latest master out of habit

git checkout master
git pull

Create a new branch from master

git checkout -b useful-commits

Now I use git cherry-pick to grab the commits from the new-feature-a branch and put them in the useful-commits branch. First, I need to know the commit hashes of the commits I want. I find the commit hashes either using git log or by looking at the commit history of the new-feature-a branch. Both give me the same info, it just depends on how my brain is working.

To use git log, I check out the feature branch and view the log:

git checkout new-feature-a
git log

In the log I find the two commits I want and copy paste their commit hashes somewhere for later, usually just textedit. I'm not fancy. For these purposes we'll pretend the hashes are:

123456
789012

Now, hop back to the useful-commits branch to cherry pick the commits:

git checkout useful-commits
git cherry-pick 123456
git cherry-pick 789012

Note: git cherry-pick does accept a range of commit hashes, but I still do them one at a time just out of habit.

After I cherry pick, I do a quick check of git log on the useful-commits branch to make sure the commits are in the log as expected.

Useful commits to master

I now have the useful-commits branch where I want it, it's ready for merge. I follow a standard PR/review/merge to master process. On merge, I promptly delete the useful-commits branch using the Github UI because the branch is merged so no longer needed and omg please delete your branches when you merge to master.

Rebasing the feature branch

The useful commits are now in master. Anybody else with feature branches can rebase to master or merge master into their branches and they'll have access to those useful commits. new-feature-a is in a slightly different state but we'll still use rebase to reconcile.

Again, make sure I have latest master and clean up a bit:

git checkout master
git pull --prune
git branch -D useful-commits

Things may be a little odd here depending on your commit history. In master we've now made the changes to the files we want with useful-commits. Those are in master under whatever commit hash they ended up the the PR merge. But we also have those exact same file changes in new-feature-a with different commit hashes. Notice I'm differentiating between "file changes" and "commit hashes". That's what makes this a little different. It may not cause any trouble, but it's good to understand in case you run into rebase conflicts or other git weirdness.

In this scenario, we've continued to work on new-feature-a and at the same time master has had a number of new merges made to it. We want to catch new-feature-a branch up to master:

git checkout new-feature-a
git rebase master

Again, this will be different depending on commit history, but in my case, the rebase completed without conflict. With rebase you will likely see a message like:

Your branch and 'origin/new-feature-a' have diverged,
and have 7 and 8 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

That's OK, but know that diverged commits mean you'll need to force push. Because the local new-feature-a is now gospel. If multiple people are working on new-feature-a let them know you're about to force push so you all can coordinate and nobody loses work/half a day with git conflict madness.

git push -f

A good thing to look at to understand what we've done with this cherry-pick and rebase is to: git log. You should notice that the useful commits from before 123456 and 789012 are no longer in the log for this branch, but should be at an earlier state in the log under a different commit hash from where we merged them into master. Neat! We're rewritten history with rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment