The player shows one focused example. The sections below explain the ideas behind each topic.
Most days you only need status, add, commit, branch, merge and push. This lesson covers the tools for the awkward moments in between: parking half-finished work, copying one fix to another branch, hunting down the commit that broke something, and working with several checkouts or very large repositories.
Each section is a separate small example, as in the walkthrough above. Commit IDs and folder paths will differ in your repository.
Stash
You are halfway through a change when an urgent bug comes in. The work is not ready to commit, but you need a clean folder to switch branches. git stash saves your uncommitted changes on a stack and puts your files back to the last commit.
Put work aside, then bring it back
-u includes untracked files such as the new ideas.txt; without it, new files are left behind. -m labels the stash so you can recognise it later. git stash pop reapplies the latest stash and removes it from the list.
bash
git status --short
git stash push -u -m "draft config"
git status --short
git stash list
git stash pop
text
$ git status --short
M config.yml
?? ideas.txt
$ git stash push -u -m "draft config"
Saved working directory and index state On main: draft config
$ git status --short
$ git stash list
stash@{0}: On main: draft config
$ git stash pop
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: config.yml
Untracked files:
(use "git add <file>..." to include in what will be committed)
ideas.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (ba3c7c43699dfa58649f88722a8f789488b187cc)
Output
Stash commands
Command
What it does
git stash push -u -m "label"
Save changes, including new files, with a label
git stash list
Show saved stashes, newest first
git stash pop
Reapply the newest stash and remove it
git stash apply stash@{1}
Reapply a specific stash but keep it in the list
git stash drop stash@{1}
Delete one stash
Cherry-pick
Sometimes one commit on a feature branch is needed on main now, while the rest of the branch is not ready. git cherry-pick copies the changes of chosen commits onto your current branch as new commits.
Copy one fix to main
Only Fix port clash is copied. The new commit has its own ID but the same message and changes; Git also prints the original author date.
$ git log --oneline main..search
d4ffe4a Add search ranking
19e9713 Fix port clash
7a6bea5 Add search
$ git switch main
Switched to branch 'main'
$ git cherry-pick 19e9713
[main fd35351] Fix port clash
Date: Tue Oct 20 09:03:00 2026 +0100
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline
fd35351 Fix port clash
4411725 Add config
Output
Bisect
Something worked at an older commit and is broken now, but there are dozens of commits in between. git bisect finds the first bad commit by binary search: it checks out a commit halfway, you say whether it is good or bad, and it halves the range each time. Even 1,000 commits take only about 10 tests.
Find the commit that broke the config
Start with a bad commit (HEAD) and a known good one. At each step, test the project and answer good or bad. Here the test is whether config.yml contains the broken port: 0. After three answers, Git names Tidy config as the first bad commit.
bash
git bisect start HEAD fd35351
git bisect good
git bisect bad
git bisect good
git bisect reset
text
$ git bisect start HEAD fd35351
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[1ad6874f664e8cd656ff7d6e3e53787806e99872] Update docs 4
$ git bisect good
Bisecting: 1 revision left to test after this (roughly 1 step)
[54446121f00b9e51dc4a03a5dd5949cab6bbe8d5] Tidy config
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[7c2b693a1dd25590d2a3be845975c2b400a31c44] Update docs 5
$ git bisect good
54446121f00b9e51dc4a03a5dd5949cab6bbe8d5 is the first bad commit
commit 54446121f00b9e51dc4a03a5dd5949cab6bbe8d5
Author: Alex Bennett <alex@example.com>
Date: Tue Oct 20 09:16:00 2026 +0100
Tidy config
README.md | 1 +
config.yml | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
$ git bisect reset
Previous HEAD position was 7c2b693 Update docs 5
Switched to branch 'main'
Output
If you have a command that exits with 0 when the project is good and 1 when it is bad, such as your test suite, git bisect run does all the testing for you:
bash
git bisect start HEAD fd35351
git bisect run npm test
git bisect reset
Worktrees, sparse checkout, and submodules
These three change how a repository is laid out on disk. Each solves a specific problem.
Worktrees: a second branch in a second folder
A worktree checks out another branch in a separate folder that shares the same repository, so you can fix a bug on hotfix without stashing or disturbing your current work. Remove it when finished.
bash
git worktree add -b hotfix ../planner-hotfix main
git worktree list
git worktree remove ../planner-hotfix
text
$ git worktree add -b hotfix ../planner-hotfix main
Preparing worktree (new branch 'hotfix')
HEAD is now at b79a01f Update docs 8
$ git worktree list
/home/alex/planner b79a01f [main]
/home/alex/planner-hotfix b79a01f [hotfix]
$ git worktree remove ../planner-hotfix
Output
Sparse checkout: only the folders you need
In a very large repository you can check out just some folders. The assets folder is not written to disk; the full history is still there. git sparse-checkout disable brings everything back.
bash
git sparse-checkout set src docs
git sparse-checkout list
ls
text
$ git sparse-checkout set src docs
$ git sparse-checkout list
docs
src
$ ls
README.md
docs
src
Output
Submodules: another repository inside yours
A submodule pins a separate repository at one exact commit inside a folder of your project. Git records the address in .gitmodules and the pinned commit as the vendor/lib entry.
bash
git submodule add https://github.com/your-team/date-utils.git vendor/lib
git status --short
text
$ git submodule add https://github.com/your-team/date-utils.git vendor/lib
Cloning into '/home/alex/planner/vendor/lib'...
done.
$ git status --short
A .gitmodules
A vendor/lib
Output
You need a clean folder to fix an urgent bug, but have half-finished edits and one new file. Which command keeps both safe?
Reveal answer
git stash push -u -m "label". The -u matters: without it, the new untracked file is not stashed. Later, git stash pop brings both back.
A bug appeared somewhere in the last 200 commits. Roughly how many commits will git bisect ask you to test?
Reveal answer
About 8. Each answer halves the range, and 2⁸ = 256 covers 200 commits.