# Git - Version Control Fundamentals

<!-- hint:slides topic="Git fundamentals: three areas (working directory, staging, repository), branches, merging strategies, and conflict resolution" slides="5" -->

## What is Git?

Git is a distributed version control system that tracks changes in source code during software development. It allows multiple developers to work on the same codebase simultaneously without overwriting each other's work.

## Core Concepts

### Repository
A Git repository (repo) is a directory that Git tracks. It contains all your project files plus a hidden `.git` directory that stores the complete history of changes.

```bash
git init           # Create a new repository
git clone <url>    # Clone an existing repository
```

### The Three Areas

Git has three main areas where your files live:

1. **Working Directory** — your actual files on disk
2. **Staging Area (Index)** — files marked to be included in the next commit
3. **Repository (HEAD)** — the committed history

```
Working Directory → git add → Staging Area → git commit → Repository
```

```mermaid
flowchart LR
    WD[Working Directory] -->|git add| SA[Staging Area]
    SA -->|git commit| Repo[Repository]
```

### Commits

A commit is a snapshot of your staged changes. Each commit has:
- A unique SHA-1 hash (e.g., `a1b2c3d`)
- Author and timestamp
- A commit message describing the change
- A pointer to its parent commit(s)

```bash
git add file.txt           # Stage a file
git commit -m "message"    # Commit staged changes
git log                    # View commit history
```

### Branches

A branch is a lightweight movable pointer to a commit. The default branch is usually `main` or `master`.

```bash
git branch feature         # Create a new branch
git checkout feature       # Switch to it
git checkout -b feature    # Create + switch in one step
git branch -d feature      # Delete a branch
```

### Merging

Merging combines work from different branches.

```bash
git checkout main
git merge feature          # Merge feature into main
```

**Fast-forward merge:** When the target branch hasn't diverged, Git just moves the pointer forward.

**Three-way merge:** When both branches have new commits, Git creates a merge commit.

### Merge Conflicts

When Git can't automatically merge changes (both branches modified the same lines), you get a conflict:

```
<<<<<<< HEAD
your changes
=======
their changes
>>>>>>> feature
```

Resolve by editing the file, removing the markers, then:
```bash
git add file.txt
git commit
```

## Common Workflows

### Undoing Changes

```bash
git checkout -- file.txt   # Discard working directory changes
git reset HEAD file.txt    # Unstage a file
git revert <commit>        # Create a new commit that undoes a previous one
git reset --hard <commit>  # Dangerous: discard all changes after a commit
```

### Remote Repositories

```bash
git remote add origin <url>   # Add a remote
git push origin main          # Push to remote
git pull origin main          # Fetch + merge from remote
git fetch origin              # Fetch without merging
```

### Stashing

Temporarily save uncommitted changes:
```bash
git stash                  # Stash changes
git stash pop              # Restore stashed changes
git stash list             # List all stashes
```

## Best Practices

1. **Commit often** — small, focused commits are easier to understand and revert
2. **Write good commit messages** — explain WHY, not just WHAT
3. **Use branches** — keep main/master clean, develop features on branches
4. **Pull before push** — avoid merge conflicts by staying up to date
5. **Don't commit secrets** — use `.gitignore` for sensitive files
