This is a step-by-step guide to extending an open source project on GitHub and contributing back to the original as well as other forks of the project. You will learn how to build off of older commits as well as how to push changes to other forks that might be out of sync with the original project.
Before we get started lets familiarize ourselves with some basic terms
Start by forking the repository that you want to suggest changes to on Github. This will create a fork of the repository in your account. Typically you will only have read-only access to other repositories. Making a fork of a repository will make a copy of it with write access. You will be using this repository to make changes, test them and creates PRs to the original fork as well as other forks of the repository.
This fork will be your remote origin
Making a local copy a.k.a cloning
Next you will make a local copy of your GitHub repository on your computer where you can make changes on it.
git clone <repository url from your fork>
You can clone using SSH or HTTPS URLs. I prefer using SSH over HTTPS as it helps set-up the local repository in fewer steps. In order to use SSH, you will need create SSH keys and update them in GitHub so GitHub can recognize your local computer.
Check your git config
git config -l
remote.origin.url=<url of your repository>
Ensure that you can see these settings. Your name and email will be used to to identify your commits.
Adding remote repositories
It is a good practice to let your local git know of the original repository so it can keep track of other branches as well as allow you to create PRs with other forks. Run these commands from within the root folder of your local repository
git remote add <local name for repository> <remote repository URL>
git remote add lprhodes git://github.com/lprhodes/homebridge-broadlink-rm.git
You can add other forks of the original as remotes as well if you wish to port the changes to those repositories as well.
git remote add ababel git://github.com/AlexanderBabel/homebridge-broadlink-rm.git
You can confirm your settings using either of these commands
git config -l OR git remote -v
So you can now start making changes that you are interested in. You can make changes on the last commit or you can move back to a previous commit and make changes to that.
If you wish to move back to a previous commit, you can run git log to see list of all commits to find the hash id of the commit
If you want to temporarily switch to it, you can then run git checkout -b <new_branch_name> <commit_id>
If you want to reset the HEAD of your repository back to the old commit and start making changes on that you will first change your local copy to the that commit and then push the changes to your repository. This is useful when your origin has bugs in the latest release and you want to build on top of an older commit rather than a buggy commit.
git reset --hard <commit_id_A>
# Force master branch @origin to update to current local master. This deletes
# all commits newer than commit_id_A from the master branch on origin
git push --force origin master
Next you have two options to create changes
Option 1: Direct commits to master
Open the file in your favorite editor, make changes and save them.
Option 2: Create a new branch and commit to that (preferred)
git branch <new_branch_name>
Open your file in your favorite editor, make changes and save them. This option will allow you to create a pull request (and review) from the new branch into your master branch on origin and review your changes in GitHub before merging them into master.
You can bundle your changes, “stage” and “commit” them so you can push them to your remote repositories.
Stage: git add <file names OR .>
Commit: git commit -m “<commit message”
Once you have tested your changes and are satisfied with it, you can update your server hosted repository aka origin by running the following command
# Finishing your changes with Option 1 (Direct commit to master)
git push origin master
By default when you push your changes to git they are sent to your remote origin. If you used option 1 above then your changes are directly merged into the master branch.
# Finishing your changes with Option 2 (using a new branch)
git push -u origin <new branch name>
If you used option 2 then the git push command will create a new branch at origin and push your commits into that. You can continue with the PR and merge using GitHub Desktop app or
For creating PRs on github.com, go to your repository page on GitHub and then click on branches at the top to view all branches
Click on branches to see all branches including the newly pushed branch
Find your branch and click on new pull request. In the next page, select your master branch of your repository as the head and the new branch on your repository as the base. Review your changes and create a pull request. You can now see a new pull request on your pull requests page
Click on pull requests to see the newly created pull requests
Once you navigate to your newly created PR from the Pull requests page, you can review it and merge it with the master branch.
Porting changes to the forks
Now that you have pushed your changes to your origin, you may want to apply this change to other forks. If you have used Option 2 then you will have your work on a new branch and you can create pull requests by going to the branches page and clicking on the new pull request button.
Once there you can select the destination repository that you want to suggest the changes to as shown below.
Here base is the repository that you want to suggest changes to and head is the repository where you already have changes. In the above example we are comparing and requesting to merge newt10/homebridge-broadlink repository @ branch babel_master_fan_step into lprhodes/homebridge-broadlink @ master
Fork is out of sync with the original repository
In this case the changes that you have made based on the original repository might not be directly compatible or merge well with the other fork “Fork B”. When you try to create a PR you will see multiple commits that are far greater than the changes you made due to this.
In order to limit the changes to your commits only.
git checkout -b <new_branch_name> <remote__other_fork_branch>
git checkout <remote_other_fork_branch>
git branch <new_branch_name> -u <remote_branch_usually_master>
This will create a new local branch called “new_branch_name” and adapt your workspace to the head of “remote_other_fork_branch”
You can now select the commits that you want to apply to this new branch
git cherry-pick <commit_id>
If there are any merge issues fix them using the guidelines .
Now you can push this new branch to your origin so that you can go to GitHub and create PRs
git push -u origin <new_branch_name>
Once you have the new branch available on GitHub use the steps above to create a PR with the fork that you want to suggest changes to - in this case the other fork “Fork B” that you based your branch on.