Guided Git Lessons and Challenges

Learn Git from repository initialization through commits, branches, merging, conflict resolution, rebasing, and reflog recovery. Each lesson in Git Visualizer provides a practical target state and an interactive repository to explore.

Start with Git fundamentals, then practice branching, merging, undo commands, and advanced history recovery.

All Git Lessons

1. Initialize a Repository

Beginner: Transform an ordinary directory into a Git repository

Objective: Create a fresh Git repository using git init and inspect the initial status.

Git tracks changes by creating a hidden `.git` folder in your project root. This contains all commits, branches, and configuration metadata.

Steps

  1. Initialize a new repository by running `git init`.

    Hint: Type "git init" into the terminal.

  2. Check repository status with `git status`.

    Hint: Type "git status" to view the working tree status.

Summary: Great job! You initialized a Git repository. HEAD is now pointing to the default branch "main".

2. Working Directory & Staging Area

Beginner: Stage files to prepare for a commit

Objective: Move untracked and modified files from the Working Directory into the Staging Area (Index).

Git has a two-phase workflow: first you prepare files in the Staging Area using `git add`, and then you freeze that snapshot into history with `git commit`.

Steps

  1. Stage only `index.html` using `git add index.html`.

    Hint: Run "git add index.html" to stage just that single file.

  2. Stage all remaining files with `git add .`.

    Hint: Run "git add ." to stage everything in the working directory.

Summary: Both files are now staged in the Index! They are ready to be permanently recorded into a commit.

3. Make Your First Commit

Beginner: Permanently record a project snapshot

Objective: Create a permanent commit object with a meaningful message.

A commit captures the exact state of all staged files in the index, assigns a cryptographic hash, stores your author identity, and points to the previous commit.

Steps

  1. Commit your staged changes with `git commit -m "Initial commit"`.

    Hint: Run: git commit -m "Initial commit"

Summary: You made your first commit! The branch "main" and HEAD now point to your new commit node.

4. Read Commit History

Beginner: Explore previous commits using git log

Objective: Inspect previous commits and branch pointers in the terminal log.

`git log` displays commits in reverse chronological order, showing hashes, authors, timestamps, and commit messages.

Steps

  1. Inspect the commit log in one-line summary mode: `git log --oneline`.

    Hint: Run "git log --oneline" to see compact commit summaries.

Summary: You explored the commit log! Each commit has a unique abbreviated hash (e.g. c3f4a5b).

5. Create & Switch Branches

Intermediate: Work safely in parallel isolated lines of development

Objective: Create a feature branch, switch HEAD to it, and make a commit.

Branches in Git are merely lightweight pointers to commits. Switching branches updates HEAD and adjusts files in your working directory.

Steps

  1. Create and switch to a new branch called `feature-login`: `git switch -c feature-login`.

    Hint: Run: git switch -c feature-login

  2. Stage existing changes and commit: run `git add .` then `git commit -m "feat: login form"`.

    Hint: Run "git add ." then "git commit -m 'feat: login form'"

Summary: Awesome! Your commit advanced `feature-login` while `main` remained securely untouched.

6. Fast-Forward vs 3-Way Merge

Intermediate: Integrate feature branch changes into main

Objective: Switch back to main and merge the feature branch.

If `main` has no new commits since branching, Git does a Fast-Forward merge by simply sliding the branch pointer forward. If both branches diverged, Git generates a 3-way merge commit.

Steps

  1. Switch back to `main`: `git switch main`.

    Hint: Run: git switch main

  2. Merge `feature-nav` into main: `git merge feature-nav`.

    Hint: Run: git merge feature-nav

Summary: You executed a Fast-Forward merge! The main branch pointer caught up to feature-nav seamlessly.

7. Resolve a Merge Conflict

Intermediate: Fix conflicting simultaneous edits with confidence

Objective: Trigger a merge conflict, understand the markers, resolve it, and finalize the merge commit.

Merge conflicts happen when two branches modify the exact same lines of a file. Git halts and embeds `<<<<<<< HEAD`, `=======`, and `>>>>>>>` markers for you to resolve.

