Lesson 01 / 15
What Is Version Control
The problem version control solves; the promises of history, reversibility, and collaboration; and a comparison of snapshot-based and diff-based storage.
Contents
The Programming Fundamentals course covered how a program is written; this course is concerned with how the written program changes over time. A file is not written once and set aside: it is corrected, extended, broken, reverted. Working without recording this sequence of changes produces a program whose only known state is its last one.
This lesson defines the problem version control solves and separates the three promises the solution carries. Commands begin in the next topic; the model built here is the vocabulary the rest of the course will use.
Manual Version Management and Its Limits
The most direct way to keep records is copying: a version of the file is backed up before work begins, and the next version is saved under a separate name. The result is a directory that looks like this:
search.sh search-backup.sh search-working.sh search-final.sh search-final-2.sh
This scheme has four separate flaws, and all four are structural:
- There is no ordering information. File names do not say which version was
derived from which. The relationship between
search-final.shandsearch-working.shexists only in the author’s memory. - There is no record of rationale. Why a line changed is written nowhere. Someone looking at the same line six months later cannot tell whether the change was a fix or an experiment.
- There is no change integrity. A fix often touches more than one file. Copying file by file does not record at which moment these files were consistent together.
- Concurrent work is undefined. If two people change copies of the same file separately, there is no rule for merging the two copies; one overwrites the other.
A version control system is a recording scheme designed to remove these four flaws. It stores changes not file by file, but in wholes called commits; it attaches a rationale text, an author, and a predecessor to every commit.
Three Promises
The guarantees version control offers fall under three headings.
History. Every commit represents the project’s complete state at that moment and links to the commit before it. This chain of links makes the question “when was this line written, by whom, and for what reason” answerable. A significant part of reading code is spent answering this question.
Reversibility. Every recorded state can be retrieved again. This makes bold changes cheap: the cost of an experiment is the cost of undoing it. When the cost is low, the number of experiments rises. The course’s third topic is devoted to these undo tools.
Collaboration. More than one person working on the same project requires changes to be merged. Because a version control system knows which common ancestor each change was derived from, it turns merging into a rule-governed operation. In this course, collaboration will appear only as the rationale for design decisions; its practice is the subject of the Branching and Collaboration course.
Snapshot or Diff
How a system stores history determines the operations it can offer. There are two basic designs.
Diff-based storage. The system stores the first version in full; for every version after that, it records only the difference from the previous version. This is economical in storage. Its cost is that obtaining any version means starting from the beginning and applying the diffs in order: the cost of reaching version is .
Snapshot-based storage. The system stores an image of the project’s entire file tree at every recorded moment. Reaching a version means looking directly at that image: . At first glance it looks wasteful — will every file be rewritten at every record?
What removes the waste is the idea of content-addressed storage. Every file’s content is named by a hash value computed from that content, and stored under that name. The same content is never stored twice; unchanged files share the same object across consecutive snapshots. The Data Structures course examined hash functions’ avalanche effect and collision probability; here, the same functions are used as an identity generator.
This way, the snapshot model largely keeps the diff model’s storage advantage while
bringing access to a version down to constant cost. The system this course covers —
git — uses the snapshot model.
The Shape of History
History is not a simple list. Every commit links to a predecessor commit; a commit can have more than one successor (two separate directions were tried from the same point), and a commit can have more than one predecessor (two directions were merged). The links point toward the past, and a commit cannot be its own ancestor.
These three properties say that history is a directed acyclic graph. This structure was defined in the Data Structures course, and its topological ordering was covered in the Algorithms course. The correspondences here are exact:
| Graph concept | Counterpart in history |
|---|---|
| Node | A commit |
| Edge | The link from a commit to its predecessor |
| Acyclicity | A commit cannot be its own ancestor |
| Topological order | Listing history in a readable order |
| Common ancestor | The commit where two directions diverged |
Listing a history “from newest to oldest” is one of the graph’s topological orders. In a history with no branching, this order is unique; if there is branching, more than one valid order exists, and the system has to choose which one to show.
(A) ← (B) ← (C) ← (D) unbranched history: a single chain
┌── (C) ← (D)
(A) ← (B) ←─┤ branched history: two directions
└── (E)
The arrows point toward the past: every node points to its own predecessor. Once a commit is written, its content does not change; history only grows from its ends. This immutability is the key to understanding how the undo tools work, and it will come up again in the third topic.
Not the Same Thing as Backup
The two schemes are confused because both promise “bringing back the old state”; the promises they make are different.
Backup is kept to recover the state at one point in time. Its purpose is preventing data loss; it does not record who changed what or why, and it offers no rule for merging two people’s work. A backup’s value is in being able to give back the last state at the moment it is needed.
Version control keeps the sequence of states and the rationale for every step. Recovery is only a side effect; the information it actually produces is the change itself.
The two do not substitute for each other. If a repository sits on only one machine, losing that machine takes the history with it; using version control does not make backup unnecessary. The next lesson will show how the distributed model spreads out this risk.
The distinction also determines the question of what gets recorded. What enters a repository is content written by a human and backed by a rationale: source files, configuration, documents. Build output and downloaded dependencies are reproducible from their sources, so there is no need for them to take up space in history; secrets, on the other hand, must never enter history at all, because once they enter they are permanent. The practice of this distinction is the subject of the Ignore Rules lesson.
The Course’s Example Repository
A single example project will be used throughout the course: a small piece of work
named sozluk. It holds three files — a description document, a text file holding
terms line by line, and a shell script that searches within it. The project will be
set up from scratch, every lesson will advance history by one step, and the lessons
in the third topic will make deliberate mistakes in the same repository and undo them.
The example’s smallness is deliberate: as the file count drops, it becomes possible to examine the object database’s content directly and verify the model by eye. The course’s goal is not to make you memorize a list of commands, but to build this model; commands stick in memory to the extent that they can be derived from it.
Summary
- Keeping versions by manual copying loses ordering, rationale, change-integrity, and concurrency information.
- A version control system stores changes not per file, but in wholes called commits.
- There are three basic promises: history, reversibility, and collaboration.
- Diff-based storage is cheap in storage, snapshot-based storage is cheap in access; content-addressed storage lowers the second model’s storage cost.
- History is a directed acyclic graph; nodes are commits, edges are predecessor links.
- Backup recovers the last state, version control keeps the sequence of states and their rationale; the two do not substitute for each other.
Next Step
What version control is has been defined; but the question of where history is kept remains open. On a single server, or as a complete copy on every participant’s machine? This choice determines which operations the system can perform without a network connection, and what is lost in the event of a failure. The next lesson will compare these two designs and their consequences.
To keep your progress and take notes, Log in
My notes
Log in to take notes.