Git Hands-on Exercises — Build Campus Library Yourself
Time to stop reading and start doing. These exercises run entirely on your own computer — no GitHub account, no internet needed. Copy each command, run it, and compare what you see with the expected output below it.
Open a terminal, type the commands one by one, and read the output. If your output differs, re-read the step — something small (like being in the wrong folder) is usually the cause.
Exercise 0 · Setup — Who Are You?
Make sure Git is installed and knows who you are.
git --version
git version 2.4x.x
git config --global user.name "Riya Sharma"
git config --global user.email "riya@campuslibrary.dev"
git config --global user.name
Riya Sharma
Exercise 1 · First Commit — Riya Opens the Notebook
Riya starts the Campus Library project. She creates the folder, opens the register, and saves the very first pages.
mkdir campus-library
cd campus-library
git init
Initialized empty Git repository in .../campus-library/.git/
Now create the first page with a terminal text editor (this example uses nano; use any editor):
nano index.html
Write anything simple inside, for example:
<h1>Welcome to Campus Library</h1>
Save (Ctrl+O, then Ctrl+X in nano) and check the librarian's view:
git status
On branch master (or: main)
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
Save the page into the notebook forever:
git add .
git commit -m "Create Campus Library homepage"
[master (root-commit) 9b2c4d1] Create Campus Library homepage
1 file changed, 1 insertion(+)
create mode 100644 index.html
git log --oneline
9b2c4d1 (HEAD -> master) Create Campus Library homepage
You just made your first commit.
Exercise 2 · Branch & Merge — Simran Builds Login
Simran joins the project. She wants a login page but does not want to touch the main notebook. She takes her own copy.
git switch -c feature-login
Switched to a new branch 'feature-login'
Create the login page:
nano login.html
Write:
<h1>Login to Campus Library</h1>
git add .
git commit -m "Add login page"
[feature-login c2e8a77] Add login page
1 file changed, 1 insertion(+)
Now check: does the main notebook have this page yet?
git switch main
git log --oneline
9b2c4d1 (HEAD -> main) Create Campus Library homepage
The login page is not here — it lives only on Simran's branch. Safe! Now bring it into the official notebook:
git merge feature-login
Updating 9b2c4d1..c2e8a77
Fast-forward
login.html | 1 +
1 file created, 1 insertion(+)
The branch did its job. Clean it up:
git branch -d feature-login
Deleted branch feature-login (was c2e8a77).
Exercise 3 · The Conflict — When Two Friends Edit the Same Page
This is the one everyone remembers. Two friends edit the same line of the same page and then try to combine notebooks. The librarian stops and asks them to decide.
Start on main and create a books page with one line:
nano books.html
Write:
Book 1: Sherlock Holmes
Commit it:
git add .
git commit -m "Add recommended books list"
Simran takes a branch and changes that line:
git switch -c feature-books
nano books.html
Change the line to:
Book 2: Harry Potter
git add .
git commit -m "Update books list"
Back on main, Riya (unknowingly) changes the same line:
git switch main
nano books.html
Change the line to:
Book 3: Dune
git add .
git commit -m "Update books list"
Now Simran tries to combine her notebook with main:
git merge feature-books
Auto-merging books.html
CONFLICT (content): Merge conflict in books.html
Automatic merge failed; fix conflicts and then commit the result.
A conflict! Git cannot decide which book comes next in the list. Look at the battlefield:
cat books.html
<<<<<<< HEAD
Book 3: Dune
=======
Book 2: Harry Potter
>>>>>>> feature-books
This reads: "above the ======= is what main has, below is what the branch has." The friends sit together and agree on the real answer:
nano books.html
Make it:
Book 2: Harry Potter and Book 3: Dune
Then tell the librarian the conflict is solved:
git add books.html
git commit -m "Resolve books conflict"
[main 5f8d0e3] Resolve books conflict
cat books.html
git log --oneline
Book 2: Harry Potter and Book 3: Dune
5f8d0e3 (HEAD -> main) Resolve books conflict
a41b2cc Update books list
c2e8a77 Add login page
9b2c4d1 Create Campus Library homepage
Panic button — I want to start the merge over from scratch
git merge --abort
This undoes the merge attempt and puts everything back exactly as it was before you ran git merge.
Conflicts are normal and expected — they are not a failure. Git pauses and lets humans decide. The markers <<<<<<<, =======, >>>>>>> are just the librarian highlighting the disagreement.
Exercise 4 · Rebase — Straightening the Timeline
Now Kabir works on a feature while main moves forward. Instead of a fork in the road, he chooses rebase so history stays one clean line.
Set up: while on main, make two new commits:
nano index.html
Add a second line (anything):
<h1>Welcome to Campus Library</h1>
<p>Borrow in minutes.</p>
git add .
git commit -m "Add tagline"
nano books.html
Add a second line:
Book 2: Harry Potter and Book 3: Dune
Book 4: The Hobbit
git add .
git commit -m "Add more books"
Now create a feature branch based on an older state and commit there:
git checkout 9b2c4d1
Note: switching to '9b2c4d1'.
... you are in 'detached HEAD' state ...
This detached state means "I am standing in the past." Create a branch here and add a commit:
git switch -c feature-membership
nano membership.html
Write:
<h1>Membership</h1>
git add .
git commit -m "Add membership page"
Now the story is forked:
(new) feature-membership: b-commit
/
... A --- B --- C main
Time to make it straight. Rebase the feature onto the newest main:
git rebase main
Successfully rebased and updated refs/heads/feature-membership.
git log --oneline --graph
* 3f9a2c1 (HEAD -> feature-membership) Add membership page
* e4b7d22 Add more books
* c77fa30 Add tagline
* 5f8d0e3 Resolve books conflict
* a41b2cc Update books list
* c2e8a77 Add login page
* 9b2c4d1 Create Campus Library homepage
One straight line — the feature commit now sits on top of the newest main, exactly as if Kabir started yesterday.
The membership commit moved from the past onto the newest pages. Its hash changed — proof that rebase rewrites commits, which is why we never rebase shared history.
Exercise 5 · Time Travel — Restoring a Lost Page
Riya accidentally deleted login.html and committed her mistake. Can the team get it back? Of course — the librarian saved every version.
git rm login.html
git commit -m "Remove login page (oops)"
Find the commit that still had the page:
git log --oneline
a6d9902 (HEAD -> main) Remove login page (oops)
3f9a2c1 (feature-membership) Add membership page
...
The commit before the deletion — 5f8d0e3 — still contains login.html. Restore it from the past:
git checkout 5f8d0e3 -- login.html
ls
cat login.html
<h1>Login to Campus Library</h1>
The file is back on your desk (staged as a change). Commit the rescue:
git add .
git commit -m "Restore login page"
git checkout <hash> -- <file> restores a file from history. For undoing a whole commit safely, use git revert <hash> — it creates a new commit that undoes the old one, keeping history honest.
You Did It! Recap Checklist
- git init + config
- clone
- add + commit
- log + status
- branch + switch
- merge
- conflict resolution
- rebase
- checkout time travel
- stash + restore
- .gitignore
What to try next: put this repository on GitHub. Create an empty repo on GitHub, then:
git remote add origin https://github.com/YOUR-USERNAME/campus-library.git
git push -u origin main
That is the central library in the story — the moment your notebook is shared with the world. Welcome to Git!
Ready for the full challenge? Put every skill together in the Capstone — Ship Campus Library v1.0.
Check Your Understanding
No peeking at the sidebar — answer in your head, then click to reveal. If you miss one, revisit the page it links to.
1. What is the difference between git init and git clone?
Reveal answer
git init opens a new register for a brand-new project. git clone copies an existing notebook (with all its history) onto your computer. (commands)
2. Your edits are made but git commit saved nothing. What did you forget?
Reveal answer
git add . — pages must be placed on the librarian's desk (staged) before they can be committed. (commands → git add)
3. What does a branch protect you from?
Reveal answer
It gives you your own copy of the notebook so experiments can't break main. Main stays safe until you merge. (commands → branch)
4. Merge or rebase to straighten your own private history before pushing?
Reveal answer
Rebase — it replays your commits on top of the newest main in one clean line. But never rebase commits others already pulled. (workflows)
5. You see <<<<<<< HEAD in a file. What is happening?
Reveal answer
A merge conflict — two friends changed the same line. Git paused and is asking you to decide. Edit the file, git add it, and commit. (exercise 3)
6. You pushed a broken commit that teammates already pulled. Should you git reset --hard or git revert?
Reveal answer
git revert — it adds a new "take that back" commit without rewriting shared history. reset --hard would make your teammates' copies disagree. (undoing)
7. What is git stash used for?
Reveal answer
Sweeping half-finished, uncommitted work into a drawer so you can switch branches, then bringing it back with git stash pop. (undoing)
8. node_modules/ keeps showing up in git status. How do you silence it?
Reveal answer
Add it to a .gitignore file — the scraps drawer the librarian never glues into the notebook. (commands → .gitignore)
9. What does the scary "detached HEAD" message actually mean?
Reveal answer
You're standing on a past commit with no branch name on your notebook. Nothing is lost — run git switch main (or create a branch) to get back safely. (troubleshooting)
10. Riya wants to mark the finished project as version 1.0 forever. What does she use?
Reveal answer
git tag v1.0 — a golden milestone sticky note on that commit. (tags & releases)