GitHub Workflow: Contributing with Open Source Projects

This week I made my first contribution to a ruby open source project, devise, the well known, flexible authentication solution for Rails with Warden.

When working on open source projects it’s very important to have a well defined git workflow. Having a well defined workflow will help you to indentify changes on your code easily, revert changes without losing your work, test your ideas without putting your main project at risk, be more organized and so.

You may find several guides talking about git workflow and different ways to accomplish what this post tries to explain. Bear in mind that given git’s flexibility you can achieve the same results in different ways.

Summary #

  1. Fork the project you want to collaborate with
  2. Clone your project’s fork to your local drive
  3. Add the original project git url to your fork’s remote list
  4. Create a new branch and commit your changes
  5. Pull the changes from the original project’s repository
  6. Rebase your master with your new branch and fix conflicts if necessary
  7. Push your new branch
  8. Go to the original project’s repository and create a new pull request

1. Fork the project you want to collaborate with #

Go to the project repository’s web page and! click on the Fork button.

2. Clone your project’s fork to your local drive #

Go to your project’s fork and you’ll find the Clone Section, that looks like this:

Copy the SSH url. GitHub suggest you to use the SSH over the others, but you could use GitHub Mac or Windows client or whatever solution fits your needs.

Now that you’ve copied the SSH url, go to the console and do:

$ git clone git@github.com:<username>/<project>.git
# Clones your fork of the repository into the current directory in terminal
#
# <username> it's your github's username
# <project>  it's the name of the github's project

3. Add the original project git url to your fork’s remote list #

When a repository is cloned, it has a default remote called origin that points to your fork on GitHub, not the original repository it was forked from.

To keep track of the original repository, you need to add another remote named upstream (that’s the convention).

You need to do this in case you need to retrieve new changes from the original project’s repository.

$ cd <project>
# Changes the active directory in the prompt to the newly cloned project directory

<project> $ git remote add upstream https://github.com/<username>/<project>.git
# Assigns the original repository to a remote called "upstream"
#
# <username> it's the github's username from the original project's owner
# <project>  it's the name of the github's project

<project> $ git fetch upstream
# Pulls in changes not present in your local repository, without modifying your files

4. Create a new branch and commit your changes #

Branching allows you to build new features or test out ideas without putting your main project at risk.

In git, branch is a sort of bookmark that references the last commit made in the branch. This makes branches very small and easy to work with.

<project> $ git checkout -b <branch>
# Creates and positions you on that new branch
#
# <branch> it's the name of the branch that will store all the changes you make

<project> $ git add .
# Tracks your changes

<project> $ git commit -m 'Some changes'
# Commits your changes

Now we can start developing our new feature.

5. Pull the changes from the original project’s repository #

After we finished developing our new feature, we need to check if they were any updates on the original project’s repository and get the latest version of the master branch.

<project> $ git checkout master
# Make sure before pulling changes that you are on master branch

<project> $ git pull --rebase upstream master
# Updates our master branch with the latest version of the original project's master branch

6. Rebase your master with your new branch and fix conflicts if necessary #

Now that we have our master branch up to date, we need to rebase it with our new branch where our new feature is.

<project> $ git checkout <new branch>
# Make sure before rebasing changes that you are on new branch

<project> $ git rebase master
# This will rebase your new branch with your master branch

If they were any conflicts during the rebase process, solve the conflicts and commit the fix.

7. Push your new branch #

So now that we have our new branch up to date, we are going to push it to GitHub.

<project> $ git checkout <new branch>
# Make sure before pushing changes that you are on new branch

<project> $ git push -u origin <new branch>
# Pushes your local new branch to your fork's repository
#
# -u option tells git to link your local branch repository to the remote branch you
# created, you only need to do this the first time you push, for future pushes,
# just write 'git push' and git will know what to do
#
# <new branch> it's the name of the branch you were working on

8. Go to the original project’s repository and create a new pull request #

After you pushed your new branch to GitHub. visit the repository you pushed to. Select your new branch and click on Compare & review button.

This is an example of a pull request of our 'alias_methods_' branch to devise

You’ll land right onto the compare page. You can click Edit at the top to pick a new branch to merge in, using the Head Fork and Compare dropdown.


Select the target repository and branch your branch should be merged to, using the Base Fork and Base dropdown.

Review your proposed changes and click on Click to create a pull request for this comparison

Enter a title and description for your pull request and click Send pull request.

That’s pretty much how it goes. Remember that you can do the same in different ways. Hope it helps you.

References #

GitHub: Fork a Repo

 
33
Kudos
 
33
Kudos

Now read this

Strong Parameters The Right Way

StrongParameters is a great gem and it comes with Rails 4 by default. Currently, there are two patterns to work with your attributes. 1. Creating a private method on your controller which returns the whitelisted attributes. # #... Continue →