2.3 Repositories, Commits, and History
Key Takeaways
- A Git repository is the project files plus the full revision history stored as commits in the object database (the hidden .git directory on a non-bare clone).
- The working tree is the checked-out files you edit; the index (staging area) is what the next commit will contain; a commit is an immutable snapshot identified by a SHA.
- git add stages; git commit records a snapshot; git status reports untracked, modified, or staged files; git log walks the commit graph.
- git clone copies the full repository including history, branches, remotes, and .git; downloading a ZIP is a snapshot of files at one ref with no Git history.
- A commit SHA is a 40-character hexadecimal object name (often abbreviated to about 7 characters in the GitHub UI) that uniquely identifies that snapshot.
GitHub Docs defines a repository (a Git project) as the entire collection of files and folders associated with a project, along with each file's revision history. The file history appears as snapshots in time called commits. Those commits can later be organized into multiple lines of development called branches (section 2.4). This section is the first half of GH-900's compound bullet "Identify key Git concepts such as repositories, commits, and branches": the container and the snapshots. Branches, HEAD, and the default branch come next.
What is inside a repository
On disk, a non-bare clone is an ordinary folder of files (the working tree) plus a hidden .git directory. .git holds the object database, refs (branch and tag names), configuration, and hooks. Delete .git and you still have files, but you no longer have a Git repository: no git log, no branches, no remotes.
A bare repository is the form usually served as a remote: a directory, often named project.git, that contains the Git administrative files at the top level and has no working tree. GitHub's hosted remotes behave like bare repositories. You do not "open" GitHub's copy in a text editor; you clone it, which gives you a working tree plus .git that talks to that remote (conventionally named origin).
Because Git is distributed, every complete clone is a full repository. There is no required central copy for Git to function. GitHub is a convenient, permissioned, backed-up remote — not the only copy of history.
Working tree, staging area, commit
Git tracks change in three layers. GH-900 expects you to keep them distinct.
| Layer | Also called | What it contains | Typical command |
|---|---|---|---|
| Working tree | working directory, worktree | The files you actually edit. May be "dirty" (uncommitted edits) or "clean" (matches HEAD). | edit files; git status |
| Index | staging area | The snapshot Git will record on the next commit. You choose what goes in. | git add, git restore --staged |
| Commit | snapshot, revision | An immutable object in history: tree + parent(s) + author + message, named by SHA. | git commit |
GitHub Docs describes the two-step snapshot: git add stages a change; git commit saves the snapshot to project history. Staging and committing separately gives you control over history without changing how you edit files. You can edit five files and commit only two.
git status reports files as untracked, modified, or staged. git diff (unstaged) versus git diff --staged (what the next commit will include) is how you review before you snapshot.
Commit anatomy
As a noun, a commit is a single point in Git history. As a verb, to commit is to store a new snapshot from the index and advance HEAD to that snapshot. A commit object records:
- A pointer to a tree (the directory of files at that revision)
- One or more parent commits (the first commit on a new repo has none; a merge commit has two or more)
- Author, committer, timestamps, and a message
Git identifies every object — including each commit — by a cryptographic hash of its contents. In Git's glossary this is the object name, colloquially the SHA (historically SHA-1), shown as a 40-character hexadecimal string. GitHub's UI commonly abbreviates it to about seven characters (a1b2c3d). Two different snapshots cannot share a SHA. Change one byte in the commit (including the message or parent) and the SHA changes. That is why rewritten history is not "the same commits with a tidier log" — it is new objects.
git log walks the commit graph from HEAD backward. GitHub's Commits tab is the same walk. git show <sha> displays one snapshot. You can check out an old commit to inspect files as they were; unless you create a branch there, HEAD is detached (covered in 2.4).
Clone versus download ZIP
This comparison is a GH-900 favorite because GitHub's Code button offers both.
git clone | Download ZIP | |
|---|---|---|
| What you get | A Git repository: working tree and .git | A snapshot of files at one ref (usually the default branch) |
| History | Full commit graph (unless a shallow clone) | None |
| Branches | Local default branch plus remote-tracking branches | The tree of whichever ref you downloaded |
| Remotes | origin is configured | No remotes |
Can you git log / git commit / git push? | Yes | Not until you git init (and then you still have no upstream history) |
| Typical use | Ongoing work, contributing, GitHub Flow | Quick read-only copy of current files |
A shallow clone (git clone --depth=1) is still a Git repository: it has .git, you can commit, and you can deepen history later. A ZIP is not a shallow clone. It is an archive of files.
GH-900 trap: "Clone and ZIP both copy the repo." They both copy files. Only clone copies the repository. If the stem asks how to contribute, open a pull request, or inspect git log, the answer is clone (or GitHub Desktop / Codespaces, which clone for you). If the stem asks how to grab today's Markdown files with no Git tooling, ZIP is enough.
Scenario: Jordan needs history
Jordan downloads docs-main.zip from GitHub to fix a typo. They edit README.md, but there is no git commit and no origin. They cannot open a pull request from that folder. The fix is to git clone https://github.com/org/docs.git (or use GitHub Desktop), create a branch, commit, and push. The ZIP was a file dump, not a repository.
How GitHub presents the same concepts
On github.com you still have a repository, commits, and history. The Commits tab is git log. Clicking a SHA opens that snapshot. The Code → Download ZIP button is the non-Git snapshot. The green Code → clone URL (HTTPS or SSH) is what git clone needs. Editing a file in the web UI still creates a Git commit; GitHub just runs git add / git commit for you and lets you pick the branch.
git init plus git remote add origin is how you publish a new local project to an empty GitHub repository. git clone is how you start from a project that already exists on GitHub. Do not initialize a GitHub repo with a README if you already have a local repo with commits — you will create two unrelated histories and a non-fast-forward push.
On the exam, map the words:
- Repository = files + commit history (not "a GitHub webpage")
- Commit = immutable snapshot with a SHA (not "saving a file")
- Working tree = files you edit (not "the GitHub website")
- Staging = choosing what the next snapshot includes
- Clone = full Git copy; ZIP = files only
A teammate uses GitHub's Code button and chooses Download ZIP instead of cloning. What do they have on disk?
What uniquely identifies a Git commit as an immutable snapshot in history?
You edited three files. git status shows two as modified and one as staged. What is the difference between the working tree and the staging area in this situation?