CPCODELAB
Practice

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
Score: 0 / 17
0/17 answered
  1. 1

    What does git init do?

  2. 2

    Which command stages all modified and new files in the current directory for the next commit?

  3. 3

    What does git status show?

  4. 4

    Which command shows the commit history of the current branch?

  5. 5

    What is the purpose of a .gitignore file?

  6. 6

    Which command creates a new branch called feature/login and switches to it in one step?

  7. 7

    You are on main and run git merge feature/login. What happens?

  8. 8

    A merge conflict occurs when:

  9. 9

    What does git pull do?

  10. 10

    Which command saves your uncommitted changes temporarily so you can switch branches without committing?

  11. 11

    Which command safely creates a new commit that undoes the changes introduced by a previous commit?

  12. 12

    What does git reflog show?

  13. 13

    You accidentally ran git reset --hard HEAD~5 and lost five commits. Which is the best way to recover them?

  14. 14

    What does git cherry-pick abc1234 do?

  15. 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. 16

    A .git/hooks/pre-commit script exits with code 1. What happens?

  17. 17

    Which command adds a new worktree that checks out an existing branch hotfix/crash into the directory ../project-fix?

🛠️

Coding exercises

8 tasks
1

Initialise a repo and make your first commit

Easy

You 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".

Starter
bash
# starting inside the my-project directory
💡 Show hint

Use git init, then git add, then git commit -m.

✅ Show solution
bash
git init
git add README.md
git commit -m "Initial commit"
2

Clone, branch, and push a feature branch

Easy

Clone 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
bash
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/navbar
3

Resolve a merge conflict

Medium

You 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
bash
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"
4

Interactive stash workflow

Medium

You 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
bash
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 pop
5

Rebase a feature branch and tag a release

Hard

Your 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
bash
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.0
6

Recover a deleted branch using the reflog

Medium

You 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
bash
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 abc1234
7

Cherry-pick a bugfix onto a release branch

Medium

A 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
bash
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.x
8

Set up a pre-commit hook that blocks commits with console.log

Hard

Write 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.

Starter
bash
#!/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
bash
#!/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