Practice Git & GitHub
You’ve read the lessons — now prove it. Take the quiz for instant feedback, then work the coding exercises. Try each one yourself before you reveal the solution.
Quick quiz
17 questions- 1
What does
git initdo? - 2
Which command stages all modified and new files in the current directory for the next commit?
- 3
What does
git statusshow? - 4
Which command shows the commit history of the current branch?
- 5
What is the purpose of a
.gitignorefile? - 6
Which command creates a new branch called
feature/loginand switches to it in one step? - 7
You are on
mainand rungit merge feature/login. What happens? - 8
A merge conflict occurs when:
- 9
What does
git pulldo? - 10
Which command saves your uncommitted changes temporarily so you can switch branches without committing?
- 11
Which command safely creates a new commit that undoes the changes introduced by a previous commit?
- 12
What does
git reflogshow? - 13
You accidentally ran
git reset --hard HEAD~5and lost five commits. Which is the best way to recover them? - 14
What does
git cherry-pick abc1234do? - 15
During an automated
git bisect run <script>session, what exit code should the script return to tell Git the currently checked-out commit is good (bug not present)? - 16
A
.git/hooks/pre-commitscript exits with code 1. What happens? - 17
Which command adds a new worktree that checks out an existing branch
hotfix/crashinto the directory../project-fix?
Coding exercises
8 tasksInitialise a repo and make your first commit
EasyYou have a new project folder called my-project with a single file README.md. Initialise a Git repository, stage the file, and create an initial commit with the message "Initial commit".
# starting inside the my-project directory
💡 Show hint
Use git init, then git add, then git commit -m.
✅ Show solution
git init
git add README.md
git commit -m "Initial commit"Clone, branch, and push a feature branch
EasyClone the repository at https://github.com/example/demo.git, create a branch called feature/navbar, make a new file navbar.html, commit it with the message "Add navbar", and push the branch to the remote.
💡 Show hint
Remember git switch -c to create and switch, and git push -u origin <branch> for the first push.
✅ Show solution
git clone https://github.com/example/demo.git
cd demo
git switch -c feature/navbar
touch navbar.html
git add navbar.html
git commit -m "Add navbar"
git push -u origin feature/navbarResolve a merge conflict
MediumYou are on main. Another developer's work lives on feature/header. When you run git merge feature/header, Git reports a conflict in index.html. Describe the steps to open the file, resolve the conflict markers, stage the resolved file, and complete the merge.
💡 Show hint
After editing the file to remove <<<<<<<, =======, and >>>>>>> markers, use git add then git commit.
✅ Show solution
git merge feature/header
# --- conflict reported in index.html ---
# Open index.html, find and resolve all conflict markers:
# <<<<<<< HEAD
# ... your version ...
# =======
# ... incoming version ...
# >>>>>>> feature/header
# Edit the file to keep the desired content, then:
git add index.html
git commit -m "Merge feature/header into main"Interactive stash workflow
MediumYou are halfway through editing app.js on main when you need to switch to hotfix/typo to fix an urgent bug. Stash your current changes, switch to the hotfix branch, commit the fix, switch back to main, and then re-apply your stashed work.
💡 Show hint
Use git stash, git switch, git stash pop in the right order.
✅ Show solution
git stash
git switch hotfix/typo
# fix the typo in the relevant file, then:
git add .
git commit -m "Fix typo in homepage copy"
git switch main
git stash popRebase a feature branch and tag a release
HardYour feature/payments branch was created from an older commit on main. New commits have since landed on main. Rebase feature/payments onto the latest main so the history stays linear, then switch to main, merge feature/payments with a fast-forward, and finally create an annotated tag v1.0.0 with the message "First stable release" and push both the branch and the tag.
💡 Show hint
Use git rebase main while on the feature branch, then git merge --ff-only, then git tag -a and git push --tags.
✅ Show solution
git switch feature/payments
git rebase main
# resolve any rebase conflicts per file, then `git rebase --continue`
git switch main
git merge --ff-only feature/payments
git tag -a v1.0.0 -m "First stable release"
git push origin main
git push origin v1.0.0Recover a deleted branch using the reflog
MediumYou accidentally deleted a local branch feature/search with git branch -D feature/search. The branch has not been pushed to the remote. Use the reflog to find the tip commit of the deleted branch and recreate the branch pointing to that commit.
💡 Show hint
Run git reflog, find the last commit that was on feature/search, then use git switch -c with that SHA.
✅ Show solution
git reflog
# Scan the output for the last entry that mentions feature/search, e.g.:
# abc1234 HEAD@{3}: commit: add search bar component
git switch -c feature/search abc1234Cherry-pick a bugfix onto a release branch
MediumA critical bugfix was committed to main as commit c0ffee1. You have a long-running support branch release/1.x that also needs this fix. Cherry-pick the commit onto release/1.x, then push the branch.
💡 Show hint
Switch to the target branch first, then use git cherry-pick with the commit SHA.
✅ Show solution
git switch release/1.x
git cherry-pick c0ffee1
# If there are conflicts, resolve them, then:
git add .
git cherry-pick --continue
git push origin release/1.xSet up a pre-commit hook that blocks commits with console.log
HardWrite a pre-commit hook that scans staged .ts and .tsx files for console.log statements and aborts the commit if any are found. Make the script executable and verify it runs on git commit.
#!/usr/bin/env bash
# .git/hooks/pre-commit
set -e
💡 Show hint
Use git diff --cached --name-only to list staged files, then grep through them. Exit 1 if a match is found.
✅ Show solution
#!/usr/bin/env bash
# .git/hooks/pre-commit
set -e
STAGED=$(git diff --cached --name-only | grep -E '\.(ts|tsx)$' || true)
if [ -z "$STAGED" ]; then
exit 0
fi
if echo "$STAGED" | xargs grep -l 'console\.log' 2>/dev/null; then
echo "Error: console.log found in staged files. Remove it before committing."
exit 1
fi
exit 0
# Make executable:
# chmod +x .git/hooks/pre-commit