git: a tiny tutorial and cheat sheet

This is intentionally not a complete guide to git. It contains the small set of git ideas and commands you need for DATA 419.

The big idea is:

git lets you take named snapshots of a project, so you can see what changed and recover older versions later.


1. git is not GitHub

These are related, but they are different things.

What it is
git A program on your computer that keeps a history of changes to your files.
GitHub A website that can store a git project on the Internet and help people share and collaborate on it.

You can use git without using GitHub at all, and you will be, this semester.

For example:

git init .

starts git history for a folder on your own computer. It does not upload anything to the Internet.

(When we get to December, if you are sufficiently proud of what you have created this semester, and you have crafted it coherently enough for a third party to understand what you did, you may well upload your repo to GitHub so that you can share it and boast about it to (say) a potential employer. But you won’t be doing that immediately.)


2. Before using git: know where you are

git commands are typed at the command line: a Terminal on Linux or macOS, or PowerShell on Windows.

The easiest rule for this class is:

Run git commands from the top-level folder of your DATA 419 project.

To see what folder you are currently in:

pwd

To see what files and folders are there:

ls

To move into a folder:

cd foldername

To move up one folder:

cd ..

These commands work in Linux/macOS terminals and in Windows PowerShell.

If you created the cdlabs shortcut in homework #0, you can simply type:

cdlabs

to go to the top of your DATA 419 project.


3. The three things to picture

git is much easier to understand if you picture three places:

  1. Your project folder – the ordinary files you are editing.
  2. The staging area – the files you have selected for your next snapshot.
  3. The repository (repo)git’s stored history of completed snapshots.

The normal flow is:

edit files → git addgit commit

A commit is one saved snapshot. Every commit gets a short message such as:

Add data loading code

or:

Complete lab 2 analysis

Think of commits as save points in a game.


4. Starting git for a project: once

First try:

git status

If git gives you normal information about your files, the project is already under git’s control. Keep using it.

If git says this is not a git repository, and you are definitely in the correct project folder, initialize it once:

git init .

The dot means “this folder.”

A typical first commit is:

git status
git add .
git status
git commit -m "Create initial project files"

If git complains that it does not know who you are, run these once:

git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"

and then try the commit again.


5. The everyday git routine

This is the part worth memorizing.

After working for a while and reaching a sensible stopping point:

git status
git diff
git add .
git status
git diff --staged
git commit -m "Briefly describe what you changed"
git status

Here is what those commands mean.

git status

git status

asks git:

What is different right now from my most recent commit?

It is safe to run at any time. Run it often.

The most important phrases are:

git says… Meaning
Untracked files These files exist, but git has never been told to include them.
Changes not staged for commit You changed these files, but have not selected the changes for the next commit.
Changes to be committed These changes are staged and will go into the next commit.
working tree clean Nothing has changed since your latest commit.

git may print other informational lines too. You can ignore them for this course.

git add .

git add .

means:

Put the current changes in this folder and its subfolders into the staging area for my next commit.

This does not create the commit yet.

If you run git add . and then edit a file again, run git add . again if you want the newer edits included too.

git diff

git diff

shows the actual line-by-line edits you have made but have not yet staged. It only displays information; it does not change your files.

git diff --staged

git diff --staged

shows exactly what changes will be recorded if you commit right now.

git difftool

(You’ll see Stephen using difftool rather than diff in class, which brings up a nice side-by-side comparison of the changes. To get this configured for your system, tell your favorite AI what your tools/OS/environment are and ask it to help you get difftool working on your system.)

git commit

git commit -m "Briefly describe what you changed"

creates the snapshot.

Good commit messages describe what you accomplished:

git commit -m "Add code to download census data"
git commit -m "Complete lab 2 exploratory plots"
git commit -m "Fix missing-value handling"

A message like “stuff” or “finally done for tonight!” will not help you much three weeks from now.


6. Looking at your history

To see your commits:

git log --oneline

You might see:

8c41d2a Fix missing-value handling
3e92f77 Complete lab 2 analysis
0a71b4c Add data acquisition code
bb12e91 Create initial project files

The newest commit is at the top.

The strange code at the left (8c41d2a, for example) is the commit’s hash: its ID number. You use hashes when you want to refer to particular old snapshots.

If git fills the screen with output, press:

q

to return to the command prompt.


7. Seeing what changed

What did one particular commit change?

git show HASH

For example:

git show 8c41d2a

This shows the commit message and the line-by-line changes made in that commit.

What did one file look like in an old commit?

git show HASH:path/to/file.py

For example:

git show 8c41d2a:lab2/analysis.py

This only displays the old file. It does not alter your current copy.

What changed between two commits?

First get their hashes with git log --oneline, then:

git diff OLD_HASH NEW_HASH

For example:

git diff 3e92f77 8c41d2a

To compare only one file:

git diff OLD_HASH NEW_HASH -- path/to/file.py

In git’s comparison output, lines beginning with - come from the older version and lines beginning with + come from the newer version.


8. Going back when something goes wrong

Throw away unstaged changes to one file

First inspect them:

git diff path/to/file.py

If you are certain you want to discard those edits:

git restore path/to/file.py

Warning: if those edits were never committed, git cannot bring them back.

Bring back an old version of one file

First make sure your current work is committed. git status should say:

working tree clean

Find the old commit with:

git log --oneline

Then restore that old version of the file:

git restore --source=OLD_HASH -- path/to/file.py

Inspect it with git diff. If you like the result, commit it normally:

git add .
git commit -m "Restore earlier version of analysis.py"

Make the whole tracked project match an old commit

Again, start only when git status says working tree clean.

Find the old commit, then:

git restore --source=GOOD_HASH -- .
git status
git diff
git add -A
git commit -m "Restore project to earlier working version"

This creates a new commit containing the restored old contents. Your later history is still there; you have not erased it.

Undo one bad commit

If one particular commit was a mistake, first make sure your current workspace is clean. Then use the hash of the bad commit:

git revert --no-edit BAD_HASH

git makes a new commit that reverses the bad one. Again, the history is preserved rather than erased.

If git reports a conflict during a restore or revert, stop and ask for help rather than guessing.


Cheat sheet

What I want Command
See where I am pwd
See files here ls
Go to DATA 419 project cdlabs (if you created it)
Check current git situation git status
See unstaged edits git diff
Stage current changes git add .
See what is staged git diff --staged
Make a snapshot git commit -m "Describe the change"
See commit history git log --oneline
See what one commit changed git show HASH
See an old version of one file git show HASH:path/to/file.py
Compare two commits git diff OLD_HASH NEW_HASH
Discard unstaged edits to a file git restore path/to/file.py
Restore an old version of a file git restore --source=HASH -- path/to/file.py
Undo one bad commit git revert --no-edit BAD_HASH
Quit git’s scrolling viewer q

The one routine to memorize

git status
git diff
git add .
git status
git diff --staged
git commit -m "What I just accomplished"
git status

Do this whenever you reach a sensible stopping point.

Several clear commits made along the way are far more useful than one giant commit at the end.


Based in part on Stephen Davies, Blueprints: Creating, Describing, and Implementing Designs for Larger-scale Software Projects, especially pp. 215-228: https://stephendavies.org/blue.pdf.