Greetings, brave adventurer! Welcome to the Git Basics quest โ where youโll learn the version control system that powers nearly every software project on the planet. Git lets you track changes, collaborate with others, and fearlessly experiment with code knowing you can always roll back. This is the single most important tool in any developerโs inventory.
Long before the age of cloud realms and container kingdoms, developers toiled in darkness โ overwriting each otherโs scrolls, losing ancient code to careless keystrokes, and deploying broken incantations with no way to revert. Then came Git, forged by Linus Torvalds in the fires of the Linux kernel. It granted developers the power of perfect memory: every change recorded, every experiment safely branched, every mistake reversible. Today, Git is the foundation spell in every developerโs grimoire โ and mastering it is your first step toward true digital sorcery.
graph TB
subgraph "Prerequisites"
Terminal["๐ฑ Terminal Fundamentals"]
end
subgraph "Current Quest"
Main["๐ฐ Git Basics: Version Control"]
end
subgraph "Unlocked Adventures"
GitAdv["๐ฐ Advanced Git Workflows"]
GitHub["๐ฐ GitHub Collaboration"]
CICD["โ๏ธ CI/CD Pipelines"]
end
Terminal --> Main
Main --> GitAdv
Main --> GitHub
GitHub --> CICD
style Main fill:#ffd700,stroke:#333,stroke-width:2px
style Terminal fill:#87ceeb
style GitAdv fill:#98fb98
style GitHub fill:#98fb98
style CICD fill:#98fb98
.git directory.gitignore โ Exclude files from version controlgit restore, git reset, and git revertcd, ls, mkdir)git --version to verify)# Git comes with Xcode CLI tools, or install via Homebrew
brew install git
# Verify installation
git --version
# Install with winget
winget install Git.Git
# Or download from https://git-scm.com/download/win
# Verify installation
git --version
# Ubuntu/Debian
sudo apt update && sudo apt install git
# Fedora
sudo dnf install git
# Verify installation
git --version
Every great codebase starts with git init. In this chapter, youโll create your first repository and learn the fundamental rhythm of Git: edit โ stage โ commit.
Before your first commit, tell Git who you are:
# Set your identity (used in every commit)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# Set default branch name to 'main' (recommended)
git config --global init.defaultBranch main
# Verify your settings
git config --list
# Create a new project directory
mkdir my-first-repo
cd my-first-repo
# Initialize Git tracking
git init
Expected Output:
Initialized empty Git repository in /path/to/my-first-repo/.git/
# 1. Create a file
echo "# My First Project" > README.md
# 2. Check status โ see untracked files
git status
# 3. Stage the file (add to staging area)
git add README.md
# 4. Commit with a descriptive message
git commit -m "docs: add initial README"
flowchart LR
WD["๐ Working Directory\n(your files)"] -->|git add| SA["๐ Staging Area\n(index)"]
SA -->|git commit| REPO["๐๏ธ Repository\n(.git history)"]
REPO -->|git restore| WD
SA -->|git restore --staged| WD
style WD fill:#ffcccc,stroke:#cc0000
style SA fill:#fff3cd,stroke:#cc9900
style REPO fill:#d4edda,stroke:#28a745
Working Directory โ Staging Area โ Repository
(your files) (git add) (git commit)
Edit files here Preview what Permanent snapshot
will be committed in project history
Validation โ confirm each before proceeding:
git config user.name returns your namegit status inside my-first-repo/ shows a clean working tree after your first commitgit log --oneline shows at least one commit with a proper message๐ง Knowledge Check:
.git/ contains and why deleting it removes all history?git add . and git add README.md?git status show a file as โuntrackedโ before staging?git init to create a repositorygit add it, and git commit itgit status before and after staging to see the differencegit log to see your first commitBranches let you work on features in isolation without affecting the main codebase. Think of them as parallel timelines you can merge together when ready.
gitGraph
commit id: "init"
commit id: "add README"
branch feature/greeting
checkout feature/greeting
commit id: "add greeting"
commit id: "update greeting"
checkout main
merge feature/greeting id: "merge feature"
commit id: "continue work"
# Create a new branch
git branch feature/greeting
# Switch to it
git switch feature/greeting
# Or create and switch in one command
git switch -c feature/greeting
# Add a new file on the feature branch
echo "Hello, World!" > greeting.txt
git add greeting.txt
git commit -m "feat: add greeting message"
# See all branches (* marks current)
git branch
# Switch back to main
git switch main
# Merge the feature branch into main
git merge feature/greeting
# Delete the branch (optional, it's merged)
git branch -d feature/greeting
When two branches modify the same lines, Git asks you to resolve the conflict:
# Git marks conflicts in the file like this:
<<<<<<< HEAD
Current content on main
=======
Different content from feature branch
>>>>>>> feature/greeting
To resolve:
<<<<<<<, =======, >>>>>>>)git add conflicted-file.txt
git commit -m "fix: resolve merge conflict in greeting"
Validation โ confirm each before proceeding:
git branch shows at least two branches (including main)git log --oneline --graph --all shows a merge commit๐ง Knowledge Check:
git switch between branches?git branch -d safer than git branch -D?git switch -c feature/testmain and merge itLocal Git is powerful, but the real magic happens when you connect to a remote like GitHub. This enables collaboration, backup, and sharing.
sequenceDiagram
participant WD as ๐ป Working Directory
participant LOCAL as ๐๏ธ Local Repo
participant REMOTE as โ๏ธ GitHub (Remote)
WD->>LOCAL: git commit
LOCAL->>REMOTE: git push
REMOTE->>LOCAL: git fetch
LOCAL->>WD: git merge / git pull
REMOTE-->>WD: git pull (fetch + merge)
Note over WD,REMOTE: git clone creates LOCAL + WD from REMOTE
# Add a remote repository
git remote add origin https://github.com/yourusername/my-first-repo.git
# Verify the remote
git remote -v
# Push your local commits to GitHub
git push -u origin main
# Clone a repository from GitHub
git clone https://github.com/username/repository.git
# This creates a local copy with full history
cd repository
git log --oneline
# Pull latest changes from remote
git pull origin main
# Push your changes to remote
git push origin main
.gitignore FileTell Git to ignore files that shouldnโt be tracked:
# Create a .gitignore file
cat > .gitignore << 'EOF'
# OS files
.DS_Store
Thumbs.db
# Dependencies
node_modules/
__pycache__/
# Environment files
.env
*.log
EOF
git add .gitignore
git commit -m "chore: add gitignore for common files"
# View commit log
git log
# Compact one-line format
git log --oneline
# Visual branch graph
git log --oneline --graph --all
# Show changes in a specific commit
git show abc1234
Validation โ confirm each before proceeding:
git remote -v shows your GitHub URL for both fetch and pushhttps://github.com/yourusername/my-first-repogit log --oneline matches between local and GitHub๐ง Knowledge Check:
-u flag in git push -u origin main do?git fetch and git pull?.env files always be in .gitignore?.gitignore and verify ignored files donโt appear in git statusgit log --oneline --graph to visualize historyEvery adventurer makes mistakes. The mark of a true Git sorcerer is knowing how to undo them safely without destroying the timeline.
flowchart TD
A{"What do you want to undo?"} -->|"Unstage a file\n(keep changes)"| B["git restore --staged file"]
A -->|"Discard local changes\n(lose edits)"| C["git restore file"]
A -->|"Undo last commit\n(keep changes)"| D["git reset --soft HEAD~1"]
A -->|"Undo last commit\n(discard changes)"| E["git reset --hard HEAD~1"]
A -->|"Create a new commit\nthat reverses a previous one"| F["git revert <commit-hash>"]
style B fill:#d4edda,stroke:#28a745
style C fill:#ffcccc,stroke:#cc0000
style D fill:#fff3cd,stroke:#cc9900
style E fill:#ffcccc,stroke:#cc0000
style F fill:#d4edda,stroke:#28a745
# Unstage a file (keep your edits)
git restore --staged README.md
# Discard changes in working directory (โ ๏ธ destructive)
git restore README.md
# Undo the last commit but keep changes staged
git reset --soft HEAD~1
# Undo the last commit AND discard all changes (โ ๏ธ destructive)
git reset --hard HEAD~1
# Safely reverse a published commit (creates a new commit)
git revert abc1234
| Command | Destructive? | Safe for shared branches? |
|---|---|---|
git restore --staged |
No | Yes |
git restore |
Yes โ loses edits | Yes |
git reset --soft |
No | โ ๏ธ Only before pushing |
git reset --hard |
Yes | โ ๏ธ Only before pushing |
git revert |
No | Yes โ preferred method |
git restore --stagedgit reset --soft HEAD~1git revert to reverse a commit safelyObjective: Build a personal project repository with a clean, professional commit history.
Acceptance Criteria:
git initREADME.md with project title, description, and usage section.gitignore with at least 5 ignore rulesfeat:, docs:, chore:, etc.)Verification Command:
# Should show exactly 5 commits
git log --oneline | wc -l
# All commits should follow conventional format
git log --oneline | grep -E '^[a-f0-9]+ (feat|fix|docs|chore|refactor|test):'
Objective: Simulate a feature-branch workflow with parallel development and a merge conflict.
Acceptance Criteria:
main branch with at least 2 filesfeature/header and feature/footer branches from mainindex.html (to force a conflict)feature/header into main (should fast-forward or clean merge)feature/footer into main โ resolve the conflictgit log --oneline --graph --all shows the merge topologyExpected Branch Topology:
gitGraph
commit id: "initial commit"
commit id: "add index.html"
branch feature/header
checkout feature/header
commit id: "add header"
checkout main
branch feature/footer
checkout feature/footer
commit id: "add footer"
checkout main
merge feature/header id: "merge header"
merge feature/footer id: "merge footer (conflict resolved)"
Verification Command:
# Should show merge commits
git log --oneline --graph --all
# Verify no conflict markers remain
grep -rn '<<<<<<' . && echo 'FAIL: unresolved conflicts' || echo 'PASS: no conflicts'
Objective: Practice the full local-to-remote workflow including forking and pull requests.
Acceptance Criteria:
feature/my-improvement branchmainVerification Command:
# Verify remote points to YOUR fork
git remote -v | grep 'your-username'
# Verify feature branch exists on remote
git branch -r | grep 'feature/my-improvement'
Youโve trained with individual spells. Now face the ultimate trial โ a multi-phase challenge that tests every skill from this quest in a single, connected scenario.
Youโre building a โQuest Logโ web page โ a simple HTML file that tracks your IT-Journey progress. You must use every Git skill from this quest to build it correctly.
# Create and initialize the project
mkdir quest-log && cd quest-log
git init
# Create the initial file
cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>Quest Log</title></head>
<body>
<h1>My Quest Log</h1>
<ul>
<li>Terminal Fundamentals โ โ
Complete</li>
</ul>
</body>
</html>
EOF
# Create .gitignore
echo -e ".DS_Store\n*.log\n.env" > .gitignore
git add .
git commit -m "feat: initialize quest log project"
# Branch 1: Add styling
git switch -c feature/styling
cat > style.css << 'EOF'
body { font-family: sans-serif; max-width: 600px; margin: 2rem auto; }
h1 { color: #2d3748; }
li { padding: 0.5rem 0; }
EOF
# Link the stylesheet in index.html (add <link> in <head>)
git add .
git commit -m "feat: add basic CSS styling"
git switch main
# Branch 2: Add more quests (this will conflict with branch 1 in index.html)
git switch -c feature/more-quests
# Add Git Basics quest to the list in index.html
git add .
git commit -m "feat: add git basics quest to log"
git switch main
# Merge styling first
git merge feature/styling
# Merge more-quests (expect conflict in index.html)
git merge feature/more-quests
# >> RESOLVE THE CONFLICT <<
git add index.html
git commit -m "fix: resolve merge conflict in quest list"
# Make a deliberate mistake
echo "BROKEN CONTENT" >> index.html
git add . && git commit -m "feat: this is a mistake"
# Revert it safely
git revert HEAD --no-edit
# Verify the bad content is gone
cat index.html
# Create the repo on GitHub, then:
git remote add origin https://github.com/yourusername/quest-log.git
git push -u origin main
git log --oneline --graph shows branching and merging.gitignore is present and workingFull Verification Script:
#!/bin/bash
echo "=== ๐ฐ Git Gauntlet Verification ==="
# Check commit count
COMMITS=$(git log --oneline | wc -l | tr -d ' ')
[[ $COMMITS -ge 6 ]] && echo "โ
Commits: $COMMITS (โฅ6)" || echo "โ Commits: $COMMITS (need โฅ6)"
# Check for merge commits
MERGES=$(git log --merges --oneline | wc -l | tr -d ' ')
[[ $MERGES -ge 1 ]] && echo "โ
Merge commits found: $MERGES" || echo "โ No merge commits"
# Check for revert commits
REVERTS=$(git log --oneline | grep -c 'Revert\|revert')
[[ $REVERTS -ge 1 ]] && echo "โ
Revert commits found: $REVERTS" || echo "โ No revert commits"
# Check for conflict markers
grep -rn '<<<<<<' . --include='*.html' --include='*.css' 2>/dev/null
[[ $? -ne 0 ]] && echo "โ
No unresolved conflicts" || echo "โ Unresolved conflicts found!"
# Check .gitignore
[[ -f .gitignore ]] && echo "โ
.gitignore exists" || echo "โ Missing .gitignore"
# Check remote
git remote -v | grep -q 'origin' && echo "โ
Remote configured" || echo "โ No remote configured"
echo "=== Verification Complete ==="
flowchart TD
START["๐ฐ Quest Start"] --> CH1["๐งโโ๏ธ Ch1: First Repository"]
CH1 --> CP1{"โ
Checkpoint 1\nRepo + Commits?"}
CP1 -->|Pass| CH2["๐งโโ๏ธ Ch2: Branching"]
CP1 -->|Fail| CH1
CH2 --> CP2{"โ
Checkpoint 2\nBranch + Merge?"}
CP2 -->|Pass| CH3["๐งโโ๏ธ Ch3: Remotes"]
CP2 -->|Fail| CH2
CH3 --> CP3{"โ
Checkpoint 3\nPush + Pull?"}
CP3 -->|Pass| CH4["๐งโโ๏ธ Ch4: Undo Mistakes"]
CP3 -->|Fail| CH3
CH4 --> CHALLENGES["๐ฎ Implementation Challenges"]
CHALLENGES --> BOSS{"โ๏ธ Boss Battle:\nThe Git Gauntlet"}
BOSS -->|Victory| REWARDS["๐ Quest Rewards"]
BOSS -->|Defeat| CHALLENGES
REWARDS --> NEXT["๐ฎ Next Adventures"]
style START fill:#6c5ce7,color:#fff
style BOSS fill:#e17055,color:#fff,stroke-width:3px
style REWARDS fill:#00b894,color:#fff
style NEXT fill:#0984e3,color:#fff
.gitignore โ Properly configured ignore rulesgit revert demonstrating safe undoBefore claiming your reward, you should be able to answer:
git revert vs. git reset.git push is rejected because the remote has new commits.