Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d48f1b0
feat: add site-wide design system (dark mode, callouts, nav chrome)
ghanendra-sdet Oct 5, 2026
2bb795e
seo: add per-page title/description front matter
ghanendra-sdet Oct 5, 2026
f9e6fd0
docs: turn README into a proper landing page
ghanendra-sdet Oct 5, 2026
6cc0d74
docs(module-00): add hands-on practice loop
ghanendra-sdet Oct 5, 2026
f4192c2
docs(module-01): add hands-on practice loop to the core module
ghanendra-sdet Oct 5, 2026
88298f1
docs(module-02): add hands-on practice loop
ghanendra-sdet Oct 5, 2026
f2f12fb
docs(module-03): add hands-on practice loop
ghanendra-sdet Oct 5, 2026
72fcb2d
docs(module-04): add Try Its and rebuild into 7 Disaster Labs
ghanendra-sdet Oct 5, 2026
a32df79
docs(module-05): add git bisect, Try Its, SDET-flavored CI example
ghanendra-sdet Oct 5, 2026
c9c4d7b
docs(module-06): add bisect and detached HEAD to the review pass
ghanendra-sdet Oct 5, 2026
c89f3ea
docs(module-07): rebuild capstone into the full Git Mastery Challenge
ghanendra-sdet Oct 5, 2026
6a2989c
chore: make the repo practice what Module 03 teaches
ghanendra-sdet Oct 5, 2026
e38d21b
chore: gitignore local Jekyll build output
ghanendra-sdet Oct 5, 2026
df075a4
fix: add _config.yml and restore the head-custom.html include
ghanendra-sdet Oct 5, 2026
e18bafa
fix: restore jekyll-relative-links plugin
ghanendra-sdet Oct 5, 2026
8db4191
feat: rebuild design system to match the dark cheatsheet look
ghanendra-sdet Oct 5, 2026
2f296db
fix: breadcrumb/progress-tracker/external-link baseurl detection
ghanendra-sdet Oct 5, 2026
cec7d9c
fix: add light mode to interactive cheatsheet, fix dead link
ghanendra-sdet Oct 5, 2026
4d62409
fix: illegible mermaid diagram text in dark mode
ghanendra-sdet Oct 5, 2026
4569813
testing update 1
ghanendra-sdet Oct 5, 2026
877322e
testing update
ghanendra-sdet Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-or-broken-content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: Bug / Broken Content
about: Report a broken link, a wrong command, or an outdated explanation
title: "[Module 0X] Short description"
labels: bug
---

**Where**
Which module/file, and roughly which section (a heading or a direct link is perfect)?

**What's wrong**
What does the course currently say, and why is it wrong or broken?

**What it should say instead**
If you know the fix, say it here — if not, that's fine too.
15 changes: 15 additions & 0 deletions .github/ISSUE_TEMPLATE/content-suggestion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: Content Suggestion
about: Suggest a missing concept, a clearer explanation, or a new Try It / lab
title: "[Suggestion] Short description"
labels: enhancement
---

**What's missing or could be clearer**
A concept, command, or scenario you think belongs in the course.

**Where it would fit**
Which existing module, if any? If it's genuinely new ground, say that instead.

**Why it's worth adding**
What would a learner be able to do afterward that they can't today?
14 changes: 14 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## What

<!-- What changed, in one or two sentences. -->

## Why

<!-- What was wrong, missing, or unclear before this change. -->

## Checklist

