Fork, Branch, and Pull - A Concise Git Workflow

Published: Aug 22, 2017

This post feature image

Here’s a super concise workflow for contributing to an existing Github project. In this guide, you will learn how to fork a project, branch a new feature or big fix, and contribute to the original project.

Initial Steps: Fork, Clone, and Add Upstream

Head over to the Github page you want to contribute to and click the “Fork” button. Copy the url to your forked repository and then from the command line:

git clone<username>/<forked_repo>.git

Track the original upstream repository, by adding a remote and then verifying:

git remote add upstream<original_repo>.git
git remote -v

Stay in Sync with Upstream

If you just did the above steps, you can create a branch and start working. Otherwise, it is a good idea to make sure you are up-to-date with the upstream repo’s latest commits.
Fetch upstream and view all branches

git fetch upstream
git branch -va

You then want to checkout your master branch and merge it with the upstream repo:

git checkout master
git merge upstream/master

You should not have any unique commits on the local master branch (since in this guide, we are doing commits against a separate branch). So Git should perform a fast-forward and bring your local master branch up-to-date.

Branch and Start Working

Before creating a branch, it is always nice to make sure you are branching from your local master. So first run:
git branch, to see if you are on the master branch, and if not: git checkout master

Now create a new branch and check it out:

git branch newfeature
git checkout newfeature

Now you can make changes using the normal Git workflow with git add and git commit

Refetch, Merge, Rebase, and Squash

If this is a quick change, you can get away without doing this. But it is nice to ensure your local master branch is up-to-date with the upstream repo. As before:

git fetch upstream
git checkout master
git merge upstream/master

This brings your local master up-to-date with the upstream repo. And if any new commits were made upstream, you can now rebase them. This means the upstream repo’s commits will be applied first, with your newfeature branch’s commits re-played after the aforementioned upstream commits. This will make your eventual pull request much easier for the developer to review and merge. Here are the commands:

git checkout newfeature
git rebase master

It is also a good idea to squash your smaller commits into a larger one:

git rebase -i

This will bring up an editor where you can squash your commits. If you had 3 commits, you might see something like this:

pick 01d1124 Commit Msg 1
pick 6340aaa Commit Msg 2
pick ebfd367 Commit Msg 3

If you want to squash these commits into a single one, you might do something like this:

pick 01d1124 Commit Msg 1
squash 6340aaa Commit Msg 2
squash ebfd367 Commit Msg 3

… which will lead you to another editor where you can edit the commit message to something that describes all the changes made. A good commit message should have a title/subject in imperative mood starting with a capital letter and no trailing period.

Push, Pull, and Delete

Now push your changes to your repository:

git push origin new-feature

You can then go to your forked repository on Github, find your branch and make a pull request. You can review the changes before you submit it. If the upstream repo’s owner approves and merges it, Github will prompt you to delete your branch, which is safe to do now. Remember your forked master is now out-of-date and requires a fetch, checkout, and merge (see earlier step), which updates your local repository. Then do another push to update your remote forked repository.

Previous Post

The Stillness is the Move

After all that we’ve been through I know that I will always love you... From now until forever baby... I can’t imagine anything better. After all that we’ve been through! I know we’ll make it, I know the way The question is it true... There is nothing we can’t do I see you along the way baby...

Next Post

Introducing Bunsenlabs

The spiritual successor to the very-much-missed Crunchbang Linux.