Skip to content

Commit 6242a14

Browse files
brabojclaude
andcommitted
docs: add hands-on exercises for all three sections
- Introduction: 6 exercises (installation, config, first repo, dataflow) - Concepts: 10 exercises (objects, tagging, branching, merging, conflicts) - Operations: 12 exercises (basic tracking → branching → rebase/reset) Progressive difficulty, realistic scenarios, no solutions provided. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5c568db commit 6242a14

4 files changed

Lines changed: 561 additions & 0 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
## Exercises
2+
3+
Hands-on exercises for the Introduction section. Use the reference pages
4+
in this chapter if you get stuck. Do not skip the verification steps.
5+
6+
### Exercise 1: Verify Your Git Installation
7+
8+
**Task:** Confirm that Git is installed and check which version you are running.
9+
10+
**Steps:**
11+
1. Open a terminal (PowerShell on Windows, a shell on Linux/macOS)
12+
2. Run the command to display the installed Git version
13+
3. Run the command to display the built-in help overview
14+
15+
**Verify:** The version command prints a line starting with `git version` followed by
16+
a version number. The help command prints a list of common Git commands grouped
17+
by category.
18+
19+
---
20+
21+
### Exercise 2: Configure Your Identity
22+
23+
**Task:** Set up the user name and email that Git will attach to every commit
24+
you make.
25+
26+
**Steps:**
27+
1. Set your global user name using `git config`
28+
2. Set your global email address using `git config`
29+
3. Read back both values to confirm they are stored correctly
30+
4. Display the full list of configuration settings with `git config --list`
31+
32+
**Verify:** The read-back commands print exactly the name and email you entered.
33+
Both entries also appear in the `--list` output.
34+
35+
---
36+
37+
### Exercise 3: Create a Local Repository
38+
39+
**Task:** Initialise a brand-new local Git repository and make your first commit.
40+
41+
**Steps:**
42+
1. Create a new directory called `git-exercises` and enter it
43+
2. Initialise a Git repository inside the directory
44+
3. Create a file called `hello.txt` with some text in it
45+
4. Check the status of the working tree
46+
5. Add the file to the staging area (index)
47+
6. Check the status again to see the file is staged
48+
7. Commit the staged file with the message `Add hello.txt`
49+
50+
**Verify:** Running `git log` shows one commit with the message `Add hello.txt`.
51+
Running `git status` reports a clean working tree with nothing to commit.
52+
53+
---
54+
55+
### Exercise 4: Explore the Dataflow
56+
57+
**Task:** Walk through each storage location in the Git dataflow — workspace,
58+
index, and local repository — by making a change and moving it through
59+
the pipeline.
60+
61+
**Steps:**
62+
1. Inside the `git-exercises` repository, edit `hello.txt` and add a second line
63+
2. Run `git status` to see the file listed as modified (workspace)
64+
3. Run `git diff` to see the exact change
65+
4. Add the file to the index with `git add`
66+
5. Run `git status` again to see the file listed as staged (index)
67+
6. Run `git diff --staged` to see what will be committed
68+
7. Commit the change with a descriptive message
69+
8. Run `git log` to confirm the new commit appears in the local repository
70+
71+
**Verify:** `git status` reports a clean working tree. `git log` shows two commits
72+
in chronological order.
73+
74+
---
75+
76+
### Exercise 5: Inspect the Repository
77+
78+
**Task:** Use several inspection commands to examine commit history,
79+
object contents, and repository status.
80+
81+
**Steps:**
82+
1. Run `git log` to see the full commit history
83+
2. Run `git log --oneline` to see a compact view
84+
3. Copy the short hash of the first commit from the oneline output
85+
4. Run `git cat-file -t <hash>` to check the object type (replace `<hash>`)
86+
5. Run `git cat-file -p <hash>` to display the commit object contents
87+
6. Note the tree hash printed in the output, then run `git cat-file -p <tree-hash>`
88+
to list the files recorded in that commit
89+
90+
**Verify:** The `-t` command prints `commit`. The `-p` command on the commit shows
91+
author, committer, tree hash, and the commit message. The `-p` command on the tree
92+
lists the `hello.txt` blob.
93+
94+
---
95+
96+
### Exercise 6: Connect to a Remote Repository
97+
98+
**Task:** Create a repository on a hosting service, link it to your local
99+
repository, and push your commits.
100+
101+
**Steps:**
102+
1. Sign in to GitHub (or another hosting service from the reference page)
103+
2. Create a new empty repository named `git-exercises` — do not add a README
104+
or any other files
105+
3. Copy the HTTPS URL of the new repository
106+
4. In your local `git-exercises` repository, add the remote with
107+
`git remote add origin <url>`
108+
5. Run `git remote -v` to confirm the remote is registered
109+
6. Push the local commits to the remote with `git push -u origin main`
110+
7. Refresh the repository page in the browser
111+
112+
**Verify:** The hosting service shows all committed files and the full commit
113+
history matches what `git log` displays locally. Running `git branch -av`
114+
shows both the local and remote branch pointing to the same commit.

