Before typing a single command, it pays to understand what problem Git solves and why it became the software industry's standard tool. Git is a distributed version control system: a program that records how a set of files evolves over time, lets you return to any earlier state, and coordinates several people working on the same code without stepping on each other. This lesson looks at how we worked before Git existed, where Git came from, how it differs from the centralised systems that preceded it, and why it won. You will also meet Ana, Bruno and Carla, the team who will accompany you through the whole course as they build an application called task-manager.

Contents

  1. The problem: how we used to do it
  2. What a version control system is
  3. A short history of Git
  4. Centralised versus distributed version control
  5. Why Git won
  6. What Git is not
  7. Our guiding thread: task-manager, Ana, Bruno and Carla

  1. The problem: how we used to do it

Anyone who has worked with files for any length of time has invented their own version control system. It usually looks like this:

Desktop/
├── task-manager/
├── task-manager_copy/
├── task-manager_v2/
├── task-manager_v2_GOOD/
├── task-manager_v2_GOOD_final/
├── task-manager_final_v2_GOOD.zip
├── task-manager_final_THIS_ONE.zip
└── task-manager_ana_reviewed_bruno.zip

The method half-works for a few days and then fails spectacularly as soon as the project grows or a second person joins. Here are its concrete problems:

  • You don't know what changed. There may be one line of difference between _v2 and _v2_GOOD, or three hundred. Finding out means comparing folder against folder by hand.
  • You don't know why it changed. A folder name doesn't explain intent. Three months from now, nobody will remember what got fixed in _THIS_ONE.
  • You don't know who changed it. Once a .zip has been e-mailed between three people, authorship is gone.
  • It eats enormous amounts of space. Every copy duplicates the entire project even when a single file changed.
  • Merging is a nightmare. If Ana touches styles.css and Bruno touches the same file in his copy, combining the two means opening both files side by side and copying lines across by hand.
  • There is no single source of truth. With five "good" folders around, nobody knows which one to publish.

A version control system attacks exactly these six points.

  1. What a version control system is

A version control system (VCS) is a program that:

  1. Saves snapshots of a project's state at specific moments that you choose.
  2. Attaches metadata to each snapshot: who created it, when, and with what explanatory message.
  3. Lets you retrieve any earlier snapshot, compare two of them, or follow how a particular file evolved.
  4. Lets you work in parallel on independent lines of development and then bring them together.

The key difference from _GOOD folders is that the history stops living in file names and moves into a database the system manages for you. On disk there is only one project folder; the full history sits hidden alongside it.

Version control systems are usually grouped into three generations:

Generation Examples Core idea Main limitation
Local RCS, SCCS History on your own machine, file by file A single user, no collaboration
Centralised (CVCS) CVS, Subversion (SVN), Perforce One server holds the history Total dependence on the server
Distributed (DVCS) Git, Mercurial, Bazaar Every copy contains the full history Steeper learning curve

Git belongs to the third generation, and that design decision explains almost everything else about it.

  1. A short history of Git

Git's origin is tied directly to the development of the Linux kernel.

  • 1991–2002. Kernel patches travelled by e-mail as text files. With thousands of contributors, the system became unmanageable.
  • 2002. The project adopted BitKeeper, a distributed proprietary tool whose licence allowed free use by kernel developers.
  • 2005. That free licence was withdrawn after a dispute between the owning company and part of the community. The kernel was suddenly left without a version control system.
  • April 2005. Linus Torvalds started writing his own system. The requirements he set himself were explicit and radical:
    • Speed, because the kernel is enormous and everyday operations had to feel instant.
    • A simple design underneath, even if the interface was austere.
    • Strong support for non-linear development, meaning thousands of parallel branches.
    • Fully distributed, with no mandatory server.
    • The ability to handle kernel-sized projects without degrading.
    • Guaranteed integrity: corrupting the history without anyone noticing had to be impossible.

Development moved at a furious pace: within weeks Git was hosting its own code, and shortly afterwards the kernel's. In July 2005 Torvalds handed maintenance to Junio Hamano, still the lead maintainer today, under whose direction Git gained the friendlier interface we use now.

About the name. "git" is a colloquial British English word meaning, roughly, "unpleasant person". Torvalds joked that he makes a habit of naming his projects after himself. The documentation also offers other retroactive readings, such as Global Information Tracker.

  1. Centralised versus distributed version control

This is the most important conceptual distinction in the lesson.

The centralised model (CVS, Subversion)

