Title: Working on Github in cs4414
Date: 2013-08-25
Category: Tools
Tags: github, git
Author: David Evans, Weilin Xu

For this course you are required to use separate private repository for
each problem set. Typically, you need to fetch the code skeleton from
the respective public repository of the course every time before you
start coding on each Problem Set.

The general process of working on problem sets is to (we'll go through
each step in detail below):

1. Create a private repository on github for each problem set, and share that repository with the `cs4414uva` account.

2. **clone** the repository, so you have a local working copy.

3. Get the code skeleton from the public repo of CS4414 course, merge it
into your working copy, and push to the main repository.

4. Edit code and text files in your local copy.

5. **push** the local changes to the main repository.

As you do the assignment, you should commit and push your changes regularly.

## Setting up the Repository

Let's take PS1 as an example. For the first assignment in cs4414 here's
what you should do.

<b>1. Create a new repository named `ps1`.</b>

- Visit [https://github.com/repositories/new](https://github.com/repositories/new)
- Select "Private" for the type of repository.  (If you got a student discount correctly, this should be available for free.  If it asks you for
          a credit card, go back to step 1 of [setting up github](|filename|github.md).)
- Keep the "Initialize this repository with a README" unchecked, since you will fetch it later from a public repository.


<b>2. Share this repository with the `cs4414uva` github account</b> following the directions below. 

- <font color="red">Be aware that this will allow the course staff to see everything you
  put in the repository!</font>  If you are worried about having rants against
  the course staff in your repo, you could wait to do this until you are
  ready to submit, but it is best to put those rants somewhere else and
  share your repo when you create it so you don't forget to share it later.
- Visit the repository's page.
- Click the "Settings" button on the right side.
- Click the "Collaborators" tab.
- Enter `cs4414uva`.
- Select the user from the dropdown.
- Click "Add".



<b>3. Clone the empty private repository to your working
environment.</b>   Instead of _mygithubname_ below, use your github username.

    :::text
    git clone https://github.com/mygithubname/ps1.git

If you haven't set up SSH keys for github, you'll need to enter your
github username and password.

<b>4. Fetch the code skeleton from the public repository of CS4414 to
your private repository.</b>  Enter the working directory of your empty
repository and add a remote repository named `course`, merge the code,
and push it to your private repository by executing: 

    :::text
    git remote add course git@github.com:cs4414/ps1.git
    git pull course master
    git push --tags origin master

## Working with Files

Now you can write your own code in editor and save it to files. You can see what files have changed by running:
`git status`.  You should see something like this:

    :::text
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #	hello.rs

In this example, nothing has been added to commit but untracked files
are present.

To add the files to the main repository:

    :::text
    git add hello.rs

You should try running `git status` again to see the files that will be
committed.  Note that add stages the file in its current state!  If you
modify the file after the add, the version of the file when you did the
add is the version that will be committed.

Then,

    :::text
    git commit

commits the staged files to the main repository.  This will launch and
editor for you to enter a commit message.  You can use `-m` to provide a
message at the command line instead:

    :::text
    git commit -m 'I am no longer afraid of commitment!'

Your actual commit messages you use should be **clear** and **useful**.
It is tempting to use [lazy commit message](http://whatthecommit.com/),
but you will regret this as your projects get more complex and code
breaks in mysterious ways.

If you want to skip the two-stage commit, you can do:

    :::text
    git commit -a

to automatically add all new and changed files to the commit.

At this point, the changes are stored in your local repository, but not
yet in the main repository.  Once you have changes you want to push to
the main repository:

    :::text
    git push

After this, all the changes are now pushed to the main repository at
github.  Visit your repository in github to see the result.  

This seems like a lot of steps, but by providing a full local repository
and making the steps of staging and pushing to the remote repository
explicit, git provides developers with a lot of control over
repositories that becomes very useful when several (or many) developers
are working on the same project and trying to combine each others
changes (or recover from mistakes).

There are many resources for learning more about git.  The free book,
[Pro Git](http://git-scm.com/book/en/) by Scott Chacon is recommended.
