cheat-sheet.md: Mention the default root for 'git branch ...'
[swc-version-control-git.git] / instructor.md
1 # Git/GitHub
2
3 The goal of this lesson is to introduce the students to [Git][git] via
4 collaboration on [GitHub][].
5
6 ## Introduction
7
8 - Say some introductory stuff about version control in general, and Git/GitHub
9   in particular.
10
11 *Note: The figures in the [Visual Git Reference][visual git] can be a good
12 stand-in if you have nowhere to draw.*
13
14 ## Setup and Signup
15
16 - Have everyone configure Git:
17
18         $ git config --global user.name "User Name"
19         $ git config --global user.email "user@email.com"
20         $ git config --global core.editor "nano"
21         $ git config --global color.ui "auto"
22
23 - Give a little tour of [GitHub][].
24 - Have everyone make [GitHub][] accounts.
25
26 ### Make and Clone
27
28 - Make a new demo repo on [GitHub][] explaining the process as you go
29   (probably on your personal account).
30     - Have [GitHub][] put in a README so it can be cloned.
31 - Explain that much like a browser navigates to websites using a URL, Git talks
32   to remote repositories using a URL.
33 - Explain the different URL options:
34     - Read/write `ssh` protocol requires [ssh keys][], which make it so you
35       don't have to enter username/password.
36     - `https` protocol takes username/password.
37     - `git` protocol is read-only.
38 - Now we want to get a copy of this down on all of our computers -- `git clone`!
39     - Have everyone do this via the `https` URL.
40 - `ls` to show the new directory and `cd` into it.
41 - Compare the local listing to what you see on [GitHub][]. Same for now, but
42   not for long!
43
44 ## Basics
45
46 ### Local Basics
47
48 **IMPORTANT:** Make sure you tell people *not* to make their own local changes,
49 that will make things really complicated later when people pull. Alternatively,
50 you can go ahead and let them do whatever they like and use it as a teaching
51 moment on `git reset --hard` in a few minutes when it's time to start the
52 collaboration.
53
54 - On the white board draw a box representing the working area and explain that
55   this is where you work and make changes.
56 - Make a new file called `top-things-to-learn.md` and put the title
57   "Top Things We Want to Learn" in it.
58 - `git status` -- highlight the "Untracked files" section and that Git tells
59   you how to add a file to the next commit.
60
61 ### Composing the Snapshot
62
63 - On the white board draw a box representing the staging area (index) and
64   explain that this is where we set up the next snapshot of our project.
65     - Like a photographer in a studio, we're putting together a shot before
66       we actually snap the picture.
67     - Connect the working area box and the staging box with `git add`.
68 - Run `git add top-things-to-learn.md`.
69 - `git status` -- highlight the "Changes to be committed" section
70   and Git telling you how to unstage the new file.
71
72 ### Taking the Snapshot
73
74 - On the white board draw a box representing the project history. Once we take
75   a snapshot of the project that snapshot becomes a permanent reference point
76   in the project's history that we can always go back to.
77     - The history is like a photo album of changes, and each snapshot has a
78       time stamp, the name of the photographer, and a description.
79     - Connect the staging area to the history with `git commit`.
80 - Run `git commit` and explain log messages.
81     - Summary message at the top, longer one below.
82 - `git status` -- nothing going on!
83
84 ### Looking at the History
85
86 - `git log` -- Shows description of what we've done.
87     - `git log --oneline` -- Abbreviated version.
88 - Explain the commit hash.
89     - Unique identifier of that commit if we ever want to refer to it.
90     - Comes from "hashing" stuff associated with the commit, like the changes
91       we made.
92     - Can demo hashing with Python's `hashlib.sha1`.
93
94 ### Previewing Changes
95
96 - The file we're making is going to be a list of the top things everyone wants
97   to learn in the boot camp. Add your item (e.g. everyone's names) and save.
98 - `git status` -- point out that now we have a modified file instead of an
99   untracked file, but the procedure for adding it to the next snapshot is
100   the same.
101 - Want to see the changes you're about to add? `git diff`!
102 - `git add`
103 - `git diff` -- now it doesn't show anything. `git diff` shows differences
104   between the working area and the staging area.
105     - To see differences between the staging area and the most recent commit
106       use `git diff --cached`.
107 - `git commit -m` -- This time use the `-m` option and show that for short
108   commit messages you can just enter them at the command line.
109
110 ### Undoing Changes
111
112 - Say I want to redo the previous commit...
113 - `git log --oneline` -- grab the commit has for the point we want to go back to.
114 - `git reset COMMIT`
115 - `git log --oneline` -- highlight that the latest commit is gone
116 - `git status` -- But the changes haven't gone anywhere.
117 - I can now edit the file to fix whatever was wrong and re-commit.
118
119 ## Sharing
120
121 - Now I want to share my changes with everyone so they can start working on
122   it too.
123
124 ### Remotes
125
126 - As we said back at the beginning, Git uses URLs to point repositories on other
127   computers, in this case [GitHub's][GitHub] servers.
128 - We can give these remote repositories names so that we don't have to type
129   in the full URL all the time, and in fact Git has already set one up for us.
130 - `git remote` -- there's a remote called "origin".
131 - `git remote -v` -- we can see that it points to the same URL we cloned from,
132   Git sets this up automatically.
133
134 ### Branches
135
136 - On the [GitHub][] view of the repo highlight the branches pull-down -- right
137   now it only has one branch called "master", this is another thing Git makes
138   for us by default.
139 - What branch are we on locally? `git branch`.
140 - Give a short explanation of branches and mention that we will come back to
141   them later.
142     - Isolated development environments.
143 - When Git communicates with a remote repository it needs to know what branch
144   is changing, in this case we'll just stick with "master".
145
146 ### Pushing
147
148 - Use `push` command to send data to a remote repository, and we also have to
149   specify the remote name and branch name: `git push origin master`.
150 - Refresh the [GitHub][] view.
151
152 ### Pulling
153
154 **IMPORTANT:** If students have been making local commits, this is the time at
155 which they will need to use `git reset --hard` to get back in sync with you.
156
157 - `pull` is the reciprocal command, must specify remote and branch.
158 - Have everyone `git pull origin master`.
159
160 ### Collaborate
161
162 - Pick a student to add their top thing to learn to the list:
163     - Add them to the collaborator list on the demo repo.
164     - edit, save, `add`, `commit`, `push`
165 - Have everyone `pull`.
166
167 ### Rebase
168
169 #### No Conflict
170
171 - Have another student add their thing and push.
172 - Make a change to the README file before pulling.
173 - Try to push.
174 - On the white board draw the situation: my repo and the remote repo have
175   different development histories and Git doesn't know how to pull things
176   together.
177 - It would be nice if I could move my local change after the remote change.
178   (Draw picture.) There's a command for that!
179 - `git fetch origin` -- This gets information from the remote repository
180   but doesn't integrate it with your local repo like `pull` does.
181 - `git rebase origin/master` -- `origin/master` is how we specify the fetched
182   data for the remote named "origin" and it's branch named "master".
183     - This replays my local changes on top of the state of the remote repo.
184 - `git log --oneline` -- Now my change is after the remote change.
185 - `git push origin master`
186 - Have everyone pull.
187
188 #### With Conflicts
189
190 - Again, have a student add their thing and push.
191 - Before pulling make a change in the same place in the same file.
192 - Try to rebase as above.
193 - Explain the conflict message Git prints out.
194 - Show the conflict messages in the file and how to clean it up.
195 - Continue the rebase and push the result.
196 - Have everyone pull.
197
198 ## Developing in Branches
199
200 Often you want to leave a stable version of your code alone while you make some
201 potentially disruptive changes. Or you and someone else are working on the code
202 and you want to be able to work without worrying what others are doing.
203
204 - It's going to take a long time to get everyone's top thing to learn onto the
205   list one at a time, so the room is going to break out into groups and each
206   come up with their own list.
207 - So that they can all do this and then push their result to [GitHub][] each
208   is going to work in their own, isolated branch.
209
210 ### Making a New Branch
211
212 *Note: The [Learn Git Branching][] app can be a useful way to
213 illustrate this part of the lesson.*
214
215 - Make a new branch: `git branch matt-list`.
216 - `git branch` -- highlight the asterisk showing the branch we're currently on.
217 - Move to that branch: `git checkout matt-list`.
218 - `git branch` -- asterisk moved!
219 - Make a change and push.
220     - **IMPORTANT:** have to specify new branch named when pushing, not "master".
221 - `git checkout master` -- show that your change is *not* in master.
222 - Show how to browse to the other branch on [GitHub][].
223 - Have each group pick a unique branch name, switch to that branch, and add
224   all of their top things to learn to the list and push the result.
225
226 ### Resolving the Changes
227
228 - Browse all of the new branches on [GitHub][].
229 - Illustrate the situation on the [Learn Git Branching][] app.
230 - Could just pick one of these branches as the new one "master" and move on,
231   but we're more adventurous than that.
232 - Make sure you're in "master".
233 - `git fetch origin` -- without a branch name it grabs all of the new branches.
234 - Pick a branch and `git merge branch-name`.
235     - Should be a smooth fast-forward.
236     - Illustrate on the [Learn Git Branching][] app.
237 - Pick another branch and try to merge.
238     - Resolve conflicts, add, and commit.
239     - Illustrate on the [Learn Git Branching][] app.
240 - Repeat as necessary.
241 - Push the final result to [GitHub][].
242
243 [git]: http://git-scm.com/
244 [GitHub]: http://github.com
245 [ssh keys]: https://help.github.com/articles/generating-ssh-keys
246 [visual git]: http://marklodato.github.com/visual-git-guide/index-en.html
247 [Learn Git Branching]: http://pcottle.github.com/learnGitBranching/?NODEMO