Steps

  1. Attempt to merge `feature-hero` into main: `git merge feature-hero`.

    Hint: Run: git merge feature-hero

  2. Mark the conflict as resolved by adding the file: `git add README.md`.

    Hint: Run "git add README.md" (or resolve via the Conflict button in the Inspector, then stage).

  3. Finalize the merge: `git commit -m "Merge resolved"`.

    Hint: Run: git commit -m "Merge resolved"

Summary: You resolved a real merge conflict and produced a multi-parent merge commit!

8. Undo Safely (Restore & Revert)

Intermediate: Discard working changes and invert commits safely

Objective: Use git restore to discard dirty edits, and git revert to safely undo a public commit without rewriting history.

`git restore` resets files in your working directory. `git revert` is the safest undo tool for shared branches because it creates an inverse commit instead of erasing history.

Steps

  1. Discard modified changes to `scratch.txt` using `git restore scratch.txt`.

    Hint: Run: git restore scratch.txt

  2. Revert the latest commit safely: `git revert HEAD`.

    Hint: Run: git revert HEAD

Summary: You safely undid changes! The history remains transparent, reproducible, and intact.

9. Stash Uncommitted Work

Advanced: Shelve changes temporarily when you need to switch contexts

Objective: Save a dirty working directory to the stash, and restore it later.

`git stash` takes your uncommitted modifications (both staged and unstaged) and pushes them onto a temporary stack, leaving your workspace completely clean.

Steps

  1. Stash your work away: `git stash`.

    Hint: Run: git stash

  2. Check your stash list: `git stash list`.

    Hint: Run: git stash list

  3. Restore and pop your saved work: `git stash pop`.

    Hint: Run: git stash pop

Summary: Stash mastered! You can safely shelve work and switch tasks without losing progress.

10. Synchronize with Remotes (Fetch & Push)

Advanced: Coordinate code with GitHub or remote team repositories

Objective: Fetch remote changes, inspect tracking branches, and push local commits.

`git fetch` downloads remote objects without touching your local working files. `git push` publishes your local branch commits to the remote.

Steps

  1. Fetch remote metadata from origin: `git fetch`.

    Hint: Run: git fetch

  2. Push your latest local commits to origin: `git push`.

    Hint: Run: git push

Summary: Your local repository and GitHub origin remote are now completely in sync!

11. Merge vs Rebase

Advanced: Keep history clean and linear with rebase

Objective: Rebase a feature branch on top of main, observing how commit hashes are rewritten.

While merge preserves the exact branching structure with a merge commit, rebase replays your commits one by one on top of the target branch tip, creating clean linear history with new commit IDs.

Steps

  1. Rebase current branch onto main: `git rebase main`.

    Hint: Run: git rebase main

Summary: Rebase successful! The widget commit was replayed directly on top of main with a clean linear parent relationship.

12. Recover Commits with Reflog

Advanced: Git's ultimate safety net for recovering lost work

Objective: View the reflog history and understand how every HEAD movement is recorded.

Even if you accidentally reset or delete a branch, Git records every commit hash that HEAD has pointed to in the reflog. Nothing is lost!

Steps

  1. Inspect the reflog to view all HEAD transitions: `git reflog`.

    Hint: Run: git reflog

Summary: Reflog examined! You now know how to locate commit hashes for any previously visited state.

Git Challenges

Challenge 1: Feature Branching Workflow

Intermediate: Starting from main, create branch "feat-profile", add a file "profile.js", commit it, switch to main, and fast-forward merge "feat-profile".

Target goal: Branch "main" must contain the commit from "feat-profile" with file "profile.js".

Hints

  1. 1. git switch -c feat-profile
  2. 2. (Create/add profile.js or run: git add .)
  3. 3. git commit -m "add profile"
  4. 4. git switch main
  5. 5. git merge feat-profile

Challenge 2: Safe Reset & Recovery

Advanced: You made an experimental commit that you want to uncommit while keeping all changes staged in the index ready to be re-committed.

Target goal: HEAD must point to c3f4a5b, but the index must still contain staged files.

Hints

  1. Think about which reset mode keeps staged changes in the index without touching them.
  2. Try: git reset --soft HEAD~1

Explore Git Visualizer

Git Visualizer is created by .