Learn
07.3 | GIT AND VERSION CONTROL
01 | BEYOND FINAL_FINAL.PY
Suppose your calculator works, then a new feature breaks it. Keeping files called final.py and final_really.py quickly becomes confusing. Version control records changes with messages and lets you inspect a project’s history.
Git is the version-control program. A repository contains the history and related metadata. GitHub is one possible hosting service; you can learn and use local Git without a GitHub account or uploading anything.
Install Git from its official site or your school’s approved software source. These examples are terminal commands entered inside a disposable practice project. Official Git downloads.
02 | START A LOCAL HISTORY
git init creates the repository metadata in the current folder. Check your location first so you initialise the intended project. Configure an author name and email locally for this practice repository. Commit metadata includes them, so use a suitable classroom identity if the history will be shared.
The local settings below apply to this repository. The .test email is an example, not an email verification or a real contact address. Later shared projects should use the identity policy you intend to publish.
Save app.py containing print("Planner ready") before staging. git status explains which files are untracked or changed.
TERMINAL | INSIDE YOUR PRACTICE PROJECT
git --version git init git config user.name "Practice Learner" git config user.email "learner@example.test" git status
03 | THREE PLACES TO UNDERSTAND
The working tree is the ordinary editable project files. The staging area, also called the index, is the version prepared for your next commit. A commit records that staged snapshot with its message and parent history.
git add app.py stages the current content of that file. It does not upload it. git commit records the staged content locally. A later edit changes the working file, but does not silently update the staged snapshot.
This distinction matters: if you stage a working version, edit it again and commit without adding again, the commit contains the earlier staged version. Inspect what you are recording.
| Place | Contains | Useful command |
|---|---|---|
| Working tree | Your current editable files | git diff |
| Index / staging area | The proposed next snapshot | git diff --cached |
| Committed history | Recorded versions and messages | git log --oneline |
TERMINAL | MAKE THE FIRST COMMIT
git add app.py git diff --cached git commit -m "Add planner greeting" git log --oneline
04 | PRACTISE A STAGED VERSUS UNSTAGED EDIT
After your first commit, edit the greeting to version two and stage it. Then edit the working file to version three without staging again. status can report the same file as both staged and unstaged.
git diff compares working changes with the index. git diff --cached compares staged changes with the current commit. Read both before committing.
Use small meaningful commits: “Validate task dates” tells a reader more than “stuff”. A commit is evidence of a recorded state, not proof that the code passes tests. Run the relevant tests before describing it as working.
05 | KEEP GENERATED AND PRIVATE FILES OUT
Create .gitignore before broadly staging a project. It contains path patterns for untracked files Git should normally ignore. Environments, caches, local databases and secrets are usually unsuitable for this teaching project’s source history.
Ignoring a file does not remove it from an existing commit or stop tracking a file already in the index. Review git status and staged changes before committing. If a real credential was published, simply adding its filename to .gitignore does not undo that disclosure; replace the exposed credential.
Keep schema and fictional seed code in history, while documenting how a fresh installation creates its local database. The planner’s sqlite file is user data, not the source schema.
.GITIGNORE | TEXT FILE
.venv/ .venv-check/ __pycache__/ *.pyc .env planner.sqlite3 planner.sqlite3-*
06 | A BRANCH IS ANOTHER LINE OF WORK
A branch name refers to a line of commit history. Creating a branch does not create another independent folder full of files. Switching changes the checked-out version in your working tree.
Begin with a clean working tree. Record the current branch name using git branch --show-current, because the initial branch may be main, master or another configured name. Save that name for the return step.
Create a report-feature branch, edit and test app.py, then commit. Switch back using the actual starting branch name and merge report-feature. Replace BASE_BRANCH below; it is a placeholder, not a literal required branch.
TERMINAL | CLEAN PRACTICE REPOSITORY
git branch --show-current git switch -c report-feature git add app.py git commit -m "Add task summary message" git switch BASE_BRANCH git merge report-feature
07 | WHEN CHANGES CONFLICT
A merge combines histories. If Git cannot safely combine competing edits to the same area, it reports a conflict and marks the affected content for you to resolve. It does not know which business rule is correct.
Read both intentions, edit a valid combined result, remove conflict markers, run tests, stage the resolved files and complete the merge commit. In a disposable practice repository, git merge --abort cancels an in-progress merge when you choose to return to its starting state.
A remote is a named external repository location. push sends commits there; pull obtains changes and integrates them according to configuration. They are separate from committing locally. Learn the local workflow before publishing a project.
08 | WATCH THE THREE SNAPSHOTS
Step through this fixed model: edit, stage, edit again and commit. It shows why a commit records the index rather than every unsaved intention. This is a browser illustration, not a real Git repository.
09 | INSPECT BEFORE YOU RESTORE
git show COMMIT_ID:app.py can display a file from a chosen commit without replacing your current source. Substitute a real ID from your history. Copying a useful idea into a new tested commit is often easier to reason about than rewriting history.
Some Git commands overwrite files or rewrite history. Do not experiment with reset --hard or forced pushes in valued work. In this lesson you can investigate history read-only with log, diff and show.
Git history is not a complete backup strategy. A local repository on a failed drive is still lost. Keep an appropriate separate backup of source and important data; do not assume untracked database files are included in commits.
10 | MAKE YOUR HISTORY TELL THE STORY
Write a three-commit story: a working greeting, a validated input, and a tested report. Inspect the differences and explain why each is one coherent change.
Ask a partner to read the history without your commentary. They should understand what changed and which tests supported the result. Version control improves collaboration when the recorded decisions are understandable.
PUT YOUR SKILLS TO WORK
Use the Section 7 challenges to practise these ideas independently. Work in your Python editor, predict results and keep a short test record.
Section 7 challenges Python course navigation