- [ ] Ran `python3 .github/scripts/check_docs.py` locally — no issues
- [ ] Kept existing examples/analogies/labs intact (or has a good reason not to)
- [ ] Used dummy data only — no real names, emails, credentials, or URLs
- [ ] New commands/concepts include a `callout-tryit` block the reader can actually run
67 changes: 67 additions & 0 deletions .github/scripts/check_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""Validate this repo's own Markdown: balanced code fences, resolvable
relative links, and balanced custom HTML components (<div>/<details>).
Used locally and by .github/workflows/validate-docs.yml in CI.
"""
import os
import re
import sys
import glob

REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def check_file(path):
problems = []
with open(path, encoding="utf-8") as fh:
content = fh.read()

fence_count = len(re.findall(r"^```", content, re.MULTILINE))
if fence_count % 2 != 0:
problems.append(f"Unbalanced code fences ({fence_count} found)")

div_open = len(re.findall(r"<div\b", content))
div_close = content.count("</div>")
if div_open != div_close:
problems.append(f"Unbalanced <div> tags ({div_open} open, {div_close} close)")

details_open = content.count("<details>")
details_close = content.count("</details>")
if details_open != details_close:
problems.append(f"Unbalanced <details> tags ({details_open} open, {details_close} close)")

for match in re.finditer(r"\]\(([^)]+)\)", content):
link = match.group(1)
if link.startswith(("http://", "https://", "mailto:", "#")):
continue
path_part = link.split("#")[0]
if not path_part:
continue
resolved = os.path.normpath(os.path.join(os.path.dirname(path), path_part))
if not os.path.exists(resolved):
problems.append(f"Broken relative link: {link}")

return problems


def main():
md_files = glob.glob(os.path.join(REPO_ROOT, "**", "*.md"), recursive=True)
all_problems = {}
for f in md_files:
problems = check_file(f)
if problems:
all_problems[os.path.relpath(f, REPO_ROOT)] = problems

if not all_problems:
print(f"OK — {len(md_files)} Markdown files checked, no issues found.")
return 0

for f, problems in sorted(all_problems.items()):
for p in problems:
print(f"{f}: {p}")
print(f"\n{sum(len(p) for p in all_problems.values())} issue(s) in {len(all_problems)} file(s).")
return 1


if __name__ == "__main__":
sys.exit(main())
14 changes: 14 additions & 0 deletions .github/workflows/validate-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Validate Docs

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
check-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: python3 .github/scripts/check_docs.py
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Jekyll build output (local preview only — GitHub Pages builds this itself)
_site/
.jekyll-cache/
.jekyll-metadata
.sass-cache/
189 changes: 178 additions & 11 deletions 00-introduction/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
title: "Module 00 — Introduction & Setup"
description: "What version control actually is, installing Git, and the one-time config that saves you from a confusing commit history."
---

<div align="center" markdown="1">

# 🏠 Module 00 — Introduction & Setup
Expand All @@ -9,10 +14,23 @@

</div>

<div class="callout callout-concept" markdown="1">

**By the end of this module you will be able to:**

✓ Explain what Git actually *is*, and why it beat older version control systems
✓ Install Git and set your identity correctly (global vs. local)
✓ Create a real Git repository from scratch with `git init`
✓ Read `git status`'s output and know what it's telling you to do next
✓ Pull up Git's built-in help without leaving the terminal

</div>

---

## 📑 In This Module

- [Set Up Your Safe Sandbox](#-set-up-your-safe-sandbox)
- [Git Home — What Even Is This](#-git-home--what-even-is-this)
- [Git Intro — Version Control, Explained Like You're Five (a smart five-year-old)](#-git-intro--version-control-explained-like-youre-five-a-smart-five-year-old)
- [Git Install](#-git-install)
Expand All @@ -23,6 +41,33 @@

---

## 🛟 Set Up Your Safe Sandbox

Every "Try It" and "Your Turn" block in this course — starting right now — assumes you have one
disposable folder to actually type commands into. Not a real project. Something you can break on
purpose, over and over, with zero consequences.

<div class="callout callout-tryit" markdown="1">

**⌨️ TRY IT YOURSELF**

```bash
mkdir ~/git-playground
cd ~/git-playground
```

That's it for now — you don't even have `git init` yet, because the very next section is about
to teach you what that command does and why. Just get the folder made and remember where it is;
every module from here forward will say "in your playground" and mean this exact folder.

</div>

> [!TIP]
> Keep this folder for the entire course. Delete everything inside it whenever you want a clean
> slate — nothing in here should ever be work you actually care about keeping.

---

## 🏠 Git Home — What Even Is This

**Git** is a program that tracks changes to files over time, so you can:
Expand Down Expand Up @@ -101,9 +146,9 @@ graph TB
E1 -.->|Works fine offline,<br/>syncs later| E1
end

style C1 fill:#ffcccc
style E1 fill:#d4edda
style E2 fill:#d4edda
style C1 fill:#ffcccc,color:#1a1a1a
style E1 fill:#d4edda,color:#1a1a1a
style E2 fill:#d4edda,color:#1a1a1a
```

In a **centralized** system, only the server has the full history — if it goes down, nobody can
Expand Down Expand Up @@ -151,6 +196,21 @@ git --version
> added to it. (The other 20% of the time, you'll be Googling PATH environment variables at
> midnight. We've all been there.)

<div class="callout callout-tryit" markdown="1">

**⌨️ TRY IT YOURSELF**

```bash
git --version
git help -a
```

**What should I see?** A version number on the first command, and a long alphabetical list of
every Git subcommand that exists on the second. You don't need to read all of it — just confirm
it printed something. That list existing at all is the whole point of the next section.

</div>

---

## ⚙️ Git Config
Expand Down Expand Up @@ -195,30 +255,83 @@ git config user.email "you@company.com"
> override it with a `--local` (no flag) config inside your work repos specifically — not the
> other way around, unless you enjoy explaining commit history to HR.

<div class="callout callout-tryit" markdown="1">

**⌨️ TRY IT YOURSELF**

```bash
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --list
```

**What should I see?** A list of key=value settings, including `user.name=Your Name` and
`user.email=you@example.com` somewhere in it. If you don't see them, the config didn't save —
check for a typo in the command before moving on.

</div>

<div class="callout callout-challenge" markdown="1">

**🎯 YOUR TURN**

Without looking at the example above: set your email to one thing **globally**, then go into
your `~/git-playground` folder and override it to something different, **locally, just for that
one folder**. Then run `git config user.email` *inside* the playground folder, and run it again
from somewhere *outside* it. Can you explain out loud why the two commands print different
answers?

<details>
<summary>💡 Show solution</summary>

```bash
git config --global user.email "global@example.com"

cd ~/git-playground
git config user.email "local-override@example.com"

git config user.email # prints "local-override@example.com" — local wins here
cd ..
git config user.email # prints "global@example.com" — no local override outside the playground
```

Local config lives in that specific repo's `.git/config` file and always wins over global when
both exist — that's the entire mechanism behind "why do my personal commits show my work email"
bugs: someone set a local override once, forgot about it, and every commit since has used it.

</details>

</div>

---

## 🚀 Git Get Started

Time to actually create a repository.
Time to actually create a repository — in the `~/git-playground` folder you made earlier.

<div class="callout callout-tryit" markdown="1">

### Step by step
**⌨️ TRY IT YOURSELF**

```bash
# 1. Make a new folder and go into it
mkdir my-first-repo
cd my-first-repo
cd ~/git-playground

# 2. Turn it into a Git repository
# Turn this folder into a Git repository
git init
# Initialized empty Git repository in .../my-first-repo/.git/
# Initialized empty Git repository in .../git-playground/.git/

# 3. Check what Git thinks is going on (you'll run this CONSTANTLY)
# Check what Git thinks is going on (you'll run this CONSTANTLY)
git status
# On branch main
# No commits yet
# nothing to commit (create/copy files and use "git add" to track)
```

**What should I see?** `git init`'s one-line confirmation, then `git status` reporting a brand
new, empty repo on branch `main` with nothing to commit yet.

</div>

That `.git` folder `git init` just created is where **all** of Git's magic lives — the entire
history, every branch, every commit. Delete that folder, and as far as Git is concerned, the
project's history never existed (the files themselves are untouched — only the tracking is gone).
Expand All @@ -229,6 +342,48 @@ project's history never existed (the files themselves are untouched — only the
> staging, after committing. It always tells you exactly what state you're in and, usually, the
> exact next command to run.

<div class="callout callout-challenge" markdown="1">

**🎯 YOUR TURN**

Before running anything — predict out loud what `git status` will print if you create a brand
new empty file right now and run it, **without** running `git add` first. Then actually do it
and check your prediction.

<details>
<summary>💡 Show solution</summary>

```bash
touch notes.txt
git status
```

```
Untracked files:
(use "git add <file>..." to include in what will be committed)
notes.txt
```

If you predicted "it'll show up as untracked, not staged" — that's exactly right, and it's the
single most important mental model from this entire module: Git notices new files immediately,
but never tracks them until you explicitly say so with `git add`.

</details>

</div>

<div class="callout callout-sdet" markdown="1">

**🧪 SDET SCENARIO**

Every automation repo you'll ever work in — a Playwright suite, a Selenium framework, a Postman
collection exported to Newman — starts with exactly this: `git init` (or `git clone`, if someone
already created it), then an immediate `.gitignore` for `node_modules/`, test reports, and
screenshots nobody wants committed. You'll see the real version of this in
[Module 05](../05-advanced-git/#-gitignore).

</div>

---

## 🆘 Git Help
Expand Down Expand Up @@ -278,6 +433,18 @@ If any of those feel shaky, that's completely normal for a first pass — skim b
click. If you're solid on all three, you're ready for the module where things actually get typed
into files.

<div class="callout callout-remember" markdown="1">

**🧠 You can now:**

✓ Install Git and verify it from the terminal
✓ Set your identity globally, and override it locally when you need to
✓ Turn any folder into a Git repository with `git init`
✓ Read `git status` and know the difference between "untracked" and "nothing to commit"
✓ Reach for `git help` instead of leaving the terminal to Google a flag

</div>

---

<div align="center" markdown="1">
Expand Down
Loading
Loading