One server holds the project's complete history. Developers keep only a working copy on their machine: the files at their current version, with no history. Almost any operation — viewing the history, creating a branch, committing a change, comparing against an old version — requires talking to the server.

graph TD
    S[(Central server<br/>full history)]
    A["Ana<br/>working copy<br/>(no history)"]
    B["Bruno<br/>working copy<br/>(no history)"]
    C["Carla<br/>working copy<br/>(no history)"]
    A -->|commit / update| S
    B -->|commit / update| S
    C -->|commit / update| S

The direct consequences:

  • If the server is down or the network is unavailable, you cannot work beyond editing files.
  • If the server's disk dies and there is no backup, the entire history is lost.
  • Every commit travels over the network, so operations are slow.

The distributed model (Git)

Each person holds a complete repository, with the whole history back to the first commit. A shared server still exists, but as an organisational convenience rather than a technical necessity: it is simply one more repository that everyone has agreed to synchronise with.

graph TD
    R[("Shared repository<br/>full history")]
    A["Ana<br/>full repository<br/>+ working copy"]
    B["Bruno<br/>full repository<br/>+ working copy"]
    C["Carla<br/>full repository<br/>+ working copy"]
    A <-->|push / fetch| R
    B <-->|push / fetch| R
    C <-->|push / fetch| R
    A <-.->|direct exchange possible| B

The direct consequences:

  • Ana can browse the history, commit changes and create branches on a plane with no wifi.
  • Every clone is a backup of the entire project.
  • Bruno and Carla could exchange work directly between their machines without going through the server.

Comparison table

Aspect Centralised (SVN / CVS) Distributed (Git)
Where the history lives Only on the server In every copy of the repository
Working offline Practically impossible Everything except synchronising
History speed Depends on the network A local disk read
Cost of creating a branch High: a server-side copy, a heavy operation Minimal: a file holding an identifier
Committing a change Publishes to everyone instantly Local; you publish when you decide to
Risk if the server dies History lost unless backups exist Any clone can restore it
Version identifier A sequential number (1, 2, 3…) A cryptographic hash of the content
Typical unit of work A file or a directory The whole project (a snapshot)
Per-folder permissions Supported natively No; handled with separate repositories or external tools
Large binary files Handled reasonably well Needs extensions such as Git LFS

No tool is perfect: Subversion remains reasonable for huge binary repositories that need fine-grained per-folder permissions. But for software development, the distributed model won hands down.

  1. Why Git won

Git was not the only distributed system: Mercurial and Bazaar appeared at almost the same time. These are the technical and circumstantial reasons behind its dominance.

5.1 Speed

Nearly every operation is local. Viewing the history of app.js, comparing today's version with last month's, or switching branches are disk reads, not network requests. Where SVN took seconds, Git takes milliseconds. That difference changes how you work: when checking the history is instant, you check it constantly.

5.2 Cheap branches

In Git, a branch is literally a 41-byte file containing a commit identifier. Creating one is instant and duplicates nothing. That turned an operation which centralised systems treated as exceptional and frightening into an everyday one: a branch per task, per fix, per experiment. Module 3 covers this in depth.

5.3 Working offline

Because every repository is complete, you can commit, browse the history, create branches and merge without a connection. The network is only needed to share work with others, and that happens when you decide, not on every change.

5.4 Guaranteed integrity

Everything in Git is identified by a cryptographic hash computed from its content. If a byte of an old file becomes corrupted on disk, the hash no longer matches and Git notices. On top of that, every commit includes the identifier of the previous one, so altering one point in the history invalidates everything after it. Changing the past silently is impossible. Module 1 returns to this in detail in the lesson The Git Data Model.

5.5 The staging area

Git introduces an intermediate zone between "I have edited files" and "I have recorded a change in the history", called the staging area. It lets you build careful commits by choosing exactly which parts of your work go into each one. We will meet it in the lesson Basic Git Terminology.

5.6 The GitHub effect

A social factor was added to the technical quality: the birth of GitHub in 2008, which made sharing code social and visible and popularised the fork-and-pull-request flow. GitLab, Bitbucket and others followed. Today, knowing Git is an entry requirement for practically any technical job.

The reasons at a glance

Reason What it gives you in practice
Speed Browsing and navigating the history without friction
Cheap branches Isolating every task, experimenting without fear
Offline work Being productive with no connection, publishing later
Integrity Trusting that the history has not been tampered with
Staging area Clean, meaningful commits
Ecosystem Integration with platforms, CI and tooling

  1. What Git is not

