CS3240, Lab 3: Version Control with git
The goals of these lab activities are to learn the basics of using git
and GitHub together.
Before Coming to the Lab Section meeting: Before
coming to lab, you must do the following things to prepare. There are
readings and also installing software on your laptop.
- Install git on your laptop. See instructions below.
- Create an account on github.com
if you do not already have one. Use your UVa email ID, which will allow
you to request an educational
discount.
Click on Request a Discount on
that page. This will allow you to have a number of private repositories
(5, in
fact). Later this term, one person on your project team will need to
use one of these private repositories for your team project.
- Note: Request a
Discount as soon as possible. In past terms, GitHub sometimes has
taken many weeks to process these. For today's lab, it doesn't matter,
but you need this for when the project starts.
- Download a copy of the Git Cheatsheet from GitHub's training page.
You'll want to refer to this during lab, so you may want to print a
copy and bring it to lab. Otherwise be prepared to look at it on your
computer.
- Review the slides we covered in the lecture on git and version
control.
- Look over one of the two suggested readings on git given in the
slides:
- Complete the pre-lab activity listed below and submit the
screen-capture described there to Collab before your lab section begins.
During the Lab Section meeting: You'll carry out
various coding activities (to be described later).
Upon Completing the Lab Activities: Submit the
output of a git log command
showing your work in the lab to the Collab
assignment called Lab 4 Submission.
Updates, Issues, Gotchas:
- None yet, but watch this space.
Installing git on your Laptop
Linux and OS X users may have git installed already (type git to
see). If not, if you are using a package manager (apt-get, brew,
etc) feel free to use that to download
git if you know how to use them for this. For everyone else....
(Note: Windows 10 Anniversary Edition may find that you have git installed
if you work with this edition's bash shell. Find info on this option
this link. If that doesn't work for you, follow the instructions
for Windows users below to install git.)
You can download a version of git from GitHub and other providers,
but
we recommend you download it from the main git site at this URL:
http://www.git-scm.com/downloads
Note: This is
particularly important for Windows users, since this download
comes
with a bash-shell (like you find on Linux) called git-bash that we ask you to
use. We've
seen git commands fail mysteriously when run from the Windows
command-prompt. Don't use that! Use git-bash! It's a bash shell command
line environment, just like Linux, with git
commands and also basic Unix commands installed, plus some other useful
things in its
/bin folder: ssh, scp, perl, curl, vi, vim. If you need to do
UNIX shell kinds of things on your Windows machine, this is a nice
thing to have. (FYI, if you know cygwin, it's like that but
lighter-weight, since it installs less.)
Follow the directions to
install git. Here are some notes for Windows users. When
running the installer, I kept all the defaults, except you need to make
sure you choose the following:
- In the window Select Components,
I chose
- Under Addtional Icons,
I checked On the Desktop (This
puts the Git Bash icon on your desktop.)
- Under Windows Explorer integration,
I checked Get Bash Here (This
lets your right-click on a folder and open Git Bash in that folder.)
- In the window Adjusting your
PATH environment, choose Use
Git
from Git Bash only
(Experience in previous classes suggests that you should only use Git
from Git Bash.)
- In the window Configuring the
line ending conversions, keep the
default.
- In the window Configuring the
terminal to use with Git Bash, we
recommend you choose Use MinTTY.
Initial
configuration (one time only, for all platforms):
Start a shell window to use Git (on Windows use Git Bath, on Linux or
OS X open a "terminal" window), in that shell window, set some
configuration values. Type the following
but update the final arguments:
git config --global user.name "Your
Name"
git config --global user.email
"your_email@whatever.com"
There are times a git command will bring up an editor window. The
default is vi, but if you
want emacs instead, type:
git config --global core.editor emacs
Pre-lab Activity and Submission to Do Before Lab
The following steps must be done before coming to lab. By doing
these steps, we'll know you've got git installed correctly and have
created a GitHub account. There's a submission to be done before coming
to lab to show that you've done this. If you don't complete this, some
points will be deducted for lab participation this week.
First, create a repository on GitHub:
- Sign into www.github.com with your account. (Don't have
one? See the top of this page.)
- Create new repository. (See instructions they give, or just
go for it by clicking the plus-sign.)
- Name the repo cs3240-labdemo,
and make it public.
- Check the box to initialize this with a README file.
- Add a .gitignore for Python, and choose the MIT License.
- Now click Create Repository.
GitHub will show the main page for your new repo.
Near the bottom-right, you'll see a text-box with the text HTTPS clone URL right above it, and
an icon like a clipboard with an arrow to its right. This textbox
contains the URL that you can use with a git-command on your local
machine to clone the directory. To do that:
- Click on the clipboard icon to copy the URL to your clipboard.
- Go to your shell window on your local machine, and cd to a folder where you want to
keep your projects in folders. (Create such a folder if you don't have
one.)
- Type git clone and then
paste in the URL from your clipboard and
hit return. It should look something like this:
git clone
https://github.com/hortonuva/cs3240-demo.git
(Windows users: in Git-Bash, you might find copy-and-paste
commands by right-clicking in your window. If not, see this
link for some more info on how to cut and
paste.)
- This will download all the files from the remote repo into a
directory (named after your repo) in the current directory.
Congrats! You now have a local repository on your machine you can work
with, plus a separate repository on GitHub where you can upload your
files for safekeeping or to share. Now do the following from the
shell window on your local machine:
- Use cd to make sure
you're in the cs3240-labdemo
directory.
- Type ls -a to see what
files are there. Note the hidden files
that begin with a "."
- Create a file hello.py
that prints "hello". Make sure it runs
under Python 3.
- Type git status and
make sure you understand what that tells you.
- Type git add hello.py
to add that file to the staging area.
- Type git status and
make sure you understand what that tells you.
- Add the file to your local repo by typing git commit -m "Initial
commit"
- Synchronize your local repository with your remote repo on GitHub
by
typing git push
Go back to your web-browser showing your GitHub repo. Refresh
your browser window, and you should see the hello.py file in the list
of files.
To submit before lab:
Take a screen-capture of this window, and submit the image file to
Lab 5 Pre-lab under Assignments in Collab before coming
to lab. Make
sure your image file shows your repo name (which includes your GitHub
id) and the list of files.
Here's
an example of the kind of screen-capture we want.
Lab Activity 1:
Feel free to work on all the activities with a partner. Everyone must
do them, but you can talk with your fellow students about how to do
them. Helping each other learn in this lab is a good thing!
The goal of this activity is to create some history! That sounds much
more dramatic than what you're going to do. You'll enhance your program
by making a series of small changes, commiting the file to your local
repo each time. The changes you are committing here are much smaller
and more trivial than you would normally do using version control.
Again, the goal here is to get a sequence of commits into your local
repo.
- Edit your file hello.py
to make a function called greeting(msg)
that
prints out the parameter. Use this to print your message
"hello". Test your program
- Before adding it to the staging area and putting it into the
repo, use git's status comand
to see
what that tells you about the status of your files.
- Add it to the staging area, and use git's status command to see what that
tells you about the status of your files.
- Now, do what it takes to commit it into the local repo (with a
good commit message).
- Use git's log command to see the history of your changes.
- Now, create a file helper.py
and move the definition of greeting(msg)
to that
file. Edit hello.py and
remove the function
definition there, and make it use the method by importing helper.py
file. (This is pretty sophisticated stuff, so you should really
test this carefully before proceeding! <grin>)
- Do git add again to put
it into the staging area. Before you commit....
- Question: What if you change your mind, and decide you do
not what this in the staging area? How do you remove it?
Hint: type git status and it
will tell you. Try this.
- Then do what it takes to put that into the local
repo (with a good commit message). Before proceding, use git's log
command again to see the history of your changes. Try using this
form: git log --oneline
- What if you goof up? Maybe you commit but then decide the
message wasn't right? Maybe you forgot to stage a file for this
commit? Maybe you've decided that file you just committed was
bad, and you want the version before that commit? These are easy
mistakes to correct. See
the
section "Undoing Things" in the Git Pro book on-line if you ever
need to do any of these.
- When you type git status do you
see files listed as "untracked" that you don't care about? For example,
if you use the Emacs editor, you'll see Emacs backup files with names that end
in '~'. We don't want those to be under configuration managment. You may
see similar files created by your editor, your IDE, etc.
The file .gitignore lists patterns
of filenames that Git will ignore. It's a good idea to add regular expressions
to this file to match any files your development practice might create
that you don't want in your repos.
Edit this file right now if you have untracked files you don't want
in your repos. Type git status after
to see if this worked. If you do, you'll see that it tells you that
there's something you do need to commit, so take care of that to keep your
repo up to date.
At this point, you should have a short set of entries in your project
history. Note that in the output of the log command you will see each
commit identified by an SHA-1 hash (or the first part of that). A hash
value is created for each set of files. This is how git identifies a
set of files that makes up a commit.
Lab Activity 2:
The files in your local repo have changed, but the remote repo has not.
If you want the remote repo to match your GitHub repo, it's easy: git status will remind you what to
do if you forget. But before we do that, here are some things to
know:
- When you cloned the GitHub repo to your local machine, your local
git repo remembers this. It keeps track of a remote that points to the "remote
address" of that remote repo. Remember this term: a remote is a reference to a
repository on a remote server.
Use this command to see what remotes are active: git remote -v (Try
it!) Very often a remote is given the name origin, which is the case here from
our use of git clone earlier.
- Another term to know is a branch.
We'll say more about these in the next activity. If you think of your
series of commits as a plant growing from a starting point, a branch is
a pointer to where the next commit will "grow" from. In what
we've done in this lab so far, right now our series of commits is like
a vine, with no branching at all. Each new commit is added to the
end. But it's possible to have more than one branch.
- Each branch has name. You can give new branches a name you
choose. When you start a new project, the "default" branch is
given the name master.
There's no special meaning for git; it could have called it default or anything. (It's
not the master of anything in the sense of being in charge!)
- You can see the branches in your local repo by typing: git branch (Try it!)
You can see all branches by typing: git branch -a (Try
it! We'll explain what you see there soon.)
- A branch points to a particular commit. If you are "working
on that branch", this means that your working copy (the files you see
in your directory) are the file-versions in that particular commit, and
that any new commit you make will "grow" from that commit.
- You can switch from one branch to another using the git command checkout. This will change
what's stored in your working copy: the current files are removed,
and the files from the branch are retrieved from the repo and put
into your working directory.
- When talking about branches in git, HEAD refers to the current branch
that you're working on. So HEAD is a pointer to a branch.
- Back to the concept of a remote. When you create a
remote to access versions of files on a remote repository, git actually
creates a new branch that is identified by remote/branch. So when you
typed git branch -a above,
you see origin/master.
This tells there is a 2nd branch call master
but this one shows the files as they were when you cloned the repo from
GitHub.
Do the following:
- Make sure we know what's in our current files. Print out
hello.py so you see what's in it (perhaps with the command cat). Also, type git log
--oneline --decorate which shows the history of this branch and shows
the branch names.
- Let's change branches, and move to the branch
origin/master. Type: git
checkout origin/master
Now see what's in hello.py
and type git log --oneline --decorate
again.
- What's going on? Do you understand what's happened?
(Note: when you did the checkout, you got see some messages about
the fact that you're now working on a branch that shouldn't be changed,
since it's supposed to reflect what's on your remote repo.)
- Type git branch -a to make
sure you see what your branch situation really is.
- You can go back to your local master branch. Type: git checkout master
Now see what's in hello.py
and type git log --oneline --decorate
again.
- Let's send all our changes in our local repo to the GitHub
repo. Once we've done that, it will store the same versions of
the files there as we have here locally. Just type: git push
Look at the messages. Type git status and note that it says "Your
branch is up-to-date with 'origin/master'."
- Go back to GitHub, do
a refresh. Is all as you expect?
- While on GitHub, edit your README.md there in the
web-interface. Change an
existing line.
- Go back to your local machine, and edit README.md by changing
that exact same line in a different way. We're trying to force a
conflict here, so do what it takes to create something that cannot be
merged automatically. Put this version into your local repo.
- Now try pushing your files to GitHub. It should report a
problem, right?
- Now try pulling your GitHub files down to your local
machine. You should get a conflict situation. Use your
editor to fix to resolve this conflict (as you see fit), and then push
this back to GitHub. Check out the state of things on
GitHub. Is all as you expect it to be?
Lab Activity 3:
Let's practice branching. Our goal here is for you to create two
different working versions of your Python program.
- On your local machine, create a new branch with the git checkout
-b command. Name your branch new-feature1.
- Switch to that branch. Now, create a new .py file
that does something simple, perhaps changing or using your existing
files. Feel free to edit your existing files too. We
want some changes to this new branch.
- Do what it takes to put those changes into your local repo.
- Switch back to your master branch. Look at the files in
your directory. Do you see the new file you added?
Why or why not?
- Again, create a new .py file here in the master branch, and
change some existing files too. Do what it takes to put these
into the local repo.
- Look at the files in your directory. Now, switch to the
other branch and look again. Is all as you expect?
- Switch back to the master branch, and now merge that other branch
into this branch. Resolve any conflicts. Look at all your
files. Is all as you expect?
- Type this command:
git log --graph --oneline --decorate
This will show a graph-like version of your branches, with info on
which commit is in which branch. Does its output make sense to
you?
- Finally, from here in the master branch, push to the GitHub repo.
This scenario mimics a common work-flow. You want to keep track
of the stable version of your files. You use the branch master for that. New
development can continue on the new-feature1
branch, where you make changes and test them, but wait to add them to
the stable version of your code-base (i.e. the master branch). Once you're
satisified they can be added to the stable-code base, you switch to the
master branch and then merge
the new-feature1 branch into
it. (And, if you happened to make changes to the master branch too, those will
be merged as well.)
See the
section "Branching Workflows"
in the Pro Git book on-line for more info on this idea.
Lab Activity 4: Remote Branches
- Using the branch you created in the last activity, push that branch to
your remote repo. Make sure you have edit some files in that branch first so that you can recognize that
the files differ from the master branch.
- Look on GitHub and explore how you can see the branch and the
files stored in that branch. GitHub's interface lets you move from branch
to branch easily.
- Back on your machine, type the git
branch -a command and make sure you understand its output.
- Back on GitHub, update one of the files in the new branch there by
editing it directly from GitHub.
- Back on your machine, what do you need to do to retrieve those changes
from the GitHub repo? Figure that out and do it.
PostLab work:
Read more branching and about what's known as the GitHub workflow. Be ready
for an on-line quiz due later this week.
Here are links that discuss this.
Submission:
By the end of lab, submit the
output of this command from your master branch: git
log
--oneline --decorate --graph
in the text-field of the Collab Assignment Lab 3 Submission.