Git Workflow

In this week's video, Chris is joined by Josh Steiner to discuss the git and github workflow we use here at thoughtbot. We'll cover feature branches, pull requests, rebasing, and finally merging our new feature into master! thoughtbot dotfiles G...
This is a companion discussion topic for the original entry at


In the video the pull request is created first and then the rebase is performed. Why that way round rather than rebase first & then pull request?


Hi @brightchimp. Normally we would rebase before creating the PR if we were aware that master had diverged.

Often though, the PR is created and while waiting for or responding to feedback someone will merge into master. We then have to rebase and force push to the branch as demoed in the video. Since this is the slightly more complicated (and real) scenario, we decided to demo that rather than the more straightforward.

Hope that clarifies it.

Yes, it does. Thanks :smile:

@christoomey Do you do rebasing and pull request when you are working on your own project by yourself? I am not sure what benefit it will have since I work mainly alone. Would you recommend these workflow even when you work alone, perhaps for better logging?

Hi @antwonlee, thanks for the questions. Short version: yes, I follow largely the same process if I am on a solo / personal project as I do on client projects with a thoughtbot team.

Longer answer:

  • Commit Messages / History - I value having a clear history that fully captures the context of a change. I want to be able to answer “why did I make this change” and “were any other solutions considered”. While this is useful for teammates, I’ve consistently found this useful for myself when I’m a few months passed making a change.
  • Squashed History - Similar to above, I want a clean history that tells the story of the changes I made, but I don’t care about all the little commits and refactorings. Commits live on if they pass the “would I want to be able to return to this commit on it’s own” test, and few do, so most commits for a feature are squashed down.
  • Linear History - Similar again. I’ve never found value in merge commits so I always rebase and merge --ff-only.
  • Pull Requests - I do in fact use PRs when working on solo side projects. This is largely due to the fact that I’ve become so used to doing code review on GitHub that I find keeping that workflow and using their interface helps me switch hats and review my own code. Sort of a Pavlov’s dog thing.

Another aspect of this is while the above may sound like much more work, I’ve honed my workflow over the years to make the above nearly automatic, so I don’t perceive any extra work to go through the full process. Keep your eye out for some new Git content coming to Upcase soon that will better cover all of this!


Man @christoomey , I appreciate your discipline so much. While it might take more time, I am so convinced to log better like this. Thanks again for sharing this workflow. I watched it like 10 times last nigh. I am pumped that you guys are in a process of making more Git content!

@christoomey I’m confused at around 16:15 about the merging of the feature branch and master.

I guess my confusion can be summed up into two scenarios.

  1. Let’s say, I’ve forked a repo, created a feature, committed, rebased, created a pull request and now I’m waiting for code review. But I now want to continue working on a new feature, feature #2. How would I go about restarting the process of creating a new feature with an already outstanding pull request? Do I merge my local commits into my local master? Will that mess things up?

  2. Let’s say another team member has created a pull request. How do I approve and merge this pull request into master? In the video it seemed like one command merged github’s master branch with the new feature, as well as, locally.

Of course if you’ve already covered this in another git video, a link would be awesome. Again thanks for the video, these are absolutely the highest quality tutorials on the web.

Thank you, guys!

Hi @thedanotto. In response to the two scenarios:

Let’s say, I’ve forked a repo

As a small note, I very rarely work with forks. It certainly happens with open source where you’re not a contributor, but just to make sure this is clear, I strongly recommend all team members working against a single common origin repo when collaborating, as opposed to maintaining individual forks on GitHub.

But I now want to continue working on a new feature, feature #2. How would I go about restarting the process

I’d create a new branch based off of master, e.g. git checkout -b feature-2 master. For any feature branch, whenever I’m ready to work with it I’ll pull down current master and rebase, then eventually merge. If I merge feature-1 and then move back to feature-2, I’ll then rebase feature-2 onto master. Ideally we’re targeting master being a single fast-forward only history, despite whatever was going on when we first worked on our features. Rebase is the magic that makes this possible. Some folks are weary of “changing history”, but I view my feature branches as WIP, and eventually I squash & rebase and adjust when ready to merge.

Let’s say another team member has created a pull request. How do I approve and merge this pull request into master?

Typically I don’t merge other folks PRs, but let’s say that your colleague has merged. You can then pull master which will now have their changes, and then you can rebase any local feature branches onto those changes, catching you up.

Hope that clarifies! If you’re still struggling to conceptualize how all this works, I’d highly recommend checking out / revisiting the Git Object Model and Object Model Operations videos which go into detail on how git stores data, and how the various operations interact with the git repo.