Using git for labwork
A fair number of students have approached me with questions about whether it's possible to clone the repository and do all development work on their own machines instead of ada.cs.iit.edu. The answer's a definite yes, but the problem is that make handin will only succeed on ada because of a firewall that blocks network connections from outside machines. That, and it's also important to test all your work on ada (i.e., verify that stuff builds and runs correctly on it) because I will be doing all my grading there and you don't want to worry about getting penalized for not checking for some platform specific bug.
You can of course do this manually -- you can clone the repository on your own machine (assuming you've a local git installation), work on the files, then copy everything back over to ada manually for final testing and submission. But this is a pain -- it's a much better idea to just use Git to do what it was meant to do: distributed version control.
This walkthrough will get you started. Please note that it's not even close to being a comprehensive tutorial on Git usage. For that, look to the online git help facility or websites like Git Magic and the Git Community Book.
I will also assume that you've installed Git on your local desktop / laptop / netbook / whatever. Git comes preinstalled on Mac OS X 10.5 or later, and can be installed on Windows using Cygwin. On Debian-derived Linux distributions, it's usually as simple as doing:
sudo apt-get install git-core git-doc
If you're running something else, I imagine you probably know how to get Git on it.
Note that the following sequence of steps and recommendations aren't the only way of getting this to work -- Git is packed with wonderful alternative routes and associated frustrations -- you're welcome to experiment once you get the hang of the system.
Cloning the repository
The first thing you should do is clone the main repository on both your local machine and on ada. You've probably already cloned it on ada, so you can skip that step. In my sample terminal sessions the prompt local$ prefaces commands entered in your local machine's shell, and ada$ prefaces commands entered on ada. Output following commands will vary for you, of course, but I show them for the sake of context and discussion.
So locally:
local$ git clone git://github.com/michaelee/cs351.git
Initialized empty Git repository in /home/lee/cs351/.git/
remote: Counting objects: 378, done.
remote: Compressing objects: 100% (304/304), done.
remote: Total 378 (delta 152), reused 171 (delta 54)
Receiving objects: 100% (378/378), 105.26 KiB, done.
Resolving deltas: 100% (152/152), done.
and on ada:
ada$ git clone git://github.com/michaelee/cs351.git
Initialized empty Git repository in /home/lee/cs351/.git/
remote: Counting objects: 378, done.
remote: Compressing objects: 100% (304/304), done.
remote: Total 378 (delta 152), reused 171 (delta 54)
Receiving objects: 100% (378/378), 108.14 KiB, done.
Resolving deltas: 100% (152/152), done.
At this point, there is a branch called "master" in both of the repositories you just cloned that is configured to automatically pull changes from the remote repository on github.com. This remote repository, by the way, is named "origin" by default. You already know that typing the command
git pull
in the repository on either machine will pull the most recent changes from the origin.
Keeping your working tree clean
The files that you currently have checked out along with any modifications you've made to them are collectively referred to as your "working tree". Before we perform any operations that involve moving changes across repositories it is critical that we "clean" our working tree of any modifications. We do this by committing our changes with a command such as
git commit -am "My commit message"
It's likely that you've already committed to your repository on ada a few times, so the following command
ada$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)
tells you that you've made commits that don't exist in the origin. This is a perfectly normal state of affairs.
Make sure that your working tree on ada is clean before continuing.
Pulling changes from ada onto your local machine
Now, we're going to pull changes from ada into your local repository. We won't do this very often, because you're going to be doing most of the development on your local machine, and will be pushing changes from there onto ada -- more about that later.
Before doing this, you're going to need to know the full path of your repository on ada. The command pwd will tell us what it is:
ada$ pwd
/home/lee/cs351
Yours will probably be a bit longer.
From within the repository on your local machine, you can now do:
local$ git remote add -f ada ssh://lee@ada.cs.iit.edu/home/lee/cs351
Updating ada
remote: Counting objects: 16, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 10 (delta 7), reused 0 (delta 0)
Unpacking objects: 100% (10/10), done.
From ssh://ada.cs.iit.edu/home/lee/cs351
* [new branch] master -> ada/master
Note that you will need to replace "lee" before the @ symbol in the command with your own ada username, and you'll need to replace /home/lee/cs351 with the full path to your own repository on ada. You may also need to type in your password.
What this command does is fetch everything from your repository on ada.cs.iit.edu into your local repository (it doesn't affect your current branch or working tree, though). It also gives that machine the nickname "ada". If you commit any changes in the future on ada and want to fetch them to your local machine, you can just run the command
local$ git fetch ada
and the changes will be downloaded.
Merging changes from ada with your local branch
At this point, we can merge changes from the remote branch we fetched from ada into our local master branch. To do this, we use the "merge" command:
local$ git merge ada/master
Updating 1467e7a..5e40352
Fast forward
labs/clab/graph.c | 16 +++++++++++++++-
labs/clab/graph.h | 1 +
labs/prelim/hello.c | 4 ++--
3 files changed, 18 insertions(+), 3 deletions(-)
Now our local and remote branches are in sync.
Making local changes and pushing to ada
Now we're ready to start working on our labs locally. So let's assume that you've worked for a while, made a bunch of commits, debugged, tested, and are now ready to push your changes to ada for final testing.
Before we do this, it's really important to make sure your local repository is up-to-date with the origin (the repository originally cloned off github.com). You can do this, as always, with
local$ git pull
Already up-to-date.
Before going further, you'll also want to make sure that you have a clean working tree. This means committing your work with git commit -a.
Now, to push our local changes to ada, we use the "push" command:
local$ git push ada master:foxtrot
Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 444 bytes, done.
Total 5 (delta 4), reused 0 (delta 0)
To ssh://lee@ada.cs.iit.edu/home/lee/cs351
* [new branch] master -> foxtrot
The command git push ada master:foxtrot says to push the local branch named "master" (where we're doing all our development) to a remote branch named "foxtrot" on the repository nicknamed "ada". I chose the name "foxtrot" because that's the name of the computer where I do my development. You can replace it with "laptop", "netbook", "l33tb00k" -- whatever you choose.
On ada, you can now try
ada$ git branch
foxtrot
* master
The git branch command simply lists all existing branches, and you can see the "foxtrot" branch which we pushed from the local machine. It's not the current branch, though --- "master", which is marked with an asterisk, is still the current branch (and we won't be changing that).
After making sure your master branch on ada is clean, which it should be, you can now merge the changes from "foxtrot" in with the command:
ada$ git merge foxtrot
Updating 5e40352..e02ae2c
Fast forward
labs/clab/graph.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
Et voila! We just did a roundtrip series of pulls and pushes to sync modifications on our local machine and on ada.
Summary
So, to recap:
If you made changes on ada that you want to merge with your local repository:
- Make sure both working trees are clean.
- Do a
git fetch adain your local repository. - Do a
git merge ada/masterin your local repository.
If you made changes on your local machine that you want to push to ada for testing:
- Make sure both working trees are clean.
- Do a
git push ada master:branchnamein your local repository. - Do a
git merge branchnameon ada.
Periodically (usually before each lab, unless I make an announcement) you should:
- Make sure your working trees are clean.
- Pull changes from the main course repository (on github.com) with
git pull. If you want to be specific, you can dogit pull origin master.