# Version Control: Why We Need It, and the Basic Concepts of Git<no value>

## What will we learn?

- What **Version Control** is, and why every developer uses it.
- What **Git** is.
- The three areas: **Working Directory**, **Staging Area**, **Repository**.
- What a **Commit** is.
- The initial setup of Git.

## Why do we need this?

Do you know this folder?

```text
project_final.py
project_final_v2.py
project_final_v2_WORKS.py
project_final_v3_dont_touch.py
project_final_v3_fixed_REALLY_FINAL.py
```

The problems:

- **Which version works?** What exactly changed between v2 and v3?
- **"I broke something, and yesterday it worked!"** How do you go back to yesterday's state?
- **Teamwork:** two people edited the same file. How do you combine the changes without overwriting?
- **Backup:** the laptop was stolen. Is the project lost?

**Version Control** solves all of these. In every software company in the world, every line of code is managed with it. Without Git, you cannot work in a development team, and in a job interview they expect you to know it.

## Explanation from the basics

### What is Version Control?

**Version Control** is a system that **records the history of the files**: every change, when it was made, by whom, and why. You can go back to any point in the past, compare versions and combine the work of several people.

### What is Git?

**Git** is the most common version control system in the world, by a huge margin. It is:

- **Local** — the whole history is kept **on your computer**, in a hidden folder `.git`. It works even without internet.
- **Distributed** — every developer has a **full** copy of the whole history.
- **Fast and free**, and originally written by Linus Torvalds, the creator of Linux.

**Git ≠ GitHub!** Git is **the tool** that runs on your computer. **GitHub** is **a website** that hosts a copy of your Repository in the cloud, and adds tools for sharing and teamwork. We will meet it in the third lesson.

### Repository

**Repository** (**Repo** for short) = a project that Git tracks: the folder with the files, **plus** the hidden folder `.git` where the whole history is kept.

### Commit — a snapshot

**Commit** = a saved **snapshot** of the project at a certain moment, with:

- A **message** that explains what changed and why.
- An **author** (name and email) and a **time**.
- A **unique identifier** (Hash), for example `a3f9c21`.
- A reference to the **previous** Commit, and that is how a **chain** of history is formed.

```text
(a3f9c21) ◄── (7b2e004) ◄── (e91d5aa)   ← HEAD (latest)
"Initial      "Add price     "Fix VAT
 project"      calculator"    rounding"
```

{{< box "analogy" "Analogy: save points in a game" >}}
**Commit** = a save point in a computer game. Before the boss fight you save. If you lose, you go back to the point. The difference: in Git **every** save point stays forever, with a description, and you can go back to any of them or compare them.
{{< /box >}}

### The three areas

This is the most important concept in the lesson. Every file in the project is in one of three "areas":

```text
 Working Directory        Staging Area            Repository (.git)
 (the files you edit)     (ready for the next     (committed history)
                           commit)
       │                        │                        │
       │──── git add ──────────►│                        │
       │                        │──── git commit ───────►│
       │◄──────────────────── (checkout / restore) ──────│
```

| Area | What it is | How you get there |
|---|---|---|
| **Working Directory** | The folder you work in: the files as they are now on the disk | You simply edit files |
| **Staging Area** (also called the Index) | A "preparation area": the changes you chose to put into the **next** Commit | `git add` |
| **Repository** | The saved history: all the Commits | `git commit` |

**Why is Staging needed?** Because sometimes you changed 5 files, but only 3 of them belong to the same logical change ("fixing a bug in the calculator"). Staging lets you choose **exactly** what goes into each Commit, so that every Commit is one logical unit.

{{< box "analogy" "Analogy: taking a group photo" >}}
**Working Directory** = all the people at the event. **Staging Area** = the people you invited to stand in front of the camera ("come on, you, into the photo"). **Commit** = pressing the button: the photo is saved in the album (Repository) forever. Whoever did not stand in front of the camera is not in the photo, even if they are at the event.
{{< /box >}}

### File states

| State | Meaning |
|---|---|
| **Untracked** | A new file that Git does not track yet |
| **Modified** | A known file that changed since the last Commit, but is not in Staging yet |
| **Staged** | The change is in Staging, ready for a Commit |
| **Committed** (Unmodified) | Identical to the last Commit, "clean" |

## Syntax

**Installation:** Git was installed on the first day of the course. Check: `git --version`.

**One-time setup** (once per computer). Git records the name and the email in every Commit:

```powershell
git config --global user.name "Dana Cohen"
git config --global user.email "dana@example.com"
git config --global init.defaultBranch main
git config --global core.editor "code --wait"
```

| Command | Meaning |
|---|---|
| `user.name` / `user.email` | Who wrote the Commit. In lesson 3, the same email as in the GitHub account. |
| `init.defaultBranch main` | The main branch will be called `main` (the modern convention). |
| `core.editor "code --wait"` | If Git needs to open an editor, it will open VS Code. |
| `--global` | The setting applies to all the projects on the computer. |

**Check:**

```powershell
git config --global --list
```

## First code example

Let's see the idea of the "three areas" in commands. In the next lesson we will break each one down in depth.

```powershell
mkdir ~\dev\kodkod6\git-demo
cd ~\dev\kodkod6\git-demo
git init
```

**Output:**

```text
Initialized empty Git repository in C:/Users/dana/dev/kodkod6/git-demo/.git/
```

Now there is a Repository. The hidden folder `.git` was created. You can see it with `ls -Force` (PowerShell) or `ls -a` (Bash).

## Breaking down the code line by line

| Line | Explanation |
|---|---|
| `mkdir ...git-demo` | A regular folder for the project. |
| `cd ...git-demo` | Go into it. **All Git commands act on the Repository of the current folder.** |
| `git init` | **init**ialize: turns the folder into a Repository, and creates `.git` inside it. |
| `.git/` | The "brain" of the Repository: all the Commits, the history and the settings. **Do not touch it by hand.** If you delete it, the whole history is deleted (the files themselves remain). |

