Introduction to Git
Git is a distributed source code version control system. When you place your code under version control, you record the changes you make to your files over time and you can recall the history of each of your file changes at will. We will be using git extensively this semester in homework assignments.
GitHub is a development ecosystem based around git. In this course, we will be using GitHub to host our git repositories and we will take advantage of other GitHub features such as the issue tracker and wiki.
If you have not done Lab 0 to set up your GitHub account or install course VM, please do it now. Please make sure that you set your USC email as the primary and public email address for your GitHub account. Otherwise you will not be able to submit your homework.
0 - Disclaimer
The instructions and discussion in this lab are for the git command line interface in course VM. GitHub and other software vendors have GUI-based applications to interact with repository. These tools are not will not be supported in this class. Git Bash is also not supported in this class.
1 - Git Configuration: SSH Keys
One of the main features of using a distributed version control system such as git, is having a complete backup of your code and its history. Git uses the Secure Shell protocol (SSH) when contacting remote servers. To facilitate this communication, you need to generate a pair of encryption keys: one public and the other private.
In this step, we will generate the set of keys required to use SSH. This will be done manually through the command line. To start the configuration you would need to launch the Terminal.
[Hint] You will be copying and pasting a lot of commands into your VM terminal. You can use ctrl+shift+c to copy from terminal, use ctrl+shift+v to paste into Terminal. You can also right-click in Terminal and choose Copy/Paste.
Then, type the following command replacing Tommy Trojan's email with your own:
ssh-keygen -t rsa -b 2048 -C "ttrojan@usc.edu"
When prompted for a file location, use the default location [press Enter]:
# Creates a new ssh key, using the provided email as a label
Generating public/private rsa key pair.
Enter file in which to save the key (/home/cs104/.ssh/id_rsa):
After that, you will be prompted for a passphrase to secure your private key. It is a good idea to secure your key with a passphrase, though it is optional. Note that your password will not show up in terminal as you type it. When you are done typing your password (don't enter anything if you do not wish to set a passphrase), press Enter. You will be promted to verify your passphrase. Re-enter your passphrase (or nothing if you did not set one) and press Enter.
Upon success, you should receive a confirmation such as:
Your identification has been saved in /home/cs104/.ssh/id_rsa.
Your public key has been saved in /home/cs104/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:vC+4OG2u1PIeE0OKX9jiFFHuLnkYCBSsvIW8ybD873H ttrojan@usc.edu
The key's randomart image is:
+---[RSA 2048]----+
| ++o. |
| S+.o *.* |
| +.X. o |
| 0. o + |
| ..o E . |
| .=S. . + .0 |
| .*=* ... |
|.+.=o*. .. *o* |
| .++*oo. .. |
+----[SHA256]-----+
2 - Git Configuration: Developer Profile
The next step is to configure your git profile in your development environment. This is important because your profile information is used to annotate your contributions to a repository/project. Although this may not seem like a big deal when you are the only one committing to a repository, it is of the utmost importance once you work on a group project because this information is the basis used to calculate your contribution to a project.
You only need to do this configuration once and we will be setting-up the following information:
- Name, e.g.
Tommy Trojan
- Email, e.g.
ttrojan@usc.edu
- Editor for commit messages, e.g.
vi
,emacs
,notepad
- Git message colors (make it pretty-er)
- How to handle new lines (Why is this a problem?)
Configuration is performed manually through the command line. To start the configuration you would need to launch the Terminal.
Your Personal Information
Please use your actual first and last name when configuring your git user.name
. For your email, you should use the email address you want to appear in the git commit log. You should not feel obligated to use your usc.edu
account here unless you want to. Configure your information as follows:
# Set your name and email
git config --global user.name "Tommy Trojan"
git config --global user.email "ttrojan@usc.edu"
[Note] One of the cool features of the GitHub UI is linking your contributions to your GitHub profile. For that to work, you MUST register and verify your git user.email
in the GitHub Email Settings. (Hint: you can have multiple emails registered with GitHub and you could control which ones are public and/or private).
Git CLI Interface
By default, git does not color its output. Pretty printing git messages makes it easy read the output and take proper actions. You can enable colors for interactive use of git by:
# Let's get pretty colored output!
git config --global color.ui auto
Git Message Text Editor
When committing code in git, the system requires a commit message. If a message is not provided via the commandline, git will launch the Operating System's default text editor prompting you for a message. You can customize this action using the following configuration directive:
# Pick your editor of choice to edit commit messages (not code)
# Note that you should pick an editor that is installed on your machine
git config --global core.editor "subl -n -w"
Here, git will automatically launch Sublime
. You may want to change that to your editor of choice. Here are some examples (you only need one):
# emacs
git config --global core.editor emacs
# Sublime Text
git config --global core.editor "subl -n -w"
If you are not familiar with any of the editors and feel unsure which one to use, it is recommended that you use Sublime. It is similar to gedit
and Notepad
but with some additional features.
Let Git Handle New Lines
Operating Systems implement new lines differently. (Why is this a problem?) Here you will configure git to automatically normalize the line feed (LF
) to properly match the platform:
# LF Normalization (Linux & MacOS)
git config --global core.autocrlf input
Update Deprecated Settings
Since Git 2.0, Git has updated its default push settings. To avoid getting a warning when you push (we will explain what push
means soon), apply the following setting:
# Push Setting
git config --global push.default simple
Check Your Work
# List local git configuration options
git config --list
You should see something like this:
user.name=Tommy Trojan
user.email=ttrojan@usc.edu
color.ui=auto
core.editor=subl -n -w
core.autocrlf=input
push.default=simple
3 - Update Your Github Profile
You need to update your profile to include your name and SSH public key. There are also some optional settings you can change such as your avatar (profile picture) and email notifications.
In your Public Email Settings:
- If your @usc.edu email address is not listed, add it using Add email address.
- In the drop-down box under Primary email address, change the email to your @usc.edu address.
- Scroll down and make sure Keep my email address private is unchecked.
- If you scroll up, you should see your @usc.edu email is listed as Primary and Public.
- [Optional] You can add more emails to your GitHub account.
In your Profile Settings:
- Change the drop-down box under Public Email to show your @usc.edu address. Then scroll down and click Update Profile.
- Put your real name in the name field. This is to ensure the TAs & CPs know who you are regardless of your username.
- [Optional] Change your avatar
[IMPORTANT] Failure to use the correct email setting will prevent you from submitting your homework.
In your SSH Key Settings:
- Click on Add SSH Key
- Provide a name for the key, such as "CS104 VM Key", "MacBook Key" or "aludra Key"
- Display the contents of your
id_rsa.pub
file by typing the following command at the terminal prompt.
cat ~/.ssh/id_rsa.pub
- Copy the contents of your id_rsa.pub file and paste them into the key field. Make sure you copy the entire contents of the id_rsa.pub file. It should start with
ssh-rsa
and end with your email address. - Click Add Key
In your Notification Settings, apply the following settings:
Notifications
- Automatically watch repositories: ON
- Participating: Email ON, Web ON
- Watching: Email OFF, Web ON
Email notification preferences
- Comments on Issues and Pull Requests: ON
- Pull Request reviews: ON
- Pull Request pushes: ON
- Include your own updates: OFF
Homework grade reports are released through GitHub, and using the above settings will ensure that you receive email notifications when your grade report is available.
4 - Using Git
Now that all your settings are in place, you are (finally) ready to use Git!
Note: While the following procedure will orient you to using git
we recommend watching this video Tutorial by Prof. Redekopp before starting your HW1.
4.1 - Create GitHub Repository
A repository is a place to host your code. You can think of it as a directory or folder in a cloud server (i.e. GitHub server). Just like a folder in your Google Drive or Dropbox, a repository can contain sub-directories and files. Unlike cloud drives, changes to your local copy of the repository are not automatically synced to GitHub servers (and for good reasons).
To create a new repository, go to GitHub's "Create a new repository" page and enter the following information:
- Owner: Set yourself as the owner and not any organization you belong to.
- Repository Name: Choose something reasonable and self-explanatory, such as "cs104-git-practice".
- Desctiption (optional): When you use the repository for an actual project, you may want to include a descritpion for your project. The repository we create right now is only used for you to learn Git commands so you can leave the field empty.
- Public/Private: Public
- Initialize this repository with a README: ON
- Add .gitignore: C++ (We will explain what this is later)
- Add a license: None
Click Create Repository and you should be taken to the repository page.
4.2 - Clone Your Repository
At this stage, we created a repository to host our code called a code. We now need to make a local version of the repository to work with it. The is called cloning the repository. To do that, you need to get the cloning URL by visiting the page of the repository you just created in GitHub and look for the SSH clone URL.
Go to your repository page and look for the green Clone or download button.
Click on Clone or download and select Clone with SSH. Click on the button to the right of your repository url to Copy to clipboard. You can use the botton at the top right to toggle between Use HTTPS and Use SSH.
Go back to your course VM and open terminal. Using that URL, you can clone the repo using the following commands in the Terminal.
# Change directory to your home directory
cd
# Clone the repository. Replace the url with what you copied from GitHub in the previous step.
git clone git@github.com:TTrojan/cs104-git-practice.git
If promted with the following question, type yes and press Enter.
The authenticity of host 'github.com (192.30.255.112)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?
You should see something like this when git is done cloning:
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
Checking connectivity... done.
Now you have clone the repository to your local machine, you can start working in it.
# Start working in the repository
cd cs104-git-practice
4.3 - HelloWorld.cpp
Use your favorite editor to write a HelloWorld program in a file called HelloWorld.cpp
:
# include <iostream>
int main()
{
std::cout << "HelloWorld!" << std::endl;
}
Since we have made progress in our code, it is a good idea to commit that code to the repository and make part of our code history. To see what files changed, you run the following command:
git status
You will get something like:
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
HelloWorld.cpp
nothing added to commit but untracked files present (use "git add" to track)
In the above status message, git is telling you that you have one file that is not currently tracked by your repository and that file is called HelloWorld.cpp
. If you want to add the file to your repository, you need to use the git add <file>
command. Here is an explanation of the some of the terms:
- branch master: you are currently working on the main thread of developement that is called by default: master.
- origin/master: in this context, origin/master refers to the master on GitHub.
- Your branch is up-to-date with 'origin/master': your local repository is sync-ed with the GitHub server. (Hint: this is since the last time you received an update from the server, which may or may not be the server's latest state).
- Untracked files: files that are not part of the repository and were never added to the repository before.
4.4 - Commiting Changes
To track HelloWorld.cpp
, we use the following command:
# Add HelloWorld.cpp
git add HelloWorld.cpp
Now, let's check the status of our repository:
git status
You notice we get:
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: HelloWorld.cpp
This tells us that we just added a new file called HelloWorld.cpp
and we are ready to commit. Technically, we moved this new file from being untracked to be staged for commit. You can continue working on other files and you can stage them too. Once you feel that you are ready to committed, i.e. be part of the repository history, you use the following command:
# Commit with a message
git commit -m "My first HelloWorld using git"
This will commit HelloWorld.cpp
and make it part of repository history. Each commit must have a message associated with it. You can add the message as part of the commit command using the -m
option (see code above) or git will prompt you for a message using the editor you configured in section 3.
To check the commit history for the repository, you use the log
command:
# See the commit history of the repository
git log
Which will give us the following message
commit df7cd3feda8a856de9cb2dc4bc132f15f7842bb1
Author: Tommy Trojan <ttrojan@usc.edu>
Date: Tue Jan 14 17:42:52 2014 -0800
My first HelloWorld using git
commit 6d9fe80012ff9bf5b43120a87dc61bf196fec313
Author: Tommy Trojan <ttrojan@usc.edu>
Date: Tue Jan 14 15:57:08 2014 -0800
Initial commit
The commit history of this repository shows that we have two commits in reverse chronological order. For each commit, you see the commit id (which is a SHA1 checksum), the author, the time the commit was made and the commit message.
4.5 - Pushing to the Server
Now that we committed successfully, let's check the status of our repository
# Check status of repository
git status
You will notice something different about this message:
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
It says that we are: ahead of 'origin/master' by 1 commit. If you go back to your repository page in GitHub, you will find that it only has one commit as opposed to the two you have locally. Since git is distributed, it allows you to work "offline" by committing locally and only pushing to the server once you feel ready to do so.
[Hint] Commit often and commit early. Try to push to the server as soon as you have a good portion of your code complete so you have a backup of your code. Never leave your coding session before pushing to the server.
To push your changes to the server, you use the following command
# Push changes to remote
git push
Now, check the commits section of your code repository by clicking on the commits links in your repository's page
4.6 - Keeping Your Repo Up to Date
Since git uses the distributed model, you can have multiple copies of the repository on multiple machines. This makes it important to make sure your local version is up to date. Here is a practical example of what could happen.
- Go to your repository on GitHub
- Click on the
HelloWorld.cpp
file - Click on Edit to edit the file online
- Let's update
HelloWorld.cpp
:- Change
HelloWorld!
toFightOn!
- In Commit changes type:
School pride
- Change
- Click _Commit changes`
Visit the commits page in your repository and note how many commits you have. Now, go to your local repository and check the status of your repository:
# Check status of repository
git status
You should get
On branch master
nothing to commit, working directory clean
If you check the commit history, how many commits will you see:
# Produce commit history with one line per commit
git log --pretty=oneline
Notice that despite that you have 3 commits in total, you can only see 2 on your local machine. Because git compares your local repository to the remote repository using the lastest update from the server, it may or may not be the server's latest state.
To get an update from the server and bring your local repository up to date, you need to pull from the server:
# Get the latest updates
git pull
You will get a response that looks like:
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:TTrojan/cs104-git-practice
df7cd3f..1ffe7e8 master -> origin/master
Updating df7cd3f..1ffe7e8
Fast-forward
HelloWorld.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Here, git is telling you:
+ It is updating from git@github.com:ttrojan/HelloWorld.git
+ It updated master
+ The update was from commit df7cd3f
to commit 1ffe7e8
- HelloWorld.cpp
has two changes - one insertion and one deletion.
- There was one file changed
- There was one line inserted
- There was one line deleted
If you want to see in detail what the changes in the last commit were, you issue this command:
git log -p -1
To see
commit 1ffe7e8b5e776395126fb6e06fc72f5af12ab063
Author: Tommy Trojan <ttrojan@usc.edu>
Date: Tue Jan 14 18:53:08 2014 -0800
School pride
diff --git a/HelloWorld.cpp b/HelloWorld.cpp
index 55818b8..b9a284d 100644
--- a/HelloWorld.cpp
+++ b/HelloWorld.cpp
@@ -1,5 +1,5 @@
#include <iostream>
int main() {
- std::cout << "HelloWorld!" << std::endl;
+ std::cout << "FightOn!" << std::endl;
}
4.7 - Ignoring Files
Code repositories are intended for just that, code. When working on a programming project, you may get a number of different files such as: object files, executables, log files and sometimes compiled header or library files. It is important to keep your repository clean of such unecessery files.
git uses a file named .gitignore
to list all files or file extensions that git should not track or report when you do a git status
. Your repository now has a list that was auto generated by GitHub. You can see that list by typing the following command from within your repository:
# List the contents of .gitignore
cat .gitignore
Let's compile our HelloWorld.cpp
to get the executable helloworld
:
# Compile HelloWorld.cpp
g++ -g -Wall HelloWorld.cpp -o helloworld
# Run the executable
./helloworld
Now, if we do a git status
, we will get the following output:
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
helloworld
nothing added to commit but untracked files present (use "git add" to track)
Since helloworld
is an executable, we don't want to add it to the repository and we definitly don't want git status
to keep bugging us about it. Append helloworld
to .gitignore
.
Now, do a git status
and examine the output:
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitignore
no changes added to commit (use "git add" and/or "git commit -a")
As you can see, we are no longer prompted for helloworld
. However, we now need to commit our changes to .gitignore.
# Add .gitignore after modifying it
git add .gitignore
# Commit the changes
git commit -m "added helloworld to the list of ignored files"
# Pushing the changes to the server
git push
[IMPORTANT] When you turn in your homework through GitHub, you should not add any binary files to your repository. This includes executables and object files (more on this later in the class). You will lose points for turning in these files. As a general rule of thumb, anything that you write should be included and anything that we can generate by running compiling commands should be excluded.
4.8 - Let's Git Going
To summarize, we learned the following git commands:
# Clone a repository
git clone git@github.com:TTrojan/cs104-git-practice.git
# Add an untracked or modified file
git add <file1> <file2> <...>
# Remove a file from your git repository AND your local repository
git rm <file1> <file2> <...>
# Commit files that are staged for commit
git commit -m "non-optional commit message"
# Push commits to the server
git push
# Check the status of the repo
git status
# Let's make sure our repository is up to date
git pull
# See the commit history
git log
# See the commit history by printing a summary of each commit in a line
git log --pretty=oneline
# See the log of the last commit (-1) showing diffs of all the files (-p)
git log -p -1
When you are working on your homework, you should ALWAYS use git pull
before you start. As you progress, you should sync your changes to the server often, using git add
, git commit
, and git push
.
5 - Important Repositories
You will need to be added to the usc-csci104-fall2019 in order to access all course-related repositories. To check whether you have access, open the organization page.
If you see a list of repositories, then you have joined the organization already and you may continue to Section 5.1.
If you are promted with a message that you've been invited to join the usc-csci104-fall2019
organization, go on to View Invitation:
You should be taken the organization's invitation page and click on Join usc-csci104-fall2019:
If you see something like this, then you are not added to the organization yet. See section Section 5.4 for instructions on how to get added to the course organization:
5.1 - Homework Repository
We have created a private repository named hw-username
for you (you'll see your USC ID instead of username). You can access it by going to https://github.com/usc-csci104-fall2019/hw-username (replace username with your USC username).
This will be your homework repository where you will be doing all your homework assignments. In order for us to grade you, all your work must be pushed to your homework repository.
Try to clone it now. Go to a top-level folder on your VM (not the repo folder you just used for HelloWorld.cpp
).
Enter the command below, replacing username
with your USC username:
git clone git@github.com:usc-csci104-fall2019/hw-username.git
You should see the repo cloned successfully. You can now cd
(change directory) to that folder:
cd hw-username
This is where you should do all of your homework assignments and put all of the related files. Do not put your code in the test repository you created earlier in the lab under your own public account. That was just a demo. Instead, you MUST put all your code in this hw-username
repo (each HW will have a separate subfolder like hw1
, hw2
, etc.). Failure to do so may lead to you receiving a 0 on your HW assignment(s).
5.2 - Homework Resources Repository
The homework_resources repository is where we post things related to your homework. This includes any skeleton code, sample test cases, and grading rubrics (after grades are released).
5.3 - Labs Repository
The labs repository is where we post things skeleton lab code. Starting from lab 2, you will need to use skeleton code from this repository to finish lab assignments.
5.4 - Cannot access a course repository?
If you cannot access the orgnization page or you get an error (i.e. 404 This is not the web page you are not looking for) when trying to access all of the repository links, please make sure that you have set up your GitHub Account correctly, following these steps.
If you can access some of the above links but not all of them, please let your lab instructor know. Give them your USC username, and the repositories that you cannot access.
If you joined the class late (i.e. missed first week of class/lab), or if you still cannot access your repository during the second week of class, please let your lab instructor know. Give them your USC username.
6 - Git Resources
For more on git and how to use it, see the following resources.
Video Tutorial by Prof. Redekopp
[CAUTION] Unless you are already familiar with Git, please avoid using any commands that you do not already know on course related repositories (i.e. labs, homework-resources, and hw-username). You are welcome to create your own repository and test out Git's various commands there.