Marking the boundaries avoids misunderstandings that are common in the first few days:

  • Git is not GitHub. Git is the program you install on your machine. GitHub, GitLab and Bitbucket are web services that host Git repositories and add features of their own (issues, reviews, permissions). You can use Git your whole life without opening an account anywhere.
  • Git is not an automatic backup. It saves only what you ask it to save, when you ask it.
  • Git is not a folder synchronisation system. It is nothing like Dropbox: nothing syncs by itself, and that is precisely the advantage.
  • Git is not designed for large binary files. Videos, heavy images or 3D models bloat the repository because they compress poorly between versions. Git LFS exists for that, and module 10 covers it.
  • Git is not a deployment manager, even though nearly every modern deployment system relies on it.

  1. Our guiding thread: task-manager, Ana, Bruno and Carla

Across the ten modules of this course we will follow a single project. Learning Git from disconnected examples produces equally disconnected knowledge; following a real project from start to finish shows why each command is used at each moment.

The project

task-manager is a small web application for managing to-do lists. It begins as a folder on Ana's laptop with four files:

File Contents
index.html Page structure: heading, form and task list
styles.css Visual appearance
app.js Logic: adding, checking off and deleting tasks
README.md Project description and instructions

This is the starting state, exactly as it sits on Ana's laptop today. There is no trace of Git yet: it is just a folder.

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Task Manager</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <h1>My tasks</h1>
  <form id="new-task">
    <input type="text" id="text" placeholder="What needs to be done?">
    <button type="submit">Add</button>
  </form>
  <ul id="list"></ul>
  <script src="app.js"></script>
</body>
</html>

Notice the deliberate simplicity: a heading, a form with a text field and a button, and an empty list that JavaScript will fill in. The whole example fits on one screen so that your attention stays on Git rather than on the application.

// app.js
const form = document.getElementById('new-task');
const list = document.getElementById('list');

form.addEventListener('submit', function (event) {
  event.preventDefault();
  const text = document.getElementById('text').value;
  if (text === '') return;
  const element = document.createElement('li');
  element.textContent = text;
  list.appendChild(element);
  form.reset();
});

Line by line: grab references to the form and the list; listen for the submit event; event.preventDefault() stops the page from reloading; if the field is empty, do nothing; otherwise create an <li>, set its text, append it to the list and clear the form. It is basic on purpose: over the course, Bruno and Carla will keep extending it, and those changes are the raw material for our examples.

The team

Person Role in the project What we learn with them
Ana Starts the project and maintains it Creating the repository, first commits, configuration
Bruno Joins second Cloning, working on branches, resolving conflicts
Carla Joins last Collaboration, code reviews, continuous integration

The journey

graph LR
    M1["Modules 1-2<br/>Ana alone<br/>local folder"] --> M2["Modules 3-4<br/>Bruno joins<br/>branches and remote"]
    M2 --> M3["Modules 5-7<br/>Carla joins<br/>rebase, reviews, workflows"]
    M3 --> M4["Modules 8-10<br/>Established team<br/>best practices, CI, scale"]

The story moves forward alongside the syllabus: what is a folder with four files in module 2 will be a shared repository with release branches, code reviews and continuous integration by module 10.

Common Mistakes and Tips

  • Confusing Git with GitHub. This is misunderstanding number one. Repeat it to yourself: Git is the local program; GitHub is a website that hosts Git repositories. Everything we do up to module 4 works with no internet connection and no account on any service.
  • Assuming Git stores differences between versions. Conceptually, Git stores complete snapshots of the project at each commit (with very efficient compression underneath that reuses unchanged content). That nuance, covered in lesson 01-04, is why switching branches is so fast.
  • Keeping _GOOD folders around "just in case" once you already use Git. It signals distrust in the tool, and it usually fades as soon as the data model clicks. It does no harm meanwhile; the goal, though, is to stop needing it.
  • Wanting to memorise commands before understanding the model. Git has dozens of commands and many options. Whoever memorises recipes gets stuck the moment something goes off script; whoever understands the model works out the command. Spend time on lessons 01-03 and 01-04.
  • Tip: install Git even if you are not going to use it yet. The next lesson covers it, so you will be ready to experiment as soon as we reach module 2.
  • Tip: pick a project of your own as a testbed. Alongside following task-manager, applying each lesson to something of yours cements the learning far faster.

Exercises

Exercise 1: Diagnosing the hand-made method

Picture this very real situation. Ana e-mails Bruno a file called task-manager_v2.zip. Bruno modifies styles.css and sends back task-manager_v2_bruno.zip. Meanwhile, Ana has carried on working and has modified styles.css and app.js in her copy.

