Git Fundamentals

Advanced · 16 min read · ▶ live playground · ✦ checkpoint

One broken edit can erase an afternoon; Git turns that panic into a normal checkpoint. Version control is a system for recording project changes over time, and Git is the version-control tool most professional Python teams expect you to know.

Git is not GitHub. GitHub is a website for hosting and reviewing Git projects, while Git itself runs on your machine with no account, browser, or network connection required. Think of Git as the history notebook in your workshop: you decide when a page is worth saving, write a short label on it, and can later see how the project grew.

Why Version Control Is Non-Negotiable

When you write real code, the file on your screen is never the whole story. You try an idea, rename a function, add tests, break something, fix half of it, then wonder which change caused the mess. Without version control, your "strategy" becomes duplicated folders:

  • expense_tracker_final.py
  • expense_tracker_final_really.py
  • expense_tracker_before_i_broke_login.py

That works like keeping receipts in your pocket during a storm. Git gives you a project history that is searchable, named, and tied to exact file contents.

Version control matters because it lets you:

  • save known-good points while you experiment
  • explain why a change happened, not just what changed
  • work with teammates without emailing files around
  • connect testing, packaging, and deployment to exact project versions

You don't need all of Git today. You need the first professional habit: make small, named checkpoints.

How Git Thinks

A repository (often shortened to repo) is a project folder with Git history attached. Inside a repo, Git stores its private database in a hidden .git folder. Your Python files remain ordinary files; Git adds the history notebook beside them.

A snapshot is Git's record of what your project files looked like at one chosen moment. The analogy is literal enough: Git is taking a project photo, not recording a continuous video. Nothing becomes history just because you typed it. You choose the moments worth preserving.

Git talks about three everyday states:

  • Your working tree is the ordinary project folder on disk, the workbench where you edit files.
  • The staging area is Git's packing tray, where you place the exact changes you want in the next snapshot.
  • The repository history is the archive cabinet where Git stores saved snapshots.

A commit is one saved snapshot in the repository history, with an ID, an author, a time, and a message. The core loop reads like a sentence: check what changed, choose what goes into the checkpoint, save the checkpoint, then review the history.

Install and Configure Git

First, check whether Git is already installed:

git --version

You should see something like git version 2.53.0. If your terminal says the command is missing, install Git first.

On Windows, install "Git for Windows" from git-scm.com/downloads. It includes Git Bash, a terminal that understands common Unix-style commands.

On macOS, running git --version may prompt you to install Apple's command-line tools. Homebrew users can also run brew install git.

On Linux, use your distro's package manager, such as sudo apt install git on Debian or Ubuntu.

Now configure the identity Git writes into your commits. Your Git identity is the name and email stored in each commit so future readers know who made it; it is not your password. A branch is a named line of project history; for new repos, you want that default line named main.

$ git config --global user.name "Maya Patel"
$ git config --global user.email "maya@example.com"
$ git config --global init.defaultBranch main
$ git config --global --list
user.name=Maya Patel
user.email=maya@example.com
init.defaultbranch=main

Use your real name or the name you want teammates to see. Use the email attached to your GitHub account later if you want GitHub to connect your commits to your profile. Commit emails can become visible when you share history publicly; GitHub offers a no-reply email option, a generated address that keeps your personal email private.

The --global flag means "use this setting for my user account." You normally do this once per machine.

Initialize a Repo

Practice in a disposable folder, not inside a course repo or a work project. Maya is starting a tiny Python project that prints a snack inventory:

$ mkdir trail_mix_tracker
$ cd trail_mix_tracker
$ git init
Initialized empty Git repository in /Users/maya/projects/trail_mix_tracker/.git/
$ git status
On branch main
 
No commits yet
 
nothing to commit (create/copy files and use "git add" to track)

git init turns the current folder into a Git repo by creating .git. That hidden folder is the archive cabinet. Don't edit files inside .git by hand; use Git commands to talk to it. Before there are commits, Git knows the repo exists but has no saved snapshots. You only need main today; branching gets its own lesson in 19.3.

The Status, Add, Commit, Log Loop

Create tracker.py in your editor with this one line: print("Trail mix ready"). Then ask Git what it sees and stage the file:

$ git status --short
?? tracker.py
$ git add tracker.py
$ git status --short
A  tracker.py

An untracked file is a file Git can see but has not been told to include in history. The ?? means: "This file is on the workbench, but it is not in the packing tray or archive." The A means Git has put the file in the staging area as an addition. Staging is choosing the exact changes that belong in the next commit; it is not uploading, sharing, or saving history yet.

Now commit the staged change:

$ git commit -m "Start trail mix tracker"
[main (root-commit) c4f88d1] Start trail mix tracker
 1 file changed, 1 insertion(+)
 create mode 100644 tracker.py
$ git log --oneline
c4f88d1 Start trail mix tracker

Your commit ID is Git's generated label for one exact snapshot, and yours will be different from c4f88d1 here. A root commit is the first commit in a repo. The message is for humans, so make it specific enough that future-you understands the checkpoint.

Edit tracker.py in your editor so it also prints print("Cashews: 12"). Repeat the loop whenever you finish a small, coherent piece of work:

$ git status --short
 M tracker.py
$ git add tracker.py
$ git commit -m "Show cashew count"
[main c1b0e56] Show cashew count
 1 file changed, 1 insertion(+)
$ git log --oneline
c1b0e56 Show cashew count
c4f88d1 Start trail mix tracker

The leading M means modified, which means Git already knows the file but your working tree has changes not yet committed. You don't have to memorize every status symbol today. Build the reflex: run git status, read what Git says, then decide whether the change belongs in the next commit.

Commit size is judgment, not math. A good commit is like a clean test case from Section 16: small enough to understand, complete enough to be useful. "Add snack count display" is better than "stuff" and usually better than one giant commit that rewrites half the project.

Checkpoint

Answer all three to mark this lesson complete

You now have Git's first loop: status, add, commit, log. Next you'll inspect exactly what changed before committing and learn how to back out of mistakes without guessing.

+50 XP on completion