You could think of GitHub as the umpire in a sort of complicated game of tennis involving three players, except they will be bouncing around files instead of tennis balls. Files get stored in a repository (repo for short) which is like a separate locker for each project. The repo also stores each file’s revision history.
The three players are:
⦁ Upstream – the “official” project files that live on the main repo in GitHub,
⦁ Origin – your fork of the project files that live in your GitHub account, and
⦁ Local – the files on your local machine where you will be making your changes.
The objective of this tutorial is to show you how to contribute to an open source project by working on files from some remote repository and then submit them (make a pull request) so they can be merged into the “official” project. It is important to understand the interaction between the three players at all stages in this process. The diagram above will be used throughout this tutorial to illustrate the various exchanges. Boxes are shown in blue when they are synchronised with the current official repo; red means they have got out of sync; green is used when the upstream repo has been changed.
Note that for some repositories (including ClassicPress) the default branch is develop rather than master, so you’d use develop everywhere the instructions say master.
STEP 1 – Fork the “official” files
You obviously can’t work directly on the main project files, so you first need to take a copy of them to your own GitHub account. This is called a fork and it involves copying the files from the “official” repo (upstream) to your own account (origin).
STEP 2 – Clone the fork to your local computer
In order to work on the files easily, you will need to make another copy on your local machine. You can do this by cloning the files from origin. Note that all players are still in sync.
git clone https://github.com/user/repo.git
STEP 3 – Create a branch, work on some files and commit the changes
Now, it’s time to get to work and start making your changes to the file(s). You should do this in a branch; this keeps your workspaces separate and manageable. Once you have created a branch, make quite sure it is your current active branch, then go in and start work. You can commit these as you go at any time. GitHub will keep track of everything and it’s easy to roll back to a previous commit. Your local files will now be out of sync with origin and upstream.
# Create a LOCAL branch "feature-x" git checkout -b feature-x # optionally push your new branch to ORIGIN git push origin feature-x # You can see all the branches created git branch -a # Now you have changed something and want to commit # See what is changed git status # Commit your changes: let's git decide what's changed git commit -am "Here my commit" # Commit your changes: decide what to commit git add mynewdir git rm myoldfile git add mynewfile git commit -m "Here my commit"
Step 4 – Publish your changes to origin when you are done
When you are happy with the changes you’ve made, you can publish (push) them to your GitHub account. Now both local and origin will be different to upstream.
# Push your commit(s) to ORIGIN # First push git push --set-upstream origin feature-x # Then just git push
Step 5 – Create a pull request
A pull request (PR) sends a message to the people who maintain the “official” repo, asking them to consider adding in your edits. There is probably a form template that you will need to use, to show you’ve followed the correct coding standards and done all the necessary tests. Maintainers may ask questions to clarify the changes, how they have been tested, or they may ask for some revisions. This process may take take a while because people are busy, but it’s acceptable to ping someone on your PR and ask them to take a look.
Step 6 – Make some revisions to your PR
Sometimes you might find the need to make some extra changes to your initial pull request, or perhaps the maintainers of the “official” repo have suggested you make some revisions. It’s recommended NOT to open a new PR for this – just do another commit to your file(s) in local, push to origin, and your latest changes will automatically flow through to the existing PR on upstream.
git add file-i-have-changed git commit -m "Ok, this is my revision" git push
Step 7 – Wait for merge
If all goes well, you will get a message to say that your edits have been approved and merged into the main project. Note that in the diagram below, you are still not in sync with the “official” repo. This is because your edited files still live in branches and your main (default) branch is now out of date. Other people may have been making changes to the upstream files as well.
Step 8 – Fetch the new upstream files and merge into local
You now need to update the files in your local computer to reflect the new “official” repo files. You do this by fetching the upstream files to local and merging them in with the files there (it’s a good idea to do this regularly, to keep up with all the changes). You can also delete the branch as this is no longer required.
# Check if is already here git remote -v # If it's not, add it git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git # Fetch the branches and their respective commits from the upstream repository. # Commits to master will be stored in a local branch, upstream/master. git fetch upstream # Check out your fork's local master branch git checkout upstream/master -B master
Step 9 – Push the new files in local to origin
Finally, you need to update the files in your GitHub repo by pushing the new files in local up to origin.
# Push to origin git push origin master
All players are now back in sync. Game, set and match!