Make the three states visible

kind: drill

Create a repository, add a file, and run git status after every single step: after creating the file, after git add, after git commit, after editing the file again.

Solution

Untracked → staged ("Changes to be committed") → clean → modified but not staged. The fourth state is the one that surprises people: the file is committed and changed, so the repository and your disk disagree. git diff shows exactly that disagreement.

Recover a deleted file from the history

kind: drill

Commit a file, delete it in the working tree, then restore it from the last commit without retyping it.

Solution
git restore report.adoc      # or: git checkout -- report.adoc

Works because the commit holds the whole state, not just a diff. If the deletion was already committed, git restore --source=HEAD~1 report.adoc reaches one commit further back.

Rewrite five bad commit messages in Conventional Commits form

kind: drill

Rewrite: update, asdf, fixed it, changes to the file, work. Assume they belonged to: a CSV export you added, a crash on an empty member list, a renamed field, an updated dependency, and a corrected README. Give each one a type and, where it helps, a scope.

Solution
feat(export): write attendance to CSV
fix(members): stop the crash on an empty list
refactor(booking): rename date to startsAt
chore(deps): update asciidoctor to 1.83
docs(readme): correct the setup command

There is no single right wording, but each line must answer "what changes for the reader", and its type must be the one an outsider would pick. Two checks worth doing: refactor may not change behaviour — if it does, it is a feat or a fix; and a commit whose type you cannot decide is usually too large. In the team project the task id belongs in each message as well, as the project guidelines require.

Read a history by type

kind: drill

In a repository with a few dozen commits, answer with git log alone: which features were added, which bugs were fixed, and what was pure housekeeping.

Solution
git log --oneline | grep -E '^[0-9a-f]+ feat'
git log --oneline | grep -E '^[0-9a-f]+ fix'
git log --oneline | grep -E '^[0-9a-f]+ (chore|style|ci|build)'

This is the payoff of the convention: the question is answered from the history itself, without asking anyone. In a repository whose messages read update, work, asdf, the same question needs a meeting. Convention over reporting is the whole idea.

Sort the commands by where they act

kind: drill

Sort into "works offline" and "needs the network": git add, git commit, git clone, git diff, git fetch, git log, git push, git status. Then say for each network command which two places in the picture it connects.

Solution

Offline: add, commit, diff, log, status — they only touch the working tree, the index and .git. Network: clone (remote → a new local repository plus working tree), fetch (remote → local repository, your files untouched), push (local repository → remote). The full history lies on both sides, which is why almost everything works without a server.

Publish your practice repository on GitHub

kind: drill

Until now your repository exists on one disk. Create an empty repository in your GitHub account, connect it as origin, push main, and check in the browser that the commits and their messages are there. Then clone the repository into a second directory and compare git log on both sides.

Solution
gh repo create syp-practice --private --source=. --remote=origin --push

# without gh, after creating the empty repository in the web interface:
git remote add origin git@github.com:<account>/syp-practice.git
git push -u origin main
git remote -v

git clone git@github.com:<account>/syp-practice.git ~/tmp/copy

-u records origin/main as the upstream branch, so later git push and git pull work without arguments. The clone carries the same commits with the same hashes — the history is copied, not summarised. Permission denied (publickey) means the SSH key created by setup-tools.sh is not registered in your GitHub account; add it under Settings → SSH and GPG keys and push again.

Set up your project repository

kind: project

Create the repository for your team project from the template, add a .gitignore that fits your stack, and make the first commit.