Over the summer, Social Innovation Simulation will be posting a series of technical tutorials designed to acquaint those interested with some of the technologies we’re working with.
This tutorial describes how you can use an online code repository called GitHub to store each working version of your code, and share your code with others.
Estimated time: 40min
Dependencies: Basic knowledge of bash or ssh code
GitHub Tutorial
- Introduction
- What is GitHub and why is it useful?
-
Overview of GitHub commands
- Tutorial:
-
Setup
-
Creating a repository
-
Adding files to your repository
-
Pushing your changes to a remote branch
-
Pulling changes someone else made and merging them with your work
-
Creating a local branch
-
Making changes on a local branch and merging those back into your local master branch
-
Look at your commit history
-
Bonus: Creating a new remote for a different remote repository
-
-
Deliberate Practice Challenge
- Resources
Tips for going through the tutorial:
- We will be following and example throughout the tutorial and showing what you should see in your command line terminal, with any comments in square brackets [ ]. All the example code will be in sections that look like this:
[example comment]
example - All the commands that you should use for the tutorial are found in the sections that look like this:
example
Introduction
What is GitHub and why is it useful?
GitHub is a Version Control System (VCS) that allows you to share your work with others online through their website.
The reason that GitHub is much better than something like GoogleDrive for sharing code is that it allows you, very easily, to make local changes to a project without affecting the main project branch. The idea behind this is that you can try out changes and play around with the code without having to worry about breaking the whole project since there will always be a working version on the main project branch that you can go back to.
You can even save your changes locally so that if you get so much work done on your changes (none of which break the project) and then end up changing something that causes the code to fail you don’t have to redo all your previous work.
Overview
GitHub uses repositories to store your work (basically folders online). Git uses the commands “push” and “fetch” to interact between your local copy of a repository and your remote copy (on the GitHub website). The “fetch” command will bring any new changes that other people have made to the remote repository to your local one and the “push” command will add any of your local changes to the remote repository.
When once you have made changes locally these changes can be in 4 “states”: unstaged changes, staged changes, locally committed changes and remotely committed changes.
“Unstaged changes” is where every change starts and this is what state you want your changes in when you are still working locally. Once you are ready to add your changes remotely you move the changes to the “Staged changes” state using the “git add” command. This is where you decide which changes you want to add to your remote repository or to a new saved state that you can go back to. Once you have finalized these changes you move them to the “locally committed” state using the “git commit” command. This command creates a saved state of your last saved state (or commit) with all the changes you had staged applied to it. This command will only create the commit locally and won’t change anything in the remote repository yet. Lastly you can move the changes to the “remotely committed” state using the aforementioned “git push” command. This command takes any commits you have made since you last called “git push” and adds them to your remote repository. Now everyone else can see the changes that you made through your online repository.
When you first create a repository you are the only one that is able to add changes to it (although others will be able to look at your work if the repository is public). If you want to let others make changes to your repository you can go into the GitHub website, navigate to the repository you want to change and the go to Settings on the upper-right side of the page and then click on Collaborators in the menu on the left side of the page. You can then type in peoples’ usernames to allow them access to your repository.
GitHub works by having a list of all the commits you have made and then having different branches that point to these commits. By default there are 2 branches created in any local Git repository: master (which is your default local branch) and origin/master (which is a local reference to the main branch on your remote repository). You normally want to make sure that these 2 branches are pointing to the same commit and then if you are working on a project you can create a new local branch and make your changes there. Calling “git fetch” will update your origin/master branch to point to the latest commit from your remote branch. You can then use the “git merge” function to bring your local master branch to the same commit as the origin/master branch.
Once you have an account you can create your own repositories, copy other peoples repositories to your computer as to look at their work, fork someone else’s repository to create your own copy that you can change, and send pull requests from forked repositories to ask the creator of the original repository to merge your changes into the original repository.
Tutorial
-
Setup:
-
First create an account at https://github.com
-
Second download GitHub here: http://git-scm.com/downloads
-
Next follow the steps here to setup your environment https://help.github.com/articles/set-up-git (this will configure your local git settings with your name and email and will also install a keychain helper so that you won’t need to input your username and password every time you access a remote repository)
-
-
Creating a repository
-
The easiest way to create a repository is through the GitHub website https://github.com (I believe it can also be done in a terminal window but its more complicated)
-
Once there click on your username in the top-right corner and then click on the Repositories tab. There will be ra green New button on the right which will create a new repository for you. You can then pick the name, description and privacy settings of your repository (make this one Public so that everyone here can see it). You should check the “Initialize with README” box so that you can clone your new repository immediately.
-
Once you have created your repository, copy the path in text box near the top of the page (or on the right-hand side if you have the new version of GitHub), it should look like:
https://github.com/*username*/*repository_name*.git
-
Open up a Terminal (or Bash) window and navigate to the folder in which you want to save your repository locally (My Documents works).
-
Then use the command
git clone [http_git_repository_address]
substituting the path you previously copied for [http_git_repository_address]. This will create a new folder in your current directory which contains all the files of the remote repository and initializes Git commands with this directory and its subdirectories.
[if your repository was named sandbox]
$ git clone https://github.com/yourusername/sandbox.git
Cloning into ‘sandbox’…
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done. -
Now you should have a version of your new repository on your computer! Use cd to navigate into this new folder in the Terminal window and execute
git status
to verify that git is running.
$git status
# On branch master
nothing to commit, working directory clean
-
-
Adding files to your repository
-
Simple as adding files to any folder, you can copy them to your repository folder using Finder or Windows Explorer, or create them in the directory in a Terminal window. Keep in mind that even if you modify the folder locally it won’t show up on your repository on the GitHub website until you push your changes.
-
-
Pushing your changes to a remote branch
-
Now that you have added some files to your repository you can update your remote repository with these changes as well. Any changes using git will be done through a Terminal window so you need to open a Terminal and navigate to your cloned repository folder.
-
-
First you need to select the files you want to be changed in your remote repository (including any new files) and stage them to be committed (as discussed before). To see which files have been changed use
git status
and it will list the changes and what state those changes are in.
[After having created the file test1.txt]
$git status
# On branch master
# Untracked files:
# (use “git add …” to include in what will be committed)
#
# test1.txt - To add a file to be updated use
git add filename
$git add test.txt
$git status
# On branch master
# Changes to be committed:
# (use “git reset HEAD …” to unstage)
#
# new file: test1.txt -
You can also use
git reset HEAD filename
to unstage a staged change and
git add -A
command to stage all your changes.
$git reset HEAD test1.txt
$git status
# Untracked files:
# (use “git add …” to include in what will be committed)
#
# test1.txt
$git add -A
$git status
# On branch master
# Changes to be committed:
# (use “git reset HEAD …” to unstage)
#
# new file: test1.txt
-
Once you have selected the changes you want to add use
git commit
to create a new commit for those changes. This will bring you to a text file (in your default text Terminal text editor) where you need to write a description of your commit (ex. “My first commit”). Once you have written your description save the file and close it and your commit will be saved*.
$git commit
[In vim editor]# Please enter the commit message for your changes. Lines starting
# with ‘#’ will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use “git reset HEAD …” to unstage)
#
# new file: test1.txt
~
~
~[Once you have entered your commit message (in this case “My first commit”) and saved]
[master 20e7c82] My first commit
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test1.txt -
Finally use
git push origin master
command to push your changes to your remote repository. Note that in this command ‘origin’ is the remote name and ‘master’ is your local branch name. These are the defaults that are set up when you initialize Git so if you haven’t changed anything just use this command (we’ll get to changing these later).
$ git push origin master
Username for ‘https://github.com’: yourusername
Password for ‘https://yourusername@github.com’:
Counting objects: 1, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (1/1), done.
Writing objects: 100% (1/1), 309 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/yourusername/sandbox.git
dd12234..20e7c82 master -> master
*The default text editor for most command line terminals is Vim but you can change this by entering “git config –global core.editor your_favourite_editor” if you prefer a different on (like Emacs).
If you are using Vim to add text you must first press the [i] key then enter your text. Once you are done, to save press [esc] then type “:wq” and press [enter].
-
Pulling changes someone else made
-
Before you can push your changes to your remote repository you must always make sure that you have the latest version of that repository saved locally. If you are the only one working on the repository this is not an issue but since that is not normally the case you should make sure to get the latest version before pushing any changes.
-
To do this navigate to the local repository in your Terminal window and call
git fetch origin master
As discussed above this will let GitHub know locally all of the changes that have been made to the main project remote project branch.
-
You can then call
git merge origin/master
to bring your master (i.e. local) branch up to date with all the remote changes (from your default remote – “origin”). Your local branch is now up to date and so you can push any changes you have made to your remote branch.
[If you call these commands now, since there have been no changes, nothing will need to be updated]
$git fetch
$git merge origin/master
Already up-to-date
-
-
Creating a local branch
-
When you are working on changes for a project it is normally a good idea to keep a copy of the main project branch locally on your computer (in your local “master” branch), so you should always create a new branch to work off of if you are making any changes.
-
To create a new branch call
git checkout -b branch_name
which will create a new branch (which is a copy of your current branch) and move you to it.
$ git checkout -b new_branch
Switched to a new branch ‘new_branch’ -
To move to an existing branch call
git checkout branch_name
$ git co master
Switched to branch ‘master’
-
-
Making changes on a local branch and merging those back into your local master branch
-
Once you’ve created a new branch you can add files and commit the just like on your local master branch. Similarly, to update either your local master branch or any remote branches you must commit any changes you’ve made to you local branch (which is done the same way as before).
-
Once you have finished making changes on your local branch and you want to push them to the main remote branch you must first merge your changes into your local master branch.
-
Before doing anything you should switch over to your master branch and pull in any changes others have made (if you don’t do this some weird things can happen with your commits that you don’t want to have to deal with)
-
Once you have done that stay on your master branch and call
git merge branch_name
and then all of your changes on your local branch will be added to your master branch.
[Since we’ve already moved back to master we don’t need to worry about that step]
$ git merge new_branch
Already up-to-date. -
Now you can push these changes from your local master branch just like before and update your remote repository.
-
Finally you can delete your branch if you are done with it using
git branch -d branch_name
$ git branch -d new_branch
Deleted branch new_branch (was 20e7c82).
-
-
Look at your commit history
-
Now that you’re jumping back and forth between branches and commits it’s nice to be able to see what commits you have made so far. To view a list all the commits on your current branch use
git log
which lists each commit along with the commit hash (a hexidecimal number used to reference the commit), the name of the person who made the commit, when they made it and the commit description.
[We’ve created a second commit to illustrate more about how the “git log” command works]
$ git log
commit a8a0a471342f806894129e5b1d9d0a6fa581187b
Author: Your Name <youremailaddress@you.com>
Date: Fri Jun 28 16:37:27 2013 -0400My second commit
commit 20e7c82b161b986f4e603898f822f3ddc4e4616b
Author: Your Name <youremailaddress@you.com>
Date: Fri Jun 28 16:19:28 2013 -0400My first commit
-
You can also add options to this to change the view of your commits. To look at only the last n commits use
git log -n
$ git log -1
commit a8a0a471342f806894129e5b1d9d0a6fa581187b
Author: Your Name <youremailaddress@you.com>
Date: Fri Jun 28 16:37:27 2013 -0400My second commit
To see the diff for each commit (i.e. what was changed in that commit) use
git log -p
commit a8a0a471342f806894129e5b1d9d0a6fa581187b
Author: Your Name <youremailaddress@you.com>
Date: Fri Jun 28 16:37:27 2013 -0400My second commit
diff –git a/README b/README
index 9daeafb..e2a082d 100644
— a/README
+++ b/README
@@ -1 +1 @@
-test
+ testcommit 20e7c82b161b986f4e603898f822f3ddc4e4616b
Author: Your Name <youremailaddress@you.com>
Date: Fri Jun 28 16:19:28 2013 -0400My first commit
…To see just the basic information for each commit on one line per commit use
git log --pretty=oneline
$ git log –pretty=oneline
a8a0a471342f806894129e5b1d9d0a6fa581187b My second commit
20e7c82b161b986f4e603898f822f3ddc4e4616b My first commit -
Additionally you can use
gitk
to bring up a graphical interface which is very useful for seeing the commits you have made and what changes were made in each commit.
-
-
Bonus: Creating a new remote for a different remote repository
-
Occasionally you will have multiple different remote repositories that you want to push your local work to or pull other peoples work from. The most common case for this is when you fork a repository to work on it but then want to still be able to communicate with the original repository (and push to it if you are given write access).
-
In order to do this you will need to create a new remote on your local machine. A remote is simply the address of a remote repository that you can interact with from your local machine. The command for this is:
$git remote add [remote_short_name] [url]
where [remote_short_name] is replaced with the name you want the remote to have (such as “mainrepo” or “origin”) and [url] is the address of the remote git repository (such as “https://github.com/yourusername/sandbox.git”).
-
After having created a new remote you can use the git fetch, git push and git merge commands just as you did before by replacing “origin” with the remote name (ex. git push [remote_short_name] master or git merge [remote_short_name]/master). You can also use
git remote -v
to see what remotes your repository currently has and where they are pointing to.
$ git remote add mainrepo https://github.com/yourusername/sandbox.git
$ git remote -v
mainrepo https://github.com/yourusername/sandbox.git (fetch)
mainrepo https://github.com/yourusername/sandbox.git (push)
origin https://github.com/yourusername/sandbox.git (fetch)
origin https://github.com/yourusername/sandbox.git (push)
Deliberate Practice Challenge:
This section is a chance for you to build on your knowledge of GitHub with more advanced techniques. There are no specific tutorial instructions for these exercises but if you explore the resources listed below you will find commands for all of these tasks. The exercises get more complex as you progress so it is useful to attempt them in order.
-
Create aliases for any commands that you use often (saves you time when you’re typing)
-
Create and then delete a remote branch (pretty useful so you don’t have to open GitHub in your browser)
-
Squash multiple commits into one commit (only do this with commits that you haven’t pushed remotely yet)
-
Stash changes that haven’t been committed yet on one branch and then apply them to a different branch
-
Amend the last commit that you made by adding changes that are currently staged
-
Undo the last commit that you made (revert locally committed changes to staged/unstaged changes)
-
Reorder your commit history (be very cautious)
Resources:
-
GitHub indepth tutorial: http://git-scm.com/book (very well written and useful for learning and as a reference)
-
GitHub basic setup: https://help.github.com/articles/set-up-git (there are also links at the bottom to pages that explain how to create a repository, how to fork a repository and how to add to someone elses repository)
-