GitHub — Tutorial

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

  1. Introduction
    1. What is GitHub and why is it useful?
    2. Overview of GitHub commands

  2. Tutorial:
    1. Setup

    2. Creating a repository

    3. Adding files to your repository

    4. Pushing your changes to a remote branch

    5. Pulling changes someone else made and merging them with your work

    6. Creating a local branch

    7. Making changes on a local branch and merging those back into your local master branch

    8. Look at your commit history

    9. Bonus: Creating a new remote for a different remote repository

  3. Deliberate Practice Challenge

  4. 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

  • 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 -0400

      My second commit

      commit 20e7c82b161b986f4e603898f822f3ddc4e4616b
      Author: Your Name <youremailaddress@you.com>
      Date: Fri Jun 28 16:19:28 2013 -0400

      My 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 -0400

      My 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 -0400

      My second commit

      diff –git a/README b/README
      index 9daeafb..e2a082d 100644
      — a/README
      +++ b/README
      @@ -1 +1 @@
      -test
      + test

      commit 20e7c82b161b986f4e603898f822f3ddc4e4616b
      Author: Your Name <youremailaddress@you.com>
      Date: Fri Jun 28 16:19:28 2013 -0400

      My 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.

Screen Shot 2013-06-28 at 3.14.02 PM

  • 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)

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s