refactor: rename 01_essentials to 01-essentials
This commit is contained in:
638
01-essentials/05-revert/README.md
Normal file
638
01-essentials/05-revert/README.md
Normal file
@@ -0,0 +1,638 @@
|
||||
# Module 05: Git Revert - Safe Undoing
|
||||
|
||||
## About This Module
|
||||
|
||||
Welcome to Module 05, where you'll learn the **safe, team-friendly way to undo changes** in Git. Unlike destructive commands that erase history, `git revert` creates new commits that undo previous changes while preserving the complete project history.
|
||||
|
||||
**Why revert is important:**
|
||||
- ✅ Safe for shared/pushed commits
|
||||
- ✅ Preserves complete history and audit trail
|
||||
- ✅ Transparent to your team
|
||||
- ✅ Can be undone itself if needed
|
||||
- ✅ Works with any commit in history
|
||||
|
||||
**Key principle:** Revert doesn't erase mistakes—it documents how you fixed them.
|
||||
|
||||
## Learning Objectives
|
||||
|
||||
By completing this module, you will:
|
||||
|
||||
1. Revert regular commits safely while preserving surrounding changes
|
||||
2. Revert merge commits using the `-m` flag
|
||||
3. Understand merge commit parent numbering
|
||||
4. Handle the re-merge problem that occurs after reverting merges
|
||||
5. Revert multiple commits at once
|
||||
6. Know when to use revert vs. other undo strategies
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting this module, you should be comfortable with:
|
||||
- Creating commits (`git commit`)
|
||||
- Viewing commit history (`git log`)
|
||||
- Understanding branches and merging (Module 03)
|
||||
|
||||
## Setup
|
||||
|
||||
Run the setup script to create the challenge environment:
|
||||
|
||||
```powershell
|
||||
./setup.ps1
|
||||
```
|
||||
|
||||
This creates a `challenge/` directory with three branches demonstrating different revert scenarios:
|
||||
- `regular-revert` - Basic commit reversion
|
||||
- `merge-revert` - Merge commit reversion
|
||||
- `multi-revert` - Multiple commit reversion
|
||||
|
||||
## Challenge 1: Reverting a Regular Commit
|
||||
|
||||
### Scenario
|
||||
|
||||
You're working on a calculator application. A developer added a `divide` function that crashes when dividing by zero. The bug was discovered after subsequent commits were made, so you can't just delete it—you need to revert it while keeping the commits that came after.
|
||||
|
||||
### Your Task
|
||||
|
||||
1. Navigate to the challenge directory:
|
||||
```bash
|
||||
cd challenge
|
||||
```
|
||||
|
||||
2. You should be on the `regular-revert` branch. View the commit history:
|
||||
```bash
|
||||
git log --oneline
|
||||
```
|
||||
|
||||
3. Find the commit with the broken divide function (message: "Add broken divide function - needs to be reverted!")
|
||||
|
||||
4. Revert that specific commit:
|
||||
```bash
|
||||
git revert <commit-hash>
|
||||
```
|
||||
|
||||
5. Git will open your editor for the revert commit message. The default message is fine—save and close.
|
||||
|
||||
### What to Observe
|
||||
|
||||
After reverting, check:
|
||||
|
||||
```bash
|
||||
# View the new revert commit
|
||||
git log --oneline
|
||||
|
||||
# Check that divide function is gone
|
||||
cat calculator.py | grep "def divide" # Should return nothing
|
||||
|
||||
# Check that modulo function still exists (it came after the bad commit)
|
||||
cat calculator.py | grep "def modulo" # Should find it
|
||||
|
||||
# Check that multiply function still exists (it came before the bad commit)
|
||||
cat calculator.py | grep "def multiply" # Should find it
|
||||
```
|
||||
|
||||
**Key insight:** Revert creates a new commit that undoes the changes from the target commit, but leaves all other commits intact.
|
||||
|
||||
### Understanding the Timeline
|
||||
|
||||
```
|
||||
Before revert:
|
||||
main.py (initial) → multiply (good) → divide (BAD) → modulo (good)
|
||||
↑
|
||||
We want to undo THIS
|
||||
|
||||
After revert:
|
||||
main.py (initial) → multiply (good) → divide (BAD) → modulo (good) → revert divide (new commit)
|
||||
↑
|
||||
Removes divide, keeps modulo
|
||||
```
|
||||
|
||||
The revert commit adds a new point in history that undoes the divide changes.
|
||||
|
||||
## Challenge 2: Reverting a Merge Commit
|
||||
|
||||
### Scenario
|
||||
|
||||
Your team merged a `feature-auth` branch that added authentication functionality. After deployment, you discovered the authentication system has critical security issues. You need to revert the entire merge while the security team redesigns the feature.
|
||||
|
||||
**This is different from reverting a regular commit!** Merge commits have **two parents**, so you must tell Git which parent to keep.
|
||||
|
||||
### Understanding Merge Commit Parents
|
||||
|
||||
When you merge a feature branch into main:
|
||||
|
||||
```
|
||||
feature-auth (parent 2)
|
||||
↓
|
||||
C---D
|
||||
/ \
|
||||
A---B-----M ← Merge commit (has TWO parents)
|
||||
↑
|
||||
parent 1 (main)
|
||||
```
|
||||
|
||||
The merge commit `M` has:
|
||||
- **Parent 1**: The branch you merged INTO (main)
|
||||
- **Parent 2**: The branch you merged FROM (feature-auth)
|
||||
|
||||
When reverting a merge, you must specify which parent to keep using the `-m` flag:
|
||||
- `-m 1` means "keep parent 1" (main) - **Most common**
|
||||
- `-m 2` means "keep parent 2" (feature-auth) - Rare
|
||||
|
||||
**In practice:** You almost always use `-m 1` to keep the main branch and undo the feature branch changes.
|
||||
|
||||
### Your Task
|
||||
|
||||
1. Switch to the merge-revert branch:
|
||||
```bash
|
||||
git switch merge-revert
|
||||
```
|
||||
|
||||
2. View the commit history and find the merge commit:
|
||||
```bash
|
||||
git log --oneline --graph
|
||||
```
|
||||
|
||||
Look for: "Merge feature-auth branch"
|
||||
|
||||
3. Revert the merge commit using `-m 1`:
|
||||
```bash
|
||||
git revert -m 1 <merge-commit-hash>
|
||||
```
|
||||
|
||||
**Explanation:**
|
||||
- `-m 1` tells Git to keep parent 1 (main branch)
|
||||
- This undoes all changes from the feature-auth branch
|
||||
- Creates a new "revert merge" commit
|
||||
|
||||
4. Save the default commit message and check the result:
|
||||
```bash
|
||||
# Verify auth.py is gone
|
||||
ls auth.py # Should not exist
|
||||
|
||||
# Verify calculator.py no longer imports auth
|
||||
cat calculator.py | grep "from auth" # Should return nothing
|
||||
```
|
||||
|
||||
### What Happens Without -m?
|
||||
|
||||
If you try to revert a merge commit without the `-m` flag:
|
||||
|
||||
```bash
|
||||
git revert <merge-commit-hash>
|
||||
# Error: commit <hash> is a merge but no -m option was given
|
||||
```
|
||||
|
||||
Git doesn't know which parent you want to keep, so it refuses to proceed.
|
||||
|
||||
### The Re-Merge Problem
|
||||
|
||||
**Important gotcha:** After reverting a merge, you **cannot simply re-merge** the same branch!
|
||||
|
||||
Here's why:
|
||||
|
||||
```
|
||||
Initial merge:
|
||||
A---B---M (merged feature-auth)
|
||||
↑
|
||||
All changes from feature-auth are now in main
|
||||
|
||||
After revert:
|
||||
A---B---M---R (reverted merge)
|
||||
↑
|
||||
Changes removed, but Git remembers they were merged
|
||||
|
||||
Attempting to re-merge:
|
||||
A---B---M---R---M2 (try to merge feature-auth again)
|
||||
↑
|
||||
Git thinks: "I already merged these commits,
|
||||
nothing new to add!" (Empty merge)
|
||||
```
|
||||
|
||||
**Solutions if you need to re-merge:**
|
||||
|
||||
1. **Revert the revert** (recommended):
|
||||
```bash
|
||||
git revert <revert-commit-hash>
|
||||
```
|
||||
This brings back all the feature-auth changes.
|
||||
|
||||
2. **Cherry-pick new commits** from the feature branch:
|
||||
```bash
|
||||
git cherry-pick <new-commits>
|
||||
```
|
||||
|
||||
3. **Merge with --no-ff** and resolve conflicts manually (advanced).
|
||||
|
||||
### When to Revert Merges
|
||||
|
||||
Revert merge commits when:
|
||||
- ✅ Feature causes production issues
|
||||
- ✅ Need to temporarily remove a feature
|
||||
- ✅ Discovered critical bugs after merging
|
||||
- ✅ Security issues require immediate rollback
|
||||
|
||||
Don't revert merges when:
|
||||
- ❌ You just need to fix a small bug (fix it with a new commit instead)
|
||||
- ❌ You plan to re-merge the same branch soon (use reset if local, or revert-the-revert later)
|
||||
|
||||
## Challenge 3: Reverting Multiple Commits
|
||||
|
||||
### Scenario
|
||||
|
||||
Two separate commits added broken mathematical functions (`square_root` and `logarithm`). Both have critical bugs and need to be removed. You can revert multiple commits at once.
|
||||
|
||||
### Your Task
|
||||
|
||||
1. Switch to the multi-revert branch:
|
||||
```bash
|
||||
git switch multi-revert
|
||||
```
|
||||
|
||||
2. View the commit history:
|
||||
```bash
|
||||
git log --oneline
|
||||
```
|
||||
|
||||
Find the two commits:
|
||||
- "Add broken square_root - REVERT THIS!"
|
||||
- "Add broken logarithm - REVERT THIS TOO!"
|
||||
|
||||
3. Revert both commits in one command:
|
||||
```bash
|
||||
git revert <commit-hash-1> <commit-hash-2>
|
||||
```
|
||||
|
||||
**Important:** List commits from **oldest to newest** for cleanest history.
|
||||
|
||||
Alternatively, revert them one at a time:
|
||||
```bash
|
||||
git revert <commit-hash-1>
|
||||
git revert <commit-hash-2>
|
||||
```
|
||||
|
||||
4. Git will prompt for a commit message for each revert. Accept the defaults.
|
||||
|
||||
5. Verify the result:
|
||||
```bash
|
||||
# Check that both bad functions are gone
|
||||
cat calculator.py | grep "def square_root" # Should return nothing
|
||||
cat calculator.py | grep "def logarithm" # Should return nothing
|
||||
|
||||
# Check that good functions remain
|
||||
cat calculator.py | grep "def power" # Should find it
|
||||
cat calculator.py | grep "def absolute" # Should find it
|
||||
```
|
||||
|
||||
### Multi-Revert Strategies
|
||||
|
||||
**Reverting a range of commits:**
|
||||
|
||||
```bash
|
||||
# Revert commits from A to B (inclusive)
|
||||
git revert A^..B
|
||||
|
||||
# Example: Revert last 3 commits
|
||||
git revert HEAD~3..HEAD
|
||||
```
|
||||
|
||||
**Reverting without auto-commit:**
|
||||
|
||||
```bash
|
||||
# Stage revert changes without committing
|
||||
git revert --no-commit <commit-hash>
|
||||
|
||||
# Review changes
|
||||
git diff --staged
|
||||
|
||||
# Commit when ready
|
||||
git commit
|
||||
```
|
||||
|
||||
This is useful when reverting multiple commits and you want one combined revert commit.
|
||||
|
||||
## Verification
|
||||
|
||||
Verify your solutions by running the verification script:
|
||||
|
||||
```bash
|
||||
cd .. # Return to module directory
|
||||
./verify.ps1
|
||||
```
|
||||
|
||||
The script checks that:
|
||||
- ✅ Revert commits were created (not destructive deletion)
|
||||
- ✅ Bad code is removed
|
||||
- ✅ Good code before and after is preserved
|
||||
- ✅ Merge commits still exist in history
|
||||
- ✅ Proper use of `-m` flag for merge reverts
|
||||
|
||||
## Command Reference
|
||||
|
||||
### Basic Revert
|
||||
|
||||
```bash
|
||||
# Revert a specific commit
|
||||
git revert <commit-hash>
|
||||
|
||||
# Revert the most recent commit
|
||||
git revert HEAD
|
||||
|
||||
# Revert the second-to-last commit
|
||||
git revert HEAD~1
|
||||
```
|
||||
|
||||
### Merge Commit Revert
|
||||
|
||||
```bash
|
||||
# Revert a merge commit (keep parent 1)
|
||||
git revert -m 1 <merge-commit-hash>
|
||||
|
||||
# Revert a merge commit (keep parent 2) - rare
|
||||
git revert -m 2 <merge-commit-hash>
|
||||
```
|
||||
|
||||
### Multiple Commits
|
||||
|
||||
```bash
|
||||
# Revert multiple specific commits
|
||||
git revert <hash1> <hash2> <hash3>
|
||||
|
||||
# Revert a range of commits (oldest^..newest)
|
||||
git revert <oldest-hash>^..<newest-hash>
|
||||
|
||||
# Revert last 3 commits
|
||||
git revert HEAD~3..HEAD
|
||||
```
|
||||
|
||||
### Revert Options
|
||||
|
||||
```bash
|
||||
# Revert but don't commit automatically
|
||||
git revert --no-commit <commit-hash>
|
||||
|
||||
# Revert and edit the commit message
|
||||
git revert --edit <commit-hash>
|
||||
|
||||
# Revert without opening editor (use default message)
|
||||
git revert --no-edit <commit-hash>
|
||||
|
||||
# Abort a revert in progress (if conflicts)
|
||||
git revert --abort
|
||||
|
||||
# Continue revert after resolving conflicts
|
||||
git revert --continue
|
||||
```
|
||||
|
||||
## When to Use Git Revert
|
||||
|
||||
Use `git revert` when:
|
||||
|
||||
- ✅ **Commits are already pushed** - Safe for shared history
|
||||
- ✅ **Working in a team** - Transparent to everyone
|
||||
- ✅ **Need audit trail** - Shows what was undone and why
|
||||
- ✅ **Public repositories** - Can't rewrite public history
|
||||
- ✅ **Undoing old commits** - Can revert commits from weeks ago
|
||||
- ✅ **Production hotfixes** - Safe emergency rollback
|
||||
|
||||
**Golden Rule:** If others might have your commits, use revert.
|
||||
|
||||
## When NOT to Use Git Revert
|
||||
|
||||
Consider alternatives when:
|
||||
|
||||
- ❌ **Commits are still local** - Use `git reset` instead (Module 06)
|
||||
- ❌ **Just want to edit a commit** - Use `git commit --amend`
|
||||
- ❌ **Haven't pushed yet** - Reset is cleaner for local cleanup
|
||||
- ❌ **Need to combine commits** - Use interactive rebase
|
||||
- ❌ **Reverting creates complex conflicts** - Might need manual fix forward
|
||||
|
||||
## Revert vs. Reset vs. Rebase
|
||||
|
||||
| Command | History | Safety | Use Case |
|
||||
|---------|---------|--------|----------|
|
||||
| **revert** | Preserves | ✅ Safe | Undo pushed commits |
|
||||
| **reset** | Erases | ⚠️ Dangerous | Clean up local commits |
|
||||
| **rebase** | Rewrites | ⚠️ Dangerous | Polish commit history |
|
||||
|
||||
**This module teaches revert.** You'll learn reset in Module 06.
|
||||
|
||||
## Handling Revert Conflicts
|
||||
|
||||
Sometimes reverting causes conflicts if subsequent changes touched the same code:
|
||||
|
||||
```bash
|
||||
# Start revert
|
||||
git revert <commit-hash>
|
||||
|
||||
# If conflicts occur:
|
||||
# Conflict in calculator.py
|
||||
# CONFLICT (content): Merge conflict in calculator.py
|
||||
```
|
||||
|
||||
**To resolve:**
|
||||
|
||||
1. Open conflicted files and fix conflicts (look for `<<<<<<<` markers)
|
||||
2. Stage resolved files:
|
||||
```bash
|
||||
git add <resolved-files>
|
||||
```
|
||||
3. Continue the revert:
|
||||
```bash
|
||||
git revert --continue
|
||||
```
|
||||
|
||||
Or abort if you change your mind:
|
||||
```bash
|
||||
git revert --abort
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
### 1. Forgetting -m for Merge Commits
|
||||
|
||||
```bash
|
||||
# ❌ Wrong - will fail
|
||||
git revert <merge-commit>
|
||||
|
||||
# ✅ Correct
|
||||
git revert -m 1 <merge-commit>
|
||||
```
|
||||
|
||||
### 2. Trying to Re-Merge After Revert
|
||||
|
||||
```bash
|
||||
# After reverting a merge:
|
||||
git revert -m 1 <merge-commit>
|
||||
|
||||
# ❌ This won't work as expected
|
||||
git merge feature-branch # Empty merge!
|
||||
|
||||
# ✅ Do this instead
|
||||
git revert <the-revert-commit> # Revert the revert
|
||||
```
|
||||
|
||||
### 3. Using Reset on Pushed Commits
|
||||
|
||||
```bash
|
||||
# ❌ NEVER do this with pushed commits
|
||||
git reset --hard HEAD~3
|
||||
|
||||
# ✅ Do this instead
|
||||
git revert HEAD~3..HEAD
|
||||
```
|
||||
|
||||
### 4. Reverting Commits in Wrong Order
|
||||
|
||||
When reverting multiple related commits, revert from newest to oldest:
|
||||
|
||||
```bash
|
||||
# If you have: A → B → C (and C depends on B)
|
||||
|
||||
# ✅ Correct order
|
||||
git revert C
|
||||
git revert B
|
||||
|
||||
# ❌ Wrong order (may cause conflicts)
|
||||
git revert B # Conflict! C still references B
|
||||
git revert C
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Write clear revert messages:**
|
||||
```bash
|
||||
git revert <hash> -m "Revert authentication - security issue #1234"
|
||||
```
|
||||
|
||||
2. **Link to issue tracking:**
|
||||
```
|
||||
Revert "Add new payment system"
|
||||
|
||||
This reverts commit abc123.
|
||||
|
||||
Critical bug in payment processing.
|
||||
See bug tracker: ISSUE-1234
|
||||
```
|
||||
|
||||
3. **Test after reverting:**
|
||||
- Run your test suite
|
||||
- Verify the application still works
|
||||
- Check no unintended changes occurred
|
||||
|
||||
4. **Communicate with team:**
|
||||
- Announce reverts in team chat
|
||||
- Explain why the revert was necessary
|
||||
- Provide timeline for re-introducing the feature
|
||||
|
||||
5. **Keep reverts focused:**
|
||||
- Revert the minimum necessary
|
||||
- Don't bundle multiple unrelated reverts
|
||||
- One problem = one revert commit
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Commit is a merge but no -m option was given"
|
||||
|
||||
**Problem:** Trying to revert a merge commit without `-m`.
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
git revert -m 1 <merge-commit-hash>
|
||||
```
|
||||
|
||||
### "Empty Revert / No Changes"
|
||||
|
||||
**Problem:** Revert doesn't seem to do anything.
|
||||
|
||||
**Possible causes:**
|
||||
- Commit was already reverted
|
||||
- Subsequent commits already undid the changes
|
||||
- Wrong commit hash
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Check what the commit actually changed
|
||||
git show <commit-hash>
|
||||
|
||||
# Check if already reverted
|
||||
git log --grep="Revert"
|
||||
```
|
||||
|
||||
### "Conflicts During Revert"
|
||||
|
||||
**Problem:** Revert causes merge conflicts.
|
||||
|
||||
**Why:** Subsequent commits modified the same code.
|
||||
|
||||
**Solution:**
|
||||
1. Manually resolve conflicts in affected files
|
||||
2. `git add <resolved-files>`
|
||||
3. `git revert --continue`
|
||||
|
||||
Or consider fixing forward with a new commit instead of reverting.
|
||||
|
||||
### "Can't Re-Merge After Reverting Merge"
|
||||
|
||||
**Problem:** After reverting a merge, re-merging the branch brings no changes.
|
||||
|
||||
**Solution:** Revert the revert commit:
|
||||
```bash
|
||||
# Find the revert commit
|
||||
git log --oneline
|
||||
|
||||
# Revert the revert (brings changes back)
|
||||
git revert <revert-commit-hash>
|
||||
```
|
||||
|
||||
## Advanced: Revert Internals
|
||||
|
||||
Understanding what revert does under the hood:
|
||||
|
||||
```bash
|
||||
# Revert creates a new commit with inverse changes
|
||||
git revert <commit-hash>
|
||||
|
||||
# This is equivalent to:
|
||||
git diff <commit-hash>^..<commit-hash> > changes.patch
|
||||
patch -R < changes.patch # Apply in reverse
|
||||
git add .
|
||||
git commit -m "Revert '<original message>'"
|
||||
```
|
||||
|
||||
**Key insight:** Revert computes the diff of the target commit, inverts it, and applies it as a new commit.
|
||||
|
||||
## Going Further
|
||||
|
||||
Now that you understand revert, you're ready for:
|
||||
|
||||
- **Module 06: Git Reset** - Learn the dangerous but powerful local history rewriting
|
||||
- **Module 07: Git Stash** - Temporarily set aside uncommitted changes
|
||||
- **Module 08: Multiplayer Git** - Collaborate with advanced workflows
|
||||
|
||||
## Summary
|
||||
|
||||
You've learned:
|
||||
|
||||
- ✅ `git revert` creates new commits that undo previous changes
|
||||
- ✅ Revert is safe for shared/pushed commits
|
||||
- ✅ Merge commits require `-m 1` or `-m 2` flag
|
||||
- ✅ Parent 1 = branch merged into, Parent 2 = branch merged from
|
||||
- ✅ Can't simply re-merge after reverting a merge
|
||||
- ✅ Multiple commits can be reverted in one command
|
||||
- ✅ Revert preserves complete history for audit trails
|
||||
|
||||
**The Golden Rule of Revert:** Use revert for any commit that might be shared with others.
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Complete all three challenge scenarios
|
||||
2. Run `./verify.ps1` to check your solutions
|
||||
3. Experiment with reverting different commits
|
||||
4. Move on to Module 06: Git Reset (dangerous but powerful!)
|
||||
|
||||
---
|
||||
|
||||
**Need Help?**
|
||||
- Review the command reference above
|
||||
- Check the troubleshooting section
|
||||
- Re-run `./setup.ps1` to start fresh
|
||||
- Practice reverting in different orders to understand the behavior
|
||||
24
01-essentials/05-revert/reset.ps1
Normal file
24
01-essentials/05-revert/reset.ps1
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Resets the Module 05 challenge environment to start fresh.
|
||||
|
||||
.DESCRIPTION
|
||||
This script removes the challenge directory and re-runs setup.ps1
|
||||
to create a fresh challenge environment.
|
||||
#>
|
||||
|
||||
Write-Host "`n=== Resetting Module 05: Git Revert Challenge ===" -ForegroundColor Cyan
|
||||
|
||||
# Check if challenge directory exists
|
||||
if (Test-Path "challenge") {
|
||||
Write-Host "Removing existing challenge directory..." -ForegroundColor Yellow
|
||||
Remove-Item -Recurse -Force "challenge"
|
||||
Write-Host "[OK] Challenge directory removed" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[INFO] No existing challenge directory found" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Run setup to create fresh environment
|
||||
Write-Host "`nRunning setup to create fresh challenge environment..." -ForegroundColor Cyan
|
||||
& "$PSScriptRoot/setup.ps1"
|
||||
373
01-essentials/05-revert/setup.ps1
Normal file
373
01-essentials/05-revert/setup.ps1
Normal file
@@ -0,0 +1,373 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Sets up the Module 05 challenge environment for learning git revert.
|
||||
|
||||
.DESCRIPTION
|
||||
This script creates a challenge directory with three branches demonstrating
|
||||
different revert scenarios:
|
||||
- regular-revert: Basic revert of a single bad commit
|
||||
- merge-revert: Reverting a merge commit with -m flag
|
||||
- multi-revert: Reverting multiple commits at once
|
||||
#>
|
||||
|
||||
Write-Host "`n=== Setting up Module 05: Git Revert Challenge ===" -ForegroundColor Cyan
|
||||
|
||||
# Remove existing challenge directory if it exists
|
||||
if (Test-Path "challenge") {
|
||||
Write-Host "Removing existing challenge directory..." -ForegroundColor Yellow
|
||||
Remove-Item -Recurse -Force "challenge"
|
||||
}
|
||||
|
||||
# Create fresh challenge directory
|
||||
Write-Host "Creating challenge directory..." -ForegroundColor Green
|
||||
New-Item -ItemType Directory -Path "challenge" | Out-Null
|
||||
Set-Location "challenge"
|
||||
|
||||
# Initialize Git repository
|
||||
Write-Host "Initializing Git repository..." -ForegroundColor Green
|
||||
git init | Out-Null
|
||||
|
||||
# Configure git for this repository
|
||||
git config user.name "Workshop Student"
|
||||
git config user.email "student@example.com"
|
||||
|
||||
# ============================================================================
|
||||
# SCENARIO 1: Regular Revert (Basic)
|
||||
# ============================================================================
|
||||
Write-Host "`nScenario 1: Creating regular-revert branch..." -ForegroundColor Cyan
|
||||
|
||||
# Initial commit
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Initial calculator implementation" | Out-Null
|
||||
|
||||
# Create regular-revert branch
|
||||
git switch -c regular-revert | Out-Null
|
||||
|
||||
# Good commit: Add multiply
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def multiply(a, b):
|
||||
"""Multiply two numbers."""
|
||||
return a * b
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Add multiply function" | Out-Null
|
||||
|
||||
# BAD commit: Add broken divide function
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def multiply(a, b):
|
||||
"""Multiply two numbers."""
|
||||
return a * b
|
||||
|
||||
def divide(a, b):
|
||||
"""Divide a by b - BROKEN: doesn't handle division by zero!"""
|
||||
return a / b # This will crash if b is 0!
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Add broken divide function - needs to be reverted!" | Out-Null
|
||||
|
||||
# Good commit: Add modulo (after bad commit)
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def multiply(a, b):
|
||||
"""Multiply two numbers."""
|
||||
return a * b
|
||||
|
||||
def divide(a, b):
|
||||
"""Divide a by b - BROKEN: doesn't handle division by zero!"""
|
||||
return a / b # This will crash if b is 0!
|
||||
|
||||
def modulo(a, b):
|
||||
"""Return remainder of a divided by b."""
|
||||
return a % b
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Add modulo function" | Out-Null
|
||||
|
||||
Write-Host "[CREATED] regular-revert branch with bad divide commit" -ForegroundColor Green
|
||||
|
||||
# ============================================================================
|
||||
# SCENARIO 2: Merge Revert (Merge Commit with -m flag)
|
||||
# ============================================================================
|
||||
Write-Host "`nScenario 2: Creating merge-revert scenario..." -ForegroundColor Cyan
|
||||
|
||||
# Switch back to main
|
||||
git switch main | Out-Null
|
||||
|
||||
# Create merge-revert branch
|
||||
git switch -c merge-revert | Out-Null
|
||||
|
||||
# Create a feature branch to merge
|
||||
git switch -c feature-auth | Out-Null
|
||||
|
||||
# Add auth functionality
|
||||
$authContent = @"
|
||||
# auth.py - Authentication module
|
||||
|
||||
def login(username, password):
|
||||
\"\"\"Login user.\"\"\"
|
||||
print(f"Logging in {username}...")
|
||||
return True
|
||||
|
||||
def logout(username):
|
||||
\"\"\"Logout user.\"\"\"
|
||||
print(f"Logging out {username}...")
|
||||
return True
|
||||
"@
|
||||
Set-Content -Path "auth.py" -Value $authContent
|
||||
git add .
|
||||
git commit -m "Add authentication module" | Out-Null
|
||||
|
||||
# Add password validation
|
||||
$authContent = @"
|
||||
# auth.py - Authentication module
|
||||
|
||||
def validate_password(password):
|
||||
\"\"\"Validate password strength.\"\"\"
|
||||
return len(password) >= 8
|
||||
|
||||
def login(username, password):
|
||||
\"\"\"Login user.\"\"\"
|
||||
if not validate_password(password):
|
||||
print("Password too weak!")
|
||||
return False
|
||||
print(f"Logging in {username}...")
|
||||
return True
|
||||
|
||||
def logout(username):
|
||||
\"\"\"Logout user.\"\"\"
|
||||
print(f"Logging out {username}...")
|
||||
return True
|
||||
"@
|
||||
Set-Content -Path "auth.py" -Value $authContent
|
||||
git add .
|
||||
git commit -m "Add password validation" | Out-Null
|
||||
|
||||
# Integrate auth into calculator (part of the feature branch)
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
from auth import login
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def secure_divide(a, b, username):
|
||||
"""Secure divide - requires authentication."""
|
||||
if login(username, "password123"):
|
||||
return a / b
|
||||
return None
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Integrate auth into calculator" | Out-Null
|
||||
|
||||
# Switch back to merge-revert and merge feature-auth
|
||||
git switch merge-revert | Out-Null
|
||||
git merge feature-auth --no-ff -m "Merge feature-auth branch" | Out-Null
|
||||
|
||||
Write-Host "[CREATED] merge-revert branch with merge commit to revert" -ForegroundColor Green
|
||||
|
||||
# ============================================================================
|
||||
# SCENARIO 3: Multi Revert (Multiple Bad Commits)
|
||||
# ============================================================================
|
||||
Write-Host "`nScenario 3: Creating multi-revert branch..." -ForegroundColor Cyan
|
||||
|
||||
# Switch back to main
|
||||
git switch main | Out-Null
|
||||
|
||||
# Create multi-revert branch
|
||||
git switch -c multi-revert | Out-Null
|
||||
|
||||
# Reset calculator to simple version
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Reset to basic calculator" | Out-Null
|
||||
|
||||
# Good commit: Add power function
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def power(a, b):
|
||||
"""Raise a to the power of b."""
|
||||
return a ** b
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Add power function" | Out-Null
|
||||
|
||||
# BAD commit 1: Add broken square_root
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def power(a, b):
|
||||
"""Raise a to the power of b."""
|
||||
return a ** b
|
||||
|
||||
def square_root(a):
|
||||
"""BROKEN: Returns wrong result for negative numbers!"""
|
||||
return a ** 0.5 # This returns NaN for negative numbers!
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Add broken square_root - REVERT THIS!" | Out-Null
|
||||
|
||||
# BAD commit 2: Add broken logarithm
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def power(a, b):
|
||||
"""Raise a to the power of b."""
|
||||
return a ** b
|
||||
|
||||
def square_root(a):
|
||||
"""BROKEN: Returns wrong result for negative numbers!"""
|
||||
return a ** 0.5 # This returns NaN for negative numbers!
|
||||
|
||||
def logarithm(a):
|
||||
"""BROKEN: Doesn't handle zero or negative numbers!"""
|
||||
import math
|
||||
return math.log(a) # This crashes for a <= 0!
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Add broken logarithm - REVERT THIS TOO!" | Out-Null
|
||||
|
||||
# Good commit: Add absolute value (after bad commits)
|
||||
$calcContent = @"
|
||||
# calculator.py - Simple calculator
|
||||
|
||||
def add(a, b):
|
||||
"""Add two numbers."""
|
||||
return a + b
|
||||
|
||||
def subtract(a, b):
|
||||
"""Subtract b from a."""
|
||||
return a - b
|
||||
|
||||
def power(a, b):
|
||||
"""Raise a to the power of b."""
|
||||
return a ** b
|
||||
|
||||
def square_root(a):
|
||||
"""BROKEN: Returns wrong result for negative numbers!"""
|
||||
return a ** 0.5 # This returns NaN for negative numbers!
|
||||
|
||||
def logarithm(a):
|
||||
"""BROKEN: Doesn't handle zero or negative numbers!"""
|
||||
import math
|
||||
return math.log(a) # This crashes for a <= 0!
|
||||
|
||||
def absolute(a):
|
||||
"""Return absolute value of a."""
|
||||
return abs(a)
|
||||
"@
|
||||
Set-Content -Path "calculator.py" -Value $calcContent
|
||||
git add .
|
||||
git commit -m "Add absolute value function" | Out-Null
|
||||
|
||||
Write-Host "[CREATED] multi-revert branch with two bad commits to revert" -ForegroundColor Green
|
||||
|
||||
# ============================================================================
|
||||
# Return to regular-revert to start
|
||||
# ============================================================================
|
||||
git switch regular-revert | Out-Null
|
||||
|
||||
# Return to module directory
|
||||
Set-Location ..
|
||||
|
||||
Write-Host "`n=== Setup Complete! ===" -ForegroundColor Green
|
||||
Write-Host "`nThree revert scenarios have been created:" -ForegroundColor Cyan
|
||||
Write-Host " 1. regular-revert - Revert a single bad commit (basic)" -ForegroundColor White
|
||||
Write-Host " 2. merge-revert - Revert a merge commit with -m flag" -ForegroundColor White
|
||||
Write-Host " 3. multi-revert - Revert multiple bad commits" -ForegroundColor White
|
||||
Write-Host "`nYou are currently on the 'regular-revert' branch." -ForegroundColor Cyan
|
||||
Write-Host "`nNext steps:" -ForegroundColor Cyan
|
||||
Write-Host " 1. cd challenge" -ForegroundColor White
|
||||
Write-Host " 2. Read the README.md for detailed instructions" -ForegroundColor White
|
||||
Write-Host " 3. Complete each revert challenge" -ForegroundColor White
|
||||
Write-Host " 4. Run '..\verify.ps1' to check your solutions" -ForegroundColor White
|
||||
Write-Host ""
|
||||
226
01-essentials/05-revert/verify.ps1
Normal file
226
01-essentials/05-revert/verify.ps1
Normal file
@@ -0,0 +1,226 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Verifies the Module 05 challenge solutions.
|
||||
|
||||
.DESCRIPTION
|
||||
Checks that all three revert scenarios have been completed correctly:
|
||||
- regular-revert: Single commit reverted
|
||||
- merge-revert: Merge commit reverted with -m flag
|
||||
- multi-revert: Multiple commits reverted
|
||||
#>
|
||||
|
||||
Write-Host "`n=== Verifying Module 05: Git Revert Solutions ===" -ForegroundColor Cyan
|
||||
|
||||
$allChecksPassed = $true
|
||||
$originalDir = Get-Location
|
||||
|
||||
# Check if challenge directory exists
|
||||
if (-not (Test-Path "challenge")) {
|
||||
Write-Host "[FAIL] Challenge directory not found. Run setup.ps1 first." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Set-Location "challenge"
|
||||
|
||||
# Check if git repository exists
|
||||
if (-not (Test-Path ".git")) {
|
||||
Write-Host "[FAIL] Not a git repository. Run setup.ps1 first." -ForegroundColor Red
|
||||
Set-Location $originalDir
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# SCENARIO 1: Regular Revert Verification
|
||||
# ============================================================================
|
||||
Write-Host "`n=== Scenario 1: Regular Revert ===" -ForegroundColor Cyan
|
||||
|
||||
git switch regular-revert 2>&1 | Out-Null
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[FAIL] regular-revert branch not found" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
} else {
|
||||
# Check that a revert commit exists
|
||||
$revertCommit = git log --oneline --grep="Revert" 2>$null
|
||||
if ($revertCommit) {
|
||||
Write-Host "[PASS] Revert commit found" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] No revert commit found" -ForegroundColor Red
|
||||
Write-Host "[HINT] Use: git revert <commit-hash>" -ForegroundColor Yellow
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check that calculator.py exists
|
||||
if (Test-Path "calculator.py") {
|
||||
$calcContent = Get-Content "calculator.py" -Raw
|
||||
|
||||
# Check that divide function is NOT in the code (was reverted)
|
||||
if ($calcContent -notmatch "def divide") {
|
||||
Write-Host "[PASS] Broken divide function successfully reverted" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] divide function still exists (should be reverted)" -ForegroundColor Red
|
||||
Write-Host "[HINT] The bad commit should be reverted, removing the divide function" -ForegroundColor Yellow
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check that modulo function still exists (should be preserved)
|
||||
if ($calcContent -match "def modulo") {
|
||||
Write-Host "[PASS] modulo function preserved (good commit after bad one)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] modulo function missing (should still exist)" -ForegroundColor Red
|
||||
Write-Host "[HINT] Only revert the bad commit, not the good ones after it" -ForegroundColor Yellow
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check that multiply function exists (should be preserved)
|
||||
if ($calcContent -match "def multiply") {
|
||||
Write-Host "[PASS] multiply function preserved (good commit before bad one)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] multiply function missing" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
} else {
|
||||
Write-Host "[FAIL] calculator.py not found" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# SCENARIO 2: Merge Revert Verification
|
||||
# ============================================================================
|
||||
Write-Host "`n=== Scenario 2: Merge Revert ===" -ForegroundColor Cyan
|
||||
|
||||
git switch merge-revert 2>&1 | Out-Null
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[FAIL] merge-revert branch not found" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
} else {
|
||||
# Check that a revert commit for the merge exists
|
||||
$revertMerge = git log --oneline --grep="Revert.*Merge" 2>$null
|
||||
if ($revertMerge) {
|
||||
Write-Host "[PASS] Merge revert commit found" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] No merge revert commit found" -ForegroundColor Red
|
||||
Write-Host "[HINT] Use: git revert -m 1 <merge-commit-hash>" -ForegroundColor Yellow
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check that the original merge commit still exists (revert doesn't erase it)
|
||||
$mergeCommit = git log --merges --oneline --grep="Merge feature-auth" 2>$null
|
||||
if ($mergeCommit) {
|
||||
Write-Host "[PASS] Original merge commit still in history (not erased)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[INFO] Original merge commit not found (this is OK if you used a different approach)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Check that auth.py no longer exists or its effects are reverted
|
||||
if (-not (Test-Path "auth.py")) {
|
||||
Write-Host "[PASS] auth.py removed (merge reverted successfully)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[INFO] auth.py still exists (check if merge was fully reverted)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Check that calculator.py exists
|
||||
if (Test-Path "calculator.py") {
|
||||
$calcContent = Get-Content "calculator.py" -Raw
|
||||
|
||||
# After reverting the merge, calculator shouldn't import auth
|
||||
if ($calcContent -notmatch "from auth import") {
|
||||
Write-Host "[PASS] Auth integration reverted from calculator.py" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] calculator.py still imports auth (merge not fully reverted)" -ForegroundColor Red
|
||||
Write-Host "[HINT] Reverting the merge should remove the auth integration" -ForegroundColor Yellow
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# SCENARIO 3: Multi Revert Verification
|
||||
# ============================================================================
|
||||
Write-Host "`n=== Scenario 3: Multi Revert ===" -ForegroundColor Cyan
|
||||
|
||||
git switch multi-revert 2>&1 | Out-Null
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[FAIL] multi-revert branch not found" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
} else {
|
||||
# Count revert commits
|
||||
$revertCommits = git log --oneline --grep="Revert" 2>$null
|
||||
$revertCount = ($revertCommits | Measure-Object).Count
|
||||
|
||||
if ($revertCount -ge 2) {
|
||||
Write-Host "[PASS] Found $revertCount revert commits (expected at least 2)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] Found only $revertCount revert commit(s), need at least 2" -ForegroundColor Red
|
||||
Write-Host "[HINT] Revert both bad commits: git revert <commit1> <commit2>" -ForegroundColor Yellow
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check calculator.py content
|
||||
if (Test-Path "calculator.py") {
|
||||
$calcContent = Get-Content "calculator.py" -Raw
|
||||
|
||||
# Check that square_root is NOT in code (reverted)
|
||||
if ($calcContent -notmatch "def square_root") {
|
||||
Write-Host "[PASS] Broken square_root function reverted" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] square_root function still exists (should be reverted)" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check that logarithm is NOT in code (reverted)
|
||||
if ($calcContent -notmatch "def logarithm") {
|
||||
Write-Host "[PASS] Broken logarithm function reverted" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] logarithm function still exists (should be reverted)" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check that power function still exists (good commit before bad ones)
|
||||
if ($calcContent -match "def power") {
|
||||
Write-Host "[PASS] power function preserved" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] power function missing (should still exist)" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
|
||||
# Check that absolute function still exists (good commit after bad ones)
|
||||
if ($calcContent -match "def absolute") {
|
||||
Write-Host "[PASS] absolute function preserved" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] absolute function missing (should still exist)" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
} else {
|
||||
Write-Host "[FAIL] calculator.py not found" -ForegroundColor Red
|
||||
$allChecksPassed = $false
|
||||
}
|
||||
}
|
||||
|
||||
Set-Location $originalDir
|
||||
|
||||
# Final summary
|
||||
Write-Host ""
|
||||
if ($allChecksPassed) {
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
Write-Host " CONGRATULATIONS! ALL SCENARIOS PASSED!" -ForegroundColor Green
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
Write-Host "`nYou've mastered git revert!" -ForegroundColor Cyan
|
||||
Write-Host "You now understand:" -ForegroundColor Cyan
|
||||
Write-Host " ✓ Reverting regular commits safely" -ForegroundColor White
|
||||
Write-Host " ✓ Reverting merge commits with -m flag" -ForegroundColor White
|
||||
Write-Host " ✓ Reverting multiple commits at once" -ForegroundColor White
|
||||
Write-Host " ✓ Preserving history while undoing changes" -ForegroundColor White
|
||||
Write-Host "`nReady for Module 06: Git Reset!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
exit 0
|
||||
} else {
|
||||
Write-Host "[SUMMARY] Some checks failed. Review the hints above and try again." -ForegroundColor Red
|
||||
Write-Host "[INFO] You can run this verification script as many times as needed." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
Reference in New Issue
Block a user