Instructor notes for teaching git via collaboration on GitHub.
authorMatt Davis <jiffyclub@gmail.com>
Fri, 22 Feb 2013 22:03:42 +0000 (17:03 -0500)
committerW. Trevor King <wking@tremily.us>
Wed, 23 Oct 2013 03:14:11 +0000 (20:14 -0700)
The focus of the lesson is to have students contribute to a repo on GitHub in
which we are building up a list of the things they are most interested in
learning at the boot camp. Requires everyone have a good internet connection
and that at least some of the participants sign up for GitHub.

version-control/git/git-and-github/instructor_notes.md [new file with mode: 0644]

diff --git a/version-control/git/git-and-github/instructor_notes.md b/version-control/git/git-and-github/instructor_notes.md
new file mode 100644 (file)
index 0000000..d59c0d4
--- /dev/null
@@ -0,0 +1,247 @@
+# 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