hello.pyhello.py.envignored.gitignore6ad1b38hello.py v1parent06efb39hello.py v26ad1b38200778373d34f29d7c639d055b9e05818- print("Hello")+ name = input("Name? ")+ print("Hello,", name)# .gitignore.env__pycache__/06efb39 Ask for the name6ad1b38 Add greetinghello.pyv1
Working directory: the files you see and editStaging area: what the next commit will saveRepository: every commit, each named by its hashArrow: a commit points back to its parentThree mats show Git's three areas: the working directory (the files you edit), the staging area (what the next commit will contain) and the repository (every commit, kept in the .git folder). git add makes the hello.py card hop from the desk to the staging mat; git commit makes it hop into the repository, where it becomes a commit block labelled with its short hash. The second commit, 06efb39, points back to its parent, 6ad1b38. v1 and v2 are the two versions of hello.py. The hashes in this figure are real: they are the SHA-1 of the Git objects for this exact file, author (Sam), time (5 January 2026) and message. Any change to these gives different hashes.

Three areas

  1. Version control keeps every saved version of a project so you can look back. git init turns a folder into a Git repository: it adds a hidden .git folder, where Git will store every version you save.

Commits

Ignore and look back

Try it in a terminal

;; step 1/10 · git init
$ mkdir hello && cd hello
$ git init
Initialized empty Git repository in /home/sam/hello/.git/

Git's own name for the staging area is the index. After a commit it still holds the committed files, so when all three areas match, git status says: nothing to commit, working tree clean. The hashes in this figure are real: they are the SHA-1 of the Git objects for this exact file, author (Sam), time (5 January 2026) and message. Any change to these gives different hashes.