List at least four concrete problems that arise now, and for each one state which feature of a version control system would solve it.

Exercise 2: Centralised or distributed

For each of these five situations, say whether it is possible in a centralised system (SVN), in a distributed one (Git), in both, or in neither. Justify each answer briefly:

  1. Finding out who last modified line 12 of app.js with no internet connection.
  2. Recovering the project's full history after the server burns down, with no backups but three people holding their working copy.
  3. Committing a change without the rest of the team seeing it yet.
  4. Restricting a user's access to a single subfolder of the project.
  5. Creating ten throwaway branches in under a second.

Exercise 3: Making the case to the team

Carla still works with zip archives and sees no need to change: "I'm well organised and I've never lost anything." Write a five-point case, one per benefit of Git covered in this lesson, phrased so that it answers that specific objection (listing features is not enough: you have to connect them to her situation).


Solutions

Solution to Exercise 1

The problems that arise and what solves them:

Problem Feature that solves it
There are two different versions of styles.css and nobody knows which is the right one Assisted merging: the system combines changes in different areas of a file automatically and flags only the genuine overlaps
Nobody knows exactly what Bruno changed Version comparison (diff): shows the differences line by line
Nobody knows why he changed it Commit messages: every change carries an explanation written by its author
Ana's work on app.js can be lost if Bruno's .zip is unpacked over it Immutable history: nothing is overwritten; every committed state can be recovered
There is no official version of the project A shared repository with an agreed main branch
Every file has been duplicated twice to change a handful of lines Efficient storage: only new content is stored

Four of these points, well argued, are enough to solve the exercise.

Solution to Exercise 2

  1. Distributed only. In Git the history is on the local disk, so you can query it with no network. In SVN that query requires talking to the server.
  2. Distributed only. SVN working copies contain no history: you would recover the latest state of the files, but the past would be gone. Any Git clone contains the entire history and is enough to rebuild the server.
  3. Distributed only. In SVN, committing publishes to the server immediately. In Git, committing is local and publishing (push) is a separate second step.
  4. Centralised only (natively). SVN supports per-path access control lists. Git has no per-folder permissions inside a repository; you solve it by splitting into several repositories or by using the hosting platform's tooling.
  5. Distributed only, in practice. SVN can create branches, but each one means a server-side operation. In Git each branch is a tiny file and creating ten is instant.

Solution to Exercise 3

A case aimed at the "I'm well organised" objection:

  1. This isn't about you, it's about the team. Your personal tidiness does nothing for Ana or Bruno when all three of you touch app.js the same afternoon. Git merges non-overlapping changes automatically and asks for human intervention only on the real conflict.
  2. The history answers questions you can't. "Why is this line here?" has an immediate answer six months later: who wrote it, when, and with what message. No zip archive holds that information.
  3. You can experiment without fear. With cheap branches, trying a complete redesign of styles.css costs a second, and throwing it away costs another. Without version control, experimenting means risking what already works.
  4. It's your safety net, not a burden. You have never lost anything yet. An accidental deletion, a failing disk or a botched change at eleven at night are only a matter of time; every clone of the repository is a complete copy of the project.
  5. It's the common language of the profession. Code reviews, automated deployment and continuous integration all rest on Git. Staying out is not a personal preference: it locks you out of everyone else's workflow.

Conclusion

Git exists because the hand-made _v2_GOOD folder method does not scale: it explains neither what changed, nor why, nor who did it, and it makes parallel work impossible. It was born in 2005 out of a concrete need in the Linux kernel and was designed from day one to be fast, distributed, cheap in branches and correct by construction. Being distributed — every copy holds the full history — is the decision that sets it apart from centralised systems like SVN, and the one that explains its speed, its offline work and its resilience to failure.

We have also met Ana, Bruno and Carla, and the task-manager project they will build over the course: today it is a folder with four files on a laptop; by the end it will be a shared repository with release branches, code reviews and continuous integration.

The next step is getting Git running on your machine. The lesson Installing Git covers how to install it on Linux, macOS and Windows, how to check the installation is correct, and why this course works on the command line rather than with a graphical client.

Mastering Git: From Beginner to Advanced

Module 1: Introduction to Git

Module 2: Basic Git Operations

Module 3: Branching and Merging

Module 4: Working with Remote Repositories

Module 5: Advanced Git Operations

Module 6: Git Tools and Techniques

Module 7: Collaboration and Workflow Strategies

Module 8: Git Best Practices and Tips

Module 9: Troubleshooting and Debugging

Module 10: Git in the Real World

© Copyright 2026. All rights reserved