docs/02-Concepts/17-exercises.md

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
## Exercises
2+
3+
Hands-on exercises for reinforcing the concepts covered in this section.
4+
All exercises use a fresh, disposable repository unless stated otherwise.
5+
6+
---
7+
8+
### Exercise 1: Create and Inspect a Repository
9+
10+
**Task:** Initialize a new Git repository and explore its internal structure.
11+
12+
**Steps:**
13+
1. Create a new directory called `concepts-lab` and navigate into it
14+
2. Run `git init` to create a repository
15+
3. List the contents of the `.git` directory
16+
4. Identify the `objects`, `refs/heads`, and `refs/tags` subdirectories
17+
5. Read the `HEAD` file and note what it points to
18+
6. Create a bare repository called `concepts-lab.git` in a sibling directory using `git init --bare`
19+
7. Compare the directory structure of the bare repository with the `.git` folder
20+
21+
**Verify:** The `.git` directory exists and contains `objects`, `refs`, `HEAD`, and `config`. The bare repository has the same internal structure but no working tree.
22+
23+
---
24+
25+
### Exercise 2: Configure User Identity at Two Levels
26+
27+
**Task:** Set user name and email at the local and global levels and observe which one takes precedence.
28+
29+
**Steps:**
30+
1. Inside `concepts-lab`, set a global user name and email using `git config --global`
31+
2. Set a different local user name and email using `git config --local`
32+
3. Run `git config --list --show-origin` to see all active settings and their sources
33+
4. Create a file, stage it, and commit it
34+
5. Run `git log` and check which user name and email appear in the commit
35+
6. Remove the local overrides using `git config --local --unset user.name` and `git config --local --unset user.email`
36+
7. Make another commit and verify the global identity is now used
37+
38+
**Verify:** The first commit shows the local identity. The second commit shows the global identity. `git config --list --show-origin` displays both levels and marks which file each setting comes from.
39+
40+
---
41+
42+
### Exercise 3: Explore Git Objects
43+
44+
**Task:** Create blobs, trees, and commits, then inspect them with plumbing commands.
45+
46+
**Steps:**
47+
1. In `concepts-lab`, create a file called `hello.txt` with the content `Hello, Git!`
48+
2. Stage the file with `git add hello.txt`
49+
3. Run `git ls-files --stage` and note the blob hash next to the file name
50+
4. Inspect the blob content using `git cat-file -p <blob-hash>`
51+
5. Inspect the blob type using `git cat-file -t <blob-hash>`
52+
6. Commit the file
53+
7. Run `git log --format=raw -1` to see the commit object and note the tree hash
54+
8. Inspect the tree using `git cat-file -p <tree-hash>`
55+
9. Verify that the tree references the same blob hash from step 3
56+
10. Browse the `.git/objects` directory and locate the two-character subdirectory matching the first two characters of the blob hash
57+
58+
**Verify:** `git cat-file -p` on the blob prints `Hello, Git!`. The tree object lists the blob hash with mode `100644` and file name `hello.txt`. The corresponding object file exists on disk under `.git/objects`.
59+
60+
---
61+
62+
### Exercise 4: Lightweight and Annotated Tags
63+
64+
**Task:** Create both tag types and compare how Git stores them internally.
65+
66+
**Steps:**
67+
1. In `concepts-lab`, make sure you have at least one commit
68+
2. Create a lightweight tag called `v0.1` using `git tag v0.1`
69+
3. Create an annotated tag called `v1.0` with the message `First release` using `git tag -a v1.0 -m "First release"`
70+
4. List all tags with `git tag`
71+
5. Read the lightweight tag reference file at `.git/refs/tags/v0.1` and note the hash
72+
6. Read the annotated tag reference file at `.git/refs/tags/v1.0` and note the hash
73+
7. Run `git cat-file -t` on both hashes and compare the object types
74+
8. Run `git cat-file -p` on the annotated tag hash and inspect the tagger, date, message, and target reference
75+
76+
**Verify:** The lightweight tag hash points directly to a commit object (`git cat-file -t` prints `commit`). The annotated tag hash points to a tag object (`git cat-file -t` prints `tag`), which in turn references the commit.
77+
78+
---
79+
80+
### Exercise 5: Stage, Unstage, and Inspect the Index
81+
82+
**Task:** Use the index to selectively stage changes and observe its contents.
83+
84+
**Steps:**
85+
1. In `concepts-lab`, create two files: `tracked.txt` and `experimental.txt`
86+
2. Stage only `tracked.txt` with `git add tracked.txt`
87+
3. Run `git ls-files --stage` to see what is in the index
88+
4. Run `git status` and note which file is staged and which is untracked
89+
5. Now stage `experimental.txt` with `git add experimental.txt`
90+
6. Run `git ls-files --stage` again and confirm both entries appear
91+
7. Remove `experimental.txt` from the index without deleting the file using `git rm --cached experimental.txt`
92+
8. Run `git ls-files --stage` a final time and confirm only `tracked.txt` remains
93+
9. Commit the staged file
94+
95+
**Verify:** After step 7, `git ls-files --stage` shows only `tracked.txt`. After the commit, `git status` shows `experimental.txt` as untracked and the working tree is otherwise clean.
96+
97+
---
98+
99+
### Exercise 6: Create, Switch, and Delete Branches
100+
101+
**Task:** Practice the full branch lifecycle and observe how references change.
102+
103+
**Steps:**
104+
1. In `concepts-lab`, confirm you are on the `main` branch with `git branch`
105+
2. Read `.git/refs/heads/main` and note the commit hash
106+
3. Create a new branch called `feature/greeting` using `git branch feature/greeting`
107+
4. Read `.git/refs/heads/feature/greeting` and confirm it points to the same commit
108+
5. Switch to the new branch with `git switch feature/greeting`
109+
6. Read `.git/HEAD` and confirm it now references `refs/heads/feature/greeting`
110+
7. Create a new file `greeting.txt`, stage, and commit it
111+
8. Read `.git/refs/heads/feature/greeting` again and confirm it advanced to the new commit
112+
9. Read `.git/refs/heads/main` and confirm it still points to the original commit
113+
10. Switch back to `main` and delete the branch with `git branch -d feature/greeting`
114+
115+
**Verify:** After deletion, the file `.git/refs/heads/feature/greeting` no longer exists. `git branch` lists only `main`. The commit created on the feature branch becomes unreachable.
116+
117+
---
118+
119+
### Exercise 7: Three-Way Merge with a Conflict
120+
121+
**Task:** Create a merge conflict, inspect the conflict markers, and resolve it manually.
122+
123+
**Steps:**
124+
1. In `concepts-lab`, create a file `config.txt` with the line `mode=production` and commit it on `main`
125+
2. Create and switch to a branch `feature/debug` using `git switch -c feature/debug`
126+
3. Change the line in `config.txt` to `mode=debug` and commit
127+
4. Switch back to `main`
128+
5. Change the same line in `config.txt` to `mode=staging` and commit
129+
6. Run `git merge feature/debug`
130+
7. Open `config.txt` and locate the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`)
131+
8. Run `git ls-files --stage` and observe the three stage entries (base, ours, theirs) for `config.txt`
132+
9. Edit `config.txt` to resolve the conflict by choosing one value or combining them
133+
10. Stage the resolved file with `git add config.txt` and complete the merge with `git commit`
134+
135+
**Verify:** After the merge commit, `git log --oneline --graph` shows the two branches converging. `git ls-files --stage` shows a single stage-0 entry for `config.txt`. The file contains the resolved content with no conflict markers.
136+
137+
---
138+
139+
### Exercise 8: Stash and Restore Work in Progress
140+
141+
**Task:** Use the stash to save uncommitted changes, switch branches, then restore them.
142+
143+
**Steps:**
144+
1. In `concepts-lab`, make sure you are on `main` with a clean working tree
145+
2. Create a file `notes.txt` with the content `Work in progress`
146+
3. Stage the file with `git add notes.txt`
147+
4. Run `git stash push -m "wip: notes"` to save the changes
148+
5. Confirm the working tree is clean with `git status`
149+
6. Run `git stash list` and note the stash entry `stash@{0}`
150+
7. Inspect the stash reference at `.git/refs/stash` and run `git cat-file -p` on it
151+
8. Create and switch to a new branch `feature/other`, make any commit, then switch back to `main`
152+
9. Restore the stashed changes with `git stash pop`
153+
10. Confirm `notes.txt` is back in the working tree and staged
154+
155+
**Verify:** After `git stash pop`, `git status` shows `notes.txt` as a staged new file. `git stash list` is empty.
156+
157+
---
158+
159+
### Exercise 9: Partial Staging with the Index
160+
161+
**Task:** Stage only some changes from a single file to make a focused commit.
162+
163+
**Steps:**
164+
1. In `concepts-lab`, create a file `multi.txt` with three lines: `line1`, `line2`, `line3` and commit it
165+
2. Modify the file so that `line1` becomes `LINE1` and `line3` becomes `LINE3` (leave `line2` unchanged)
166+
3. Run `git diff` to confirm both hunks appear
167+
4. Use `git add -p multi.txt` to interactively stage only the first hunk (the change to `line1`)
168+
5. Run `git diff --cached` and confirm only the `line1` change is staged
169+
6. Run `git diff` and confirm the `line3` change remains in the working tree
170+
7. Commit the staged hunk
171+
8. Stage and commit the remaining change
172+
173+
**Verify:** `git log --oneline` shows two separate commits. Running `git diff HEAD~1 HEAD~2` shows only the `line1` change. Running `git diff HEAD HEAD~1` shows only the `line3` change.
174+
175+
---
176+
177+
### Exercise 10: Simulate a Branching Strategy
178+
179+
**Task:** Apply a simplified Git Flow workflow using branches and merges.
180+
181+
**Steps:**
182+
1. Create a fresh repository called `flow-lab` and navigate into it
183+
2. Create an initial commit on `main` with a file `app.txt` containing `v1.0`
184+
3. Create a `develop` branch from `main` and switch to it
185+
4. Create a `feature/login` branch from `develop`, add a file `login.txt`, and commit
186+
5. Merge `feature/login` into `develop` and delete the feature branch
187+
6. Create a `release/1.1` branch from `develop`
188+
7. On the release branch, update `app.txt` to `v1.1` and commit the change
189+
8. Merge `release/1.1` into `main` and tag `main` with an annotated tag `v1.1`
190+
9. Merge `release/1.1` into `develop` to bring the version bump back
191+
10. Delete the release branch
192+
11. Run `git log --oneline --graph --all` to visualize the full history
193+
194+
**Verify:** `main` and `develop` both contain the `v1.1` change and the `login.txt` file. The tag `v1.1` exists and points to the merge commit on `main`. The feature and release branches are deleted. The graph shows the expected merge topology.

0 commit comments

Comments
 (0)