## Another example

**The journey of one change, through the three areas**, with `git status` after every step (the full details in the next lesson):

```powershell
New-Item hello.py
git status
git add hello.py
git status
git commit -m "Add hello.py"
git status
```

**Output (shortened):**

```text
Untracked files:
        hello.py

Changes to be committed:
        new file:   hello.py

[main (root-commit) 3c1f2a9] Add hello.py
 1 file changed, 0 insertions(+), 0 deletions(-)

nothing to commit, working tree clean
```

| Step | State of `hello.py` | Area |
|---|---|---|
| After `New-Item` | **Untracked** | Working Directory only |
| After `git add` | **Staged** | Staging Area |
| After `git commit` | **Committed**, and "working tree clean" | Repository |

## Common mistake

**Mistake 1: `git init` in the wrong folder**, for example in the home folder (`C:\Users\dana`) or inside a folder that is already inside another Repository. Then Git tracks **all** the files on the computer, or confusing nested Repositories are created.

**Always:** `cd` to the project folder, `pwd` to make sure, and only then `git init`. And if you made a mistake: delete the hidden `.git` folder that was created by mistake (only it!).

**Mistake 2: "I did `git add`, so it is saved."** No! `add` only prepares. Only **`commit`** saves into the history. And a change you made **after** the `add` is not included, until you `add` again.

**Mistake 3: thinking that Git backs up to the cloud.** Git is local. If the laptop is lost, the Repository is lost with it, unless you did a **push** to GitHub (lesson 3).

**Mistake 4: not setting `user.name` / `user.email`.**

```text
Author identity unknown
*** Please tell me who you are.
```

Git refuses to make a Commit without knowing who the author is. Run the `config` commands from above.

<!-- exercises:start — generated by scripts/intro6/sync_site_exercises.py; edit scripts/intro6/exercises/ -->
## Practice

The exercises use only what was taught in this lesson and the lessons before it. Try on your own first, and only then open the solution.

### Exercise 1: Why do we need version control?

Danny's folder has these files:

```text
project_final.py
project_final_v2.py
project_final_v2_WORKS.py
project_final_v3_dont_touch.py
```

Give three problems with this method, and how Git solves each one.

{{< solution >}}
| The problem | How Git solves it |
|---|---|
| It is not clear what the difference between the files is and what changed in each one | Every **Commit** saves exactly what changed, with a message that explains why |
| You cannot know which version is really the latest one that works | There is one orderly history, and **HEAD** points to the current state |
| When several people work, each one adds "another version" | Everyone works on the same **Repository**, and Git knows how to combine the changes |
{{< /solution >}}

### Exercise 2: The three areas

For each action — in which area is the change after it: the Working Directory, the Staging Area or the Repository?

1. You edited `calculator.py` and saved it.
2. You ran `git add calculator.py`.
3. You ran `git commit -m "Add subtract"`.

{{< solution >}}
1. **Working Directory** — the change exists only in the file on the disk.
2. **Staging Area** — the change was marked as part of the next Commit.
3. **Repository** — the change was saved as a snapshot in the history.
{{< /solution >}}

### Exercise 3: First setup

Write the commands that set the name `Dana Cohen` and the email `dana@example.com` for Git, and then create a new Repository in the current folder. Why does Git need a name and an email?

{{< solution >}}
```powershell
git config --global user.name "Dana Cohen"
git config --global user.email "dana@example.com"
git init
```

Git records in every Commit **who** made it. Without a name and an email, Git will not agree to make a Commit. `--global` saves the setting once for all the Repositories on the computer.
{{< /solution >}}

### Exercise 4: A chain of Commits

```text
(a3f9c21) <── (7b2e004) <── (e91d5aa)  <- HEAD
"Initial      "Add price     "Fix VAT
 project"      calculator"    rounding"
```

1. What is each of the identifiers `a3f9c21`, `7b2e004`, `e91d5aa`?
2. What does HEAD point to?
3. Why does every Commit "point" to the one before it?

{{< solution >}}
1. These are **identifiers of Commits** — every Commit gets a unique identifier (shortened here).
2. **HEAD** points to the current Commit — `e91d5aa`, "Fix VAT rounding". This is the state the files are in now.
3. That is how a **history** is formed: from every Commit you can go back and see what came before it, and return to any point in the past.
{{< /solution >}}

### Exercise 5: Why do we need a Staging Area?

Today you changed three things in the project: you fixed a bug in the calculator, improved the README, and added a temporary test file that you do not want to keep. How does the Staging Area help here?

{{< solution >}}
The Staging Area lets you **choose** what goes into each Commit:

1. `git add calculator.py` → Commit: "Fix rounding bug in calculator".
2. `git add README.md` → Commit: "Improve README".
3. The temporary test file is not added at all.

That way every Commit is **one logical change** with a clear message — and not a mix of everything you touched that day.
{{< /solution >}}

<!-- exercises:end -->

## Summary

- **Version Control** records every change, and lets you go back, compare and work in a team. **Git** is the tool. **GitHub** is the website that hosts it in the cloud.
- **Repository** = a project + the hidden folder `.git` with the whole history.
- **Commit** = a snapshot with a message, an author, a time and an identifier (Hash).
- Three areas: **Working Directory** → (`git add`) → **Staging Area** → (`git commit`) → **Repository**.
- One-time setup: `git config --global user.name` / `user.email`.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

## Official documentation

- [Pro Git — About Version Control](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control)
- [Pro Git — What is Git?](https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F)
- [Pro Git — First-Time Git Setup](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)

<!-- docs:end -->
