Git and GitHub
Based on materials by Katy Huff, Anthony Scopatz, Joshua R. Smith, and Sri Hari Krishna Narayanan
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 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 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
.
- Pick another branch and try to merge.
- Repeat as necessary.
- Push the final result to GitHub.