Vasu Patel logoVasu Patel
← Git Mastery
All chapters in this track
  1. 011. The Mental Model
  2. 022. Essential Setup
  3. 033. Core Daily Workflow
  4. 044. Branching
  5. 055. Merging & Conflict Resolution
  6. 066. Rebasing
  7. 077. Remote Repositories
  8. 088. Stashing
  9. 099. Undoing Things
  10. 1010. Tagging & Versioning
  11. 1111. Cherry-Pick
  12. 1212. Git Bisect & Blame
  13. 1313. Git Hooks
  14. 1414. Submodules
  15. 1515. Team Workflows
  16. 1616. Power Commands & Aliases
  17. 1717. Reflog: The Safety Net
  18. 1818. Practice Tasks
  19. 19Quick Reference Cheatsheet

Chapter 18 of 19

18. Practice Tasks

Work through these exercises in order. Each builds on the previous.


Exercise 1 — Staging & Committing

mkdir git-practice ; cd git-practice ; git init
echo "Hello World" > readme.txt
echo "secret=abc123" > .env

Tasks:

  1. Create a .gitignore that ignores .env
  2. Stage only readme.txt
  3. Commit with message docs: add readme
  4. Verify .env is untracked and not staged

Exercise 2 — Branches & Merging

# Starting from the repo above
git switch -c feature/about
echo "About page" > about.txt
git add . ; git commit -m "feat: add about page"
git switch main
echo "Main update" >> readme.txt
git add . ; git commit -m "chore: update readme"

Tasks:

  1. Merge feature/about into main — what type of merge is this? (3-way)
  2. Inspect the merge commit with git log --graph --oneline
  3. Delete feature/about

Exercise 3 — Rebase & Interactive Rebase

git switch -c feature/cleanup
echo "Step 1" > work.txt ; git add . ; git commit -m "WIP: step 1"
echo "Step 2" >> work.txt ; git add . ; git commit -m "WIP: step 2"
echo "Step 3" >> work.txt ; git add . ; git commit -m "feat: complete feature"

Tasks:

  1. Use interactive rebase to squash the three commits into one with message feat: implement cleanup feature
  2. Rebase feature/cleanup onto main
  3. Merge into main — observe it's a fast-forward

Exercise 4 — Conflict Resolution

git switch main
git switch -c branch-a
echo "Color: Blue" > config.txt ; git add . ; git commit -m "set color blue"
git switch main
echo "Color: Red" > config.txt ; git add . ; git commit -m "set color red"
git merge branch-a

Tasks:

  1. Resolve the conflict, choosing "Color: Purple" as the final value
  2. Complete the merge with a commit message merge: reconcile color config
  3. Verify the file contents and history with git log --oneline

Exercise 5 — Stash & Recover

git switch -c feature/header
echo "Header draft" > header.txt
# Don't commit yet — you need to hotfix main

Tasks:

  1. Stash your changes with a name "header work in progress"
  2. Switch to main, create file hotfix.txt, commit it
  3. Return to feature/header, pop the stash
  4. Verify header.txt is back and unstaged

Exercise 6 — Undoing & Reflog

echo "Important code" > important.py ; git add . ; git commit -m "feat: important"
echo "Bug introduced" >> important.py ; git add . ; git commit -m "wip: bad change"

Tasks:

  1. Use git reset --soft HEAD~1 — observe commit is undone but changes are staged
  2. Re-commit with a better message
  3. Use git reset --hard HEAD~1 to discard everything
  4. Use git reflog to find and recover the "feat: important" commit

Exercise 7 — Cherry-Pick

git switch -c experimental
echo "Util function" > utils.py ; git add . ; git commit -m "feat: add util function"
echo "Broken code" > bad.py ; git add . ; git commit -m "wip: broken experiment"

Tasks:

  1. Note the hash of the feat: add util function commit
  2. Switch to main
  3. Cherry-pick only the util function commit onto main
  4. Verify only utils.py appears, not bad.py

Exercise 8 — Full GitHub Flow Simulation

Simulate a complete feature cycle:

# Setup
git init shop ; cd shop
echo "# Shop" > README.md ; git add . ; git commit -m "init: project setup"

Tasks:

  1. Create feature/add-cart branch from main
  2. Add 3 commits simulating cart development
  3. Simulate a code review: use git rebase -i to clean up commits before "PR"
  4. Rebase onto main (simulate others merged code while you worked)
  5. Merge into main using --no-ff (simulating PR merge)
  6. Tag the release as v1.0.0
  7. Push everything to a remote (use a local bare repo as stand-in):
    git init --bare ../shop-remote.git
    git remote add origin ../shop-remote.git
    git push -u origin main
    git push origin --tags