Overview
traditional save patterns without git
Traditionally we may save a file in-place, or to a new file.
Saving in place is destructive: it does not preserve the old version.
Saving to a new file is not destructive, but it leads to another challenge: managing multiple versions of a file, including managing the name and the location. Doing this manually is cumbersome and error-prone.
saving the snapshot of a project
Software projects are made of multiples files, that live in one or multiple directories. The root directory contains all the others. To run or compile such a project, we need the files to be present in the directory.
As such, if we want to run the project as to how it is at one point in time, we must first save the whole file tree as a snapshot, so that we may reconstruct it any time.
The simpliest way to save a filetree is to archive it as-is, while we make a full, distinct copy for futher editing.
This method leads to heavy storage footprint and clutter the filesystem. It requires naming each snapshot with a distinct name, and navigating between snapshots may not be convenient.
what we want from a versioning software
We want an approach that is more efficient in terms of storage and more convenient in that we don't name snapshots. We want to store metadata, such as a message that summarizes the change, a unique identifier, the date and potentially more.
We want the ability to browse old snapshots of the project. Those snapshots must be reconstructed on-demand rather than being stored as-is.
The software must manage the storing and retrieving of file versions, and to ensure they are not duplicated.
lightweight snapshot: a declarative list of files
We store the snapshot as the declarative list of files that make up its content (their names), like a shopping list. The software may reconstruct the snapshot from this list.
In this pattern, the files may live anywhere, for example in a storage area. This allows files to be referred to by several snapshots, and to only be stored once.
When needed, the software fetches the files from the storage and place them (a copy) in a directory, effectively reconstructing the snapshot.
easy edit of the latest or selected snapshot.
We want the latest snapshot (or rather a copy of its content) to always be present as an actual directory in our filesystem, so that we may easily edit it and submit a new snapshot for save. We call this directory the working directory or working tree.
terminology
commit means to intentionally save a snapshot of the project. As a name, a commit is the term that refers to a snapshot. Technically it's an object that stores references and metadata.
working tree, or working directory, means a local directory, initially a copy of the latest snapshot (or a specific snapshot) that we interact with and may freely edit, and prepare for submission.
staging area, also called the index, represents a tentative snapshot, that is yet to be committed.