Thursday, November 29, 2012

Working with Your Rails GitHub Fork

Note: Some of the commands listed here can really do some damage and screw you up, so be careful and learn what you are doing before blindly executing things.

Lets say you've read the great reference doc, Contributing to Ruby on Rails, and just forked Rails in Github, want to clone it locally, and want to keep it updated.

First clone it:

cd ~
mkdir github
cd github 
git clone git@github.com:my_user/rails.git
cd rails

Now you want to setup a remote to the original repo to fetch from later to update your copy:

git remote add rails git@github.com:rails/rails.git

Rails changes a lot. To update your version and apply any current changes on top of it, first you need to fetch and then rebase. Since we called the remote "rails" since that is the name of the user in Github. (If we had forked from https://github.com/twitter/bootstrap then we would have called it "twitter"):

git fetch rails

Check to see what branch you're on:

git branch

Let's assume you are on master, so:

git fetch rails
git rebase rails/master

Working directly with your master branch (not recommended)

The easiest thing to do is to work in your master. This is problematic, but it is what many might do at first, so let's see what that involves...

As you continue to work on it, if you want to get the latest and apply any changes you made atop it, you'd do that again.

So, again to check to see what branch you're on:

git branch

Then assuming you are in master:

git fetch rails
git rebase rails/master

That covers keeping everything up-to-date. So, let's assume you made some changes, added them, committed them, and pushed them (to your GitHub fork). Then you discussed it on the Rails core list/google group, did a pull request, and the core team decided not to take your contribution. You don't want to get rid of the commit, because then people wouldn't be able to see your commit in Github when looking back at the denied pull request, just in case they want to use some of your code themselves. But you need to get master looking like the original master Rails.

First find the long hash key of the last commit before your changes were applied. Please be sure to fetch and rebase first so we have the best chance to be fully up-to-date. To find the commit hash of the last guy outside of you (and your team if more than one worked on your rejected commit(s)) that made the last commit to remote Rails master:

git log

Then reset your head to that commit, which will abandon that/those commit(s) you made locally:

git reset --hard (put hash of most recent commit that wasn't yours here)

Then push this back to your fork, abandoning that/those commit(s) you made. This assumes that Github is origin (you can look at .git/config if you want to check) and that you are pushing to the master branch in your rails fork:

git push -f origin master
Painful, huh? Well, not too bad, but if you need to work on two different Rails patches at once, that won't work. So let's talk about the other way...

Working in feature branches in your fork and then doing pull requests from it to Rails master (recommended)

First create a remote feature branch. I like the gbranch command from my git-scripts project, so I'll show what it looks like if using it:

gbranch add_something_incredible_to_rails
If you are working in your branch and want to keep it up-to-date with remote rails master and apply your fork's feature branch changes on top, do:

git fetch rails
git rebase rails/master

So, let's assume you made some changes, added them, committed them, and pushed them (to your GitHub fork). Then you discussed it on the Rails core list/google group, did a pull request, and the core team decided not to take your contribution. Don't delete that branch because it will be referenced from the pull request in GitHub and people might want to take a look.

When you want to do another new feature, just gbranch again, and at anytime use gbranch to switch between features.

Thanks to:

No comments: