--- /dev/null
+# git/GitHub
+
+The goal of this lesson is to introduce the students to [git][] via
+collaboration on [GitHub][].
+
+## Introduction
+
+- Say some introductory stuff about version control in general, and git/GitHub
+ in particular.
+
+*Note: The figures in the [Visual Git Reference][visual git] can be a good
+stand-in if you have nowhere to draw.*
+
+## Setup and Signup
+
+- Have everyone configure git:
+
+ $ git config --global user.name "User Name"
+ $ git config --global user.email "user@email.com"
+ $ git config --global core.editor "nano"
+ $ git config --global color.ui "auto"
+
+- Give a little tour of [GitHub][].
+- Have everyone make [GitHub][] accounts.
+
+### Make and Clone
+
+- Make a new demo repo on [GitHub][] explaining the process as you go
+ (probably on your personal account).
+ - Have [GitHub][] put in a README so it can be cloned.
+- Explain that much like a browser navigates to websites using a URL, git talks
+ to remote repositories using a URL.
+- Explain the different URL options:
+ - Read/write `ssh` protocol requires [ssh keys][], which make it so you
+ don't have to enter username/password.
+ - `https` protocol takes username/password.
+ - `git` protocol is read-only.
+- Now we want to get a copy of this down on all of our computers -- `git clone`!
+ - Have everyone do this via the `https` URL.
+- `ls` to show the new directory and `cd` into it.
+- Compare the local listing to what you see on [GitHub][]. Same for now, but
+ not for long!
+
+## Basics
+
+### Local Basics
+
+**IMPORTANT:** Make sure you tell people *not* to make their own local changes,
+that will make things really complicated later when people pull. Alternatively,
+you can go ahead and let them do whatever they like and use it as a teaching
+moment on `git reset --hard` in a few minutes when it's time to start the
+collaboration.
+
+- On the white board draw a box representing the working area and explain that
+ this is where you work and make changes.
+- Make a new file called `top-things-to-learn.md` and put the title
+ "Top Things We Want to Learn" in it.
+- `git status` -- highlight the "Untracked files" section and that git tells
+ you how to add a file to the next commit.
+
+### Composing the Snapshot
+
+- On the white board draw a box representing the staging area (index) and
+ explain that this is where we set up the next snapshot of our project.
+ - Like a photographer in a studio, we're putting together a shot before
+ we actually snap the picture.
+ - Connect the working area box and the staging box with `git add`.
+- Run `git add top-things-to-learn.md`.
+- `git status` -- highlight the "Changes to be committed" section
+ and git telling you how to unstage the new file.
+
+### Taking the Snapshot
+
+- On the white board draw a box representing the project history. Once we take
+ a snapshot of the project that snapshot becomes a permanent reference point
+ in the project's history that we can always go back to.
+ - The history is like a photo album of changes, and each snapshot has a
+ time stamp, the name of the photographer, and a description.
+ - Connect the staging area to the history with `git commit`.
+- Run `git commit` and explain log messages.
+ - Summary message at the top, longer one below.
+- `git status` -- nothing going on!
+
+### Looking at the History
+
+- `git log` -- Shows description of what we've done.
+ - `git log --oneline` -- Abbreviated version.
+- Explain the commit hash.
+ - Unique identifier of that commit if we ever want to refer to it.
+ - Comes from "hashing" stuff associated with the commit, like the changes
+ we made.
+ - Can demo hashing with Python's `hashlib.sha1`.
+
+### Previewing Changes
+
+- The file we're making is going to be a list of the top things everyone wants
+ to learn in the boot camp. Add your item (e.g. everyone's names) and save.
+- `git status` -- point out that now we have a modified file instead of an
+ untracked file, but the procedure for adding it to the next snapshot is
+ the same.
+- Want to see the changes you're about to add? `git diff`!
+- `git add`
+- `git diff` -- now it doesn't show anything. `git diff` shows differences
+ between the working area and the staging area.
+ - To see differences between the staging area and the most recent commit
+ use `git diff --cached`.
+- `git commit -m` -- This time use the `-m` option and show that for short
+ commit messages you can just enter them at the command line.
+
+### Undoing Changes
+
+- Say I want to redo the previous commit...
+- `git log --oneline` -- grab the commit has for the point we want to go back to.
+- `git reset COMMIT`
+- `git log --oneline` -- highlight that the latest commit is gone
+- `git status` -- But the changes haven't gone anywhere.
+- I can now edit the file to fix whatever was wrong and re-commit.
+
+## Sharing
+
+- Now I want to share my changes with everyone so they can start working on
+ it too.
+
+### Remotes
+
+- As we said back at the beginning, git uses URLs to point repositories on other
+ computers, in this case [GitHub's][GitHub] servers.
+- We can give these remote repositories names so that we don't have to type
+ in the full URL all the time, and in fact git has already set one up for us.
+- `git remote` -- there's a remote called "origin".
+- `git remote -v` -- we can see that it points to the same URL we cloned from,
+ git sets this up automatically.
+
+### Branches
+
+- On the [GitHub][] view of the repo highlight the branches pull-down -- right
+ now it only has one branch called "master", this is another thing git makes
+ for us by default.
+- What branch are we on locally? `git branch`.
+- Give a short explanation of branches and mention that we will come back to
+ them later.
+ - Isolated development environments.
+- When git communicates with a remote repository it needs to know what branch
+ is changing, in this case we'll just stick with "master".
+
+### Pushing
+
+- Use `push` command to send data to a remote repository, and we also have to
+ specify the remote name and branch name: `git push origin master`.
+- Refresh the [GitHub][] view.
+
+### Pulling
+
+**IMPORTANT:** If students have been making local commits, this is the time at
+which they will need to use `git reset --hard` to get back in sync with you.
+
+- `pull` is the reciprocal command, must specify remote and branch.
+- Have everyone `git pull origin master`.
+
+### Collaborate
+
+- Pick a student to add their top thing to learn to the list:
+ - Add them to the collaborator list on the demo repo.
+ - edit, save, `add`, `commit`, `push`
+- Have everyone `pull`.
+
+### Rebase
+
+#### No Conflict
+
+- Have another student add their thing and push.
+- Make a change to the README file before pulling.
+- Try to push.
+- On the white board draw the situation: my repo and the remote repo have
+ different development histories and git doesn't know how to pull things
+ together.
+- It would be nice if I could move my local change after the remote change.
+ (Draw picture.) There's a command for that!
+- `git fetch origin` -- This gets information from the remote repository
+ but doesn't integrate it with your local repo like `pull` does.
+- `git rebase origin/master` -- `origin/master` is how we specify the fetched
+ data for the remote named "origin" and it's branch named "master".
+ - This replays my local changes on top of the state of the remote repo.
+- `git log --oneline` -- Now my change is after the remote change.
+- `git push origin master`
+- Have everyone pull.
+
+#### With Conflicts
+
+- Again, have a student add their thing and push.
+- Before pulling make a change in the same place in the same file.
+- Try to rebase as above.
+- Explain the conflict message git prints out.
+- Show the conflict messages in the file and how to clean it up.
+- Continue the rebase and push the result.
+- Have everyone pull.
+
+## Developing in Branches
+
+Often you want to leave a stable version of your code alone while you make some
+potentially disruptive changes. Or you and someone else are working on the code
+and you want to be able to work without worrying what others are doing.
+
+- It's going to take a long time to get everyone's top thing to learn onto the
+ list one at a time, so the room is going to break out into groups and each
+ come up with their own list.
+- So that they can all do this and then push their result to [GitHub][] each
+ is going to work in their own, isolated branch.
+
+### Making a New Branch
+
+*Note: The [Learn Git Branching][] app can be a useful way to
+illustrate this part of the lesson.*
+
+- Make a new branch: `git branch matt-list`.
+- `git branch` -- highlight the asterisk showing the branch we're currently on.
+- Move to that branch: `git checkout matt-list`.
+- `git branch` -- asterisk moved!
+- Make a change and push.
+ - **IMPORTANT:** have to specify new branch named when pushing, not "master".
+- `git checkout master` -- show that your change is *not* in master.
+- Show how to browse to the other branch on [GitHub][].
+- Have each group pick a unique branch name, switch to that branch, and add
+ all of their top things to learn to the list and push the result.
+
+### Resolving the Changes
+
+- Browse all of the new branches on [GitHub][].
+- Illustrate the situation on the [Learn Git Branching][] app.
+- Could just pick one of these branches as the new one "master" and move on,
+ but we're more adventurous than that.
+- Make sure you're in "master".
+- `git fetch origin` -- without a branch name it grabs all of the new branches.
+- Pick a branch and `git merge branch-name`.
+ - Should be a smooth fast-forward.
+ - Illustrate on the [Learn Git Branching][] app.
+- Pick another branch and try to merge.
+ - Resolve conflicts, add, and commit.
+ - Illustrate on the [Learn Git Branching][] app.
+- Repeat as necessary.
+- Push the final result to [GitHub][].
+
+[git]: http://git-scm.com/
+[GitHub]: http://github.com
+[ssh keys]: https://help.github.com/articles/generating-ssh-keys
+[visual git]: http://marklodato.github.com/visual-git-guide/index-en.html
+[Learn Git Branching]: http://pcottle.github.com/learnGitBranching/?NODEMO