Git: Using Git and Submitting With Git

Posted on November 1, 2016

Submission Cheat Sheet

This is going to become your core workflow for submitting:

$ git status
$ git diff
$ git add file1
$ git add file2
$ git commit -m "Message Here: What Did You Change"
$ git pull
$ git push

Then check on Gitlab to confirm that your changes are there.

Git

Git is a source code management tool that lets you:

To use technical terms, Git is a distributed version control system. Because of its speed and flexibility, it has become the leading tool for managing source code. For example, Github is the world’s largest storehouse of open source projects. However, Github did not make Git—that honor goes to Linus Torvalds, who you may recognize as the creator of Linux.

If you’re looking for a version control system to learn in 2016, Git is the one. You won’t be using many of its features (for example, you won’t be collaborating with each other), but using Git to submit code will give you a taste of what you can do.

Overview

Git lets you take snapshots of an entire folder and store those snapshots as “commits”. It’s kind of like a fancy backup system for your code, but it also lets you to easily transfer those snapshots to different computers.

Thus, we’ll be using Git to submit assignments.

A Bit Of Setup

Check your Git config and see if you have a name and email set.

$ git config -l

If you don’t have a name and email set, choose the name and email that will appear on all your commits. You do not have to use your UChicago email.

$ git config --global user.name "Name"
$ git config --global user.email "email@example.com"

And I don’t know what the defaults are these days, but color makes me happier:

$ git config --global color.ui auto

Getting Your Repository

We created repositories for all of you. You need to gain access to yours.

  1. Log in to https://mit.cs.uchicago.edu/. This is a web interface where you can view your repository.

  2. Find the settings.

  1. Go to manage your SSH Keys.
  1. If you don’t have an SSH key (usually they are stored in the ~/.ssh/ folder), follow the directions for generating one (I always skip the password step).

Public key encryption is one of the coolest things in computer science. Unfortunately, we don’t have time to discuss it. Just make sure you give Gitlab your public key not your private one.

  1. Copy/paste your public key into Gitlab.

There. Now, when you try to talk to the submission system from your computer, the submission system knows it’s your computer and not someone else. Let’s give it a go.

On the command line, navigate to your folder for this class. Now, clone the repository from the submission system onto your computer:

$ git clone git@mit.cs.uchicago.edu:cs161-aut-16/yourcnetid.git
$ cd yourcnetid

Each of your labs will eventually be its own folder in this one big repository (e.g. folders named lab4, lab5, lab6, etc.). Well, I guess it’s not a big repository yet. But it’s your one repository for this term.

Basic Git

Let’s practice Git’s workflow.

Create two simple files, hello.txt and world.txt. These files can be empty.

Run:

$ git status

You should see something like:

On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	hello.txt
	world.txt

nothing added to commit but untracked files present (use "git add" to track)

Git is telling you that it’s not watching the hello and world files. Any changes to these files will be ignored.

Tell Git to track your files with git add.

$ git add hello.txt world.txt

Now if you run git status you should see:

On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   hello.txt
	new file:   world.txt

We haven’t actually created a snapshot (a commit). We’re just telling Git what files we want to include in the commit.

So now is a good time to make a commit with your two new files.

$ git commit -m "For fun, add files hello.txt world.txt"

The string after -m is your message for the commit. It’s sort of a name for the snapshot. Use it to describe what you changed since the last commit.

You can see a log of commits with git log:

$ git log
commit 30a672d7a3b3f615080a7fd79eccaa831f5285dc
Author: Brian Hempel <brianhempel@uchicago.edu>
Date:   Mon Oct 31 22:46:35 2016 -0500

    For fun, add files hello.txt world.txt

Okay, now it’s time to make a real change. Write some text in hello.txt and then save the file.

Use git diff see any changes that we haven’t told Git we want to commit. (Note, this shows changes in tracked files only; hello.txt is tracked because we already committed it once).

$ git diff
diff --git a/hello.txt b/hello.txt
index e69de29..dfc3e88 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1,6 @@
+Hello Git,
+
+I hope we can be friends, even though I hear you can sometimes be complicated.
+
+Sincerely,
+Brian

Or, you can see a summary with git status:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

Tell Git to include this change in our next commit:

git add hello.txt

Now, actually make the commit:

git commit -m "Write a message to Git"

If you run git log, you will now see two commits:

$ git log
commit 32133475e7e83c3ba4017787f4c0d56aab35f058
Author: Brian Hempel <bnhempel@mtu.edu>
Date:   Mon Oct 31 23:01:02 2016 -0500

    Write a message to Git

commit 30a672d7a3b3f615080a7fd79eccaa831f5285dc
Author: Brian Hempel <bnhempel@mtu.edu>
Date:   Mon Oct 31 22:46:35 2016 -0500

    For fun, add files hello.txt world.txt

All these commits are still only on your computer. To push these changes to the remote repository (the mit.cs.uchicago.edu server that’s acting as our submission system), just type:

$ git push

(For your very first push, you may have to type git push -u origin master.)

You should see a message about pushing to master.

There you go! Push early and push often.

When you think your submission is final, you should verify that your changes were pushed:

  1. Run git status to make sure you don’t have any local changes.
  2. Then navigate to the “Files” tab on Gitlab. Make sure you are on the master branch and make sure that your files look right.

If everything looks good, your submission is done. An automated script will grab your repository at the deadline.

There’s one more thing you should know.

Your instructor or the graders may distribute grades by making changes to your remote repository. When there are more commits on the remote repository than on your local repository, Git will not let you push.

You have to first run:

git pull

This will pull any commits from the remote repository and automatically merge them with your local changes. Then you can run

git push

You now know everything you need to get started!

Graphical Tools

For the git add and git commit part of the workflow, I use a GUI tool (the Mac-only GitX). It helps visualize the changes much better. There are equivalent tools for other operating systems. (Git comes with gitk. I have no idea if it’s usable.)

Documentation

There are man pages documenting the different git commands, e.g.:

$ man git-add
$ man git-diff
$ man git-commit
$ man git-pull
...

Or:

$ git help add
$ git help diff
...

Reading these docs, I see there’s an interactive mode for git add that you might find useful:

$ git add -i

*** Commands ***
  1: status	  2: update	  3: revert	  4: add untracked
  5: patch	  6: diff	  7: quit	  8: help
What now>

Of course, you can also search online for tutorials.

More Git

The above commands are all you should need for this class, but in the future you may want to learn more about what you can do with Git.

Git gives you complete flexibility. You can grab old versions of files. You can undo entire commits. You can work on different branches to separate different features while you are working on them. You can reorder commits. You can go back in time and change history. (However, a rule of thumb is that you should not rewrite history after pushing.)

For what it’s worth, these are the commands I use in my programming workflow. More advanced users may find these interesting. For this course, I do not recommend multiple branches or rewriting history.

git add --patch     # Okay, really I use GitX; but `git add -p` is close.
git rm              # Un-stage a change so it's not committed
git commit          # Again, I do this through GitX
git commit --amend  # Change last commit; (GitX again)
git rebase --interactive HEAD^^^^^^ # Clean up history before pushing!
git commit -a -m "wip"  # WIP commits are better than stashing. Never stash.
git reset HEAD^         # Un-commit a WIP commit (but keep changes).
git checkout file_name  # Discard changes to file
git checkout -b branch_name # New branch
git branch -d branch_name   # Delete a branch
git pull --rebase      # Pull, then re-apply local commits
git rebase branch_name # Replay commits on top of branch
git cherry-pick        # Apply a single commit from a different branch
git reflog             # Recover deleted branches or mistaken hard resets

Happy coding!