All Git Exercises
Create a Git repository and make your first commit
Description: Create a folder named my-notes, make it a Git repository, create a file notes.txt with some text, and save it in a first commit with the message “Add notes”.
Hint:
- Use
git initinside the folder. - A file must be staged with
git addbefore the commit.
Solution
$ mkdir my-notes
$ cd my-notes
$ git init
Initialized empty Git repository in /home/robin/my-notes/.git/
$ echo "My first note" > notes.txt
$ git add notes.txt
$ git commit -m "Add notes"
[main (root-commit) 6927e03] Add notes
1 file changed, 1 insertion(+)
create mode 100644 notes.txt
$ git log –oneline
6927e03 (HEAD -> main) Add notes
How it works
git initcreates the hidden.gitfolder, which makes the folder a repository.git addstages the file, andgit commit -msaves it with the message.git log --onelineshows the new commit.
Read Git Init and Git Commit.
Check the status of files in a Git repository
Description: In a repository, create two files a.txt and b.txt, stage only a.txt, and show the status in the short format.
Hint:
- Use
git status -sfor the short format.
Solution
$ mkdir status-demo
$ cd status-demo
$ git init -q
$ echo "a" > a.txt
$ echo "b" > b.txt
$ git add a.txt
$ git status -s
A a.txt
?? b.txt
How it works
Ain the first column meansa.txtis staged (added).??meansb.txtis untracked.
Read Git Status.
Stage only selected files and commit them separately
Description: You changed index.html, about.html and style.css. Make two commits: one with the two html files and one with only the css file.
Hint:
- Stage the html files first with a pattern, commit, then stage the css file.
Solution
$ git add *.html
$ git commit -m "Update html pages"
[main 3f16559] Update html pages
2 files changed, 2 insertions(+), 2 deletions(-)
$ git add style.css
$ git commit -m "Update style"
[main 3ce526e] Update style
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log –oneline
3ce526e (HEAD -> main) Update style
3f16559 Update html pages
333d1be Start
How it works
- The staging area lets us choose which files go in a commit.
- Two small commits are easier to review than one big commit.
Read Git Add.
Show the commit history in one line per commit
Description: Show the history of a repository with one line per commit, and then show only the last 2 commits.
Hint:
- Use
--onelineand the option-n(or-2).
Solution
$ git log –oneline
a9b08d4 (HEAD -> main) Update file again
f95aab8 Update file
ad07eb3 Add file
$ git log –oneline -2
a9b08d4 (HEAD -> main) Update file again
f95aab8 Update file
How it works
--onelineshows the short hash and the title of each commit.-2limits the output to two commits.
Read Git Log.
See the changes of a file before staging and before commit
Description: Change a line in a tracked file. Show the change before staging, then stage the file and show the staged change.
Hint:
- Plain
git diffshows unstaged changes, and--stagedshows staged changes.
Solution
$ printf "Tea\nMilk\n" > drinks.txt
$ git diff
diff –git a/drinks.txt b/drinks.txt
index 345af57..4227ee2 100644
— a/drinks.txt
+++ b/drinks.txt
@@ -1,2 +1,2 @@
Tea
-Coffee
+Milk
$ git add drinks.txt
$ git diff
$ git diff –staged
diff –git a/drinks.txt b/drinks.txt
index 345af57..4227ee2 100644
— a/drinks.txt
+++ b/drinks.txt
@@ -1,2 +1,2 @@
Tea
-Coffee
+Milk
How it works
- Lines with
-are removed and lines with+are added. - After
git add, plaingit diffis empty, because there is no unstaged change.
Read Git Diff.
Ignore all .log files with .gitignore
Description: Create debug.log, app.js and a folder build with a file inside. Make Git ignore all .log files and the build folder.
Hint:
- Write the patterns
*.logandbuild/in a file named.gitignore.
Solution
$ mkdir ignore-demo
$ cd ignore-demo
$ git init -q
$ echo "log" > debug.log
$ echo "code" > app.js
$ mkdir build
$ echo "out" > build/out.js
$ printf "*.log\nbuild/\n" > .gitignore
$ git status -s
?? .gitignore
?? app.js
$ git check-ignore -v debug.log
.gitignore:1:*.log debug.log
How it works
- Only
.gitignoreandapp.jsare shown. The log file and the build folder are hidden from Git. git check-ignore -vtells which rule matched.
Read Git Ignore.
Create a new branch and switch to it
Description: Create a branch named feature-login, move to it, add a file login.html and commit it. Then show all branches.
Hint:
git switch -ccreates a branch and moves to it.
Solution
$ git switch -c feature-login
Switched to a new branch 'feature-login'
$ echo "login" > login.html
$ git add login.html
$ git commit -m "Add login page"
[feature-login 001dfd4] Add login page
1 file changed, 1 insertion(+)
create mode 100644 login.html
$ git branch
* feature-login
main
How it works
- The new branch starts from the commit where you were, so it has all the old files.
- The new commit belongs only to
feature-login, andmainis not changed.
Read Git Branch and Git Checkout and Switch.
Merge a feature branch into main
Description: You have finished the work on feature-search. Merge it into main and show the history.
Hint:
- Move to the target branch (
main) first, then rungit merge.
Solution
$ git switch main
Switched to branch 'main'
$ git merge feature-search
Updating a17f7f4..d37f093
Fast-forward
search.html | 1 +
1 file changed, 1 insertion(+)
create mode 100644 search.html
$ git log –oneline
d37f093 (HEAD -> main, feature-search) Add search page
a17f7f4 Add home
How it works
mainhad no new commits, so Git made a fast-forward merge and moved the pointer.- After the merge, the branch
feature-searchcan be deleted.
Read Git Merge.
Resolve a merge conflict
Description: Both main and feature changed the first line of title.txt. Merge feature into main and solve the conflict by keeping the text “Learn Git Fast”.
Hint:
- Edit the file to the final text, remove the markers, then
git addandgit commit.
Solution
$ git merge feature
Auto-merging title.txt
CONFLICT (content): Merge conflict in title.txt
Automatic merge failed; fix conflicts and then commit the result.
$ cat title.txt
<<<<<<< HEAD
Learn Git Easily
=======
Learn Git Quickly
>>>>>>> feature
$ echo "Learn Git Fast" > title.txt
$ git add title.txt
$ git commit -m "Merge feature and solve conflict"
[main b4f0e8e] Merge feature and solve conflict
$ git status
On branch main
nothing to commit, working tree clean
How it works
- Git stops the merge and writes the markers in the file.
- We replaced the file content with the final text, so no markers are left.
git addtells Git the conflict is solved, and the commit finishes the merge.
Read Git Merge Conflict.
Delete a merged branch
Description: The branch feature-menu is merged into main. Show the merged branches and delete it.
Hint:
git branch --mergedlists merged branches.-dis the safe delete.
Solution
$ git branch –merged
feature-menu
* main
$ git branch -d feature-menu
Deleted branch feature-menu (was cda1bfa).
$ git branch
* main
How it works
- The safe delete
-dworks only when the branch is merged. Otherwise Git refuses. - The commit is not lost, because it is already part of
main.
Read Git Branch.
Rename a local branch
Description: Rename the branch fix-hedaer (a spelling mistake) to fix-header.
Hint:
- Use
git branch -m old new.
Solution
$ git branch -m fix-hedaer fix-header
$ git branch
fix-header
* main
How it works
-mmeans move (rename). Only the name changes, not the commits.- If the branch was pushed, push the new name and delete the old name on the remote.
Read Git Branch.
Unstage a file
Description: You staged secret.txt by mistake. Remove it from the staging area, but keep the file.
Hint:
- Use
git restore --staged.
Solution
$ git status -s
A secret.txt
$ git restore –staged secret.txt
$ git status -s
?? secret.txt
$ ls
app.txt
secret.txt
How it works
A(staged) changes to??(untracked), and the file stays in the folder.- Add the file to
.gitignoreso this does not happen again.
Read Git Restore.
Discard the changes of a file
Description: You edited config.txt and broke it. Discard your edit and get the last saved version back.
Hint:
- Use
git restore file. It cannot be undone, so be sure.
Solution
$ git status -s
M config.txt
$ git restore config.txt
$ git status -s
$ cat config.txt
theme=light
How it works
- The file is replaced with the version from the last commit.
- Changes that were never committed are lost, Git cannot bring them back.
Read Git Restore.
Undo the last commit but keep the changes
Description: You committed too early. Undo the last commit, but keep your changes ready in the staging area.
Hint:
HEAD~1means one commit beforeHEAD.
Solution
$ git reset –soft HEAD~1
$ git log –oneline
2875ee0 (HEAD -> main) First
$ git status -s
M f.txt
How it works
- The branch moves back one commit, and the commit “Second” is gone from the history.
Mshows that the change is still staged, so you can finish your work and commit again.
Read Git Reset.
Revert a commit with git revert
Description: The commit “Add debug page” was a mistake, and it is already pushed. Undo it without changing the history.
Hint:
- Use
git revertwith--no-editto accept the default message.
Solution
$ git revert HEAD~1 –no-edit
[main a51ba50] Revert "Add debug page"
Date: Sat Jan 10 11:31:00 2026 +0000
1 file changed, 1 deletion(-)
delete mode 100644 debug.txt
$ git log –oneline
a51ba50 (HEAD -> main) Revert "Add debug page"
27e27e3 Add about page
f5f5ec5 Add debug page
95d0194 Add home page
$ ls
about.txt
home.txt
How it works
- Git made a new commit which removes
debug.txt. - The old commits are still in the history, so it is safe for shared branches.
Read Git Revert.
Fix the message of the last commit
Description: The last commit message is “Add contcat page”. Change it to “Add contact page”.
Hint:
- Use
git commit --amend -m.
Solution
$ git log –oneline
0e698a4 (HEAD -> main) Add contcat page
$ git commit –amend -m "Add contact page"
[main 6e54967] Add contact page
Date: Sat Jan 10 10:42:00 2026 +0000
1 file changed, 1 insertion(+)
create mode 100644 contact.html
$ git log –oneline
6e54967 (HEAD -> main) Add contact page
How it works
- Amend replaces the last commit with a new commit, so the hash changes.
- Do not amend a commit that is already pushed and used by others.
Read Git Commit Amend.
Stash your changes and bring them back
Description: You edited app.txt but must switch tasks. Put the changes aside, check that the folder is clean, and then bring the changes back.
Hint:
- Use
git stashandgit stash pop.
Solution
$ echo "half done" >> app.txt
$ git stash
Saved working directory and index state WIP on main: 6b3a366 Add app
$ git status -s
$ 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: app.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (0aac64f7d5bb638391472f0c078c4e2ca0506864)
$ cat app.txt
v1
half done
How it works
- After
git stashthe folder is clean, so you can switch branches. git stash popapplies the changes again and removes the stash entry.
Read Git Stash.
Create an annotated tag for a release
Description: Mark the latest commit as version v1.0 with the message “First release”. Show all tags and the details of the tag.
Hint:
- Use
git tag -awith-m.
Solution
$ git tag -a v1.0 -m "First release"
$ git tag
v1.0
$ git show v1.0 –no-patch
tag v1.0
Tagger: Robin Sharma <robin@example.com>
Date: Sat Jan 10 10:49:00 2026 +0000
First release
commit 378ffde0b81bbd9da251867b0d52884f32d49425 (HEAD -> main, tag: v1.0)
Author: Robin Sharma <robin@example.com>
Date: Sat Jan 10 10:42:00 2026 +0000
Add app
How it works
- An annotated tag stores the tagger, date and message.
- Tags are not pushed by
git push. Usegit push origin v1.0.
Read Git Tag.
Clone a repository, make a change and push it
Description: Clone the repository server.git into a folder my-work, add a file todo.txt, commit it and push it to the remote.
Hint:
- A clone already has the remote
origin, so a plaingit pushis enough.
Solution
$ git clone server.git my-work
Cloning into 'my-work'…
done.
$ cd my-work
$ echo "buy milk" > todo.txt
$ git add todo.txt
$ git commit -m "Add todo list"
[main 9eaf666] Add todo list
1 file changed, 1 insertion(+)
create mode 100644 todo.txt
$ git push
To /home/robin/server.git
4f5618b..9eaf666 main -> main
How it works
- We used a local folder as the server. A GitHub URL works in the same way.
- The last line shows that
mainwas pushed to the remotemain.
Get new changes from the remote with fetch and pull
Description: A teammate pushed a new commit. First check the new commits without changing your branch, and then update your branch.
Hint:
git fetchdownloads without merging.git pulldownloads and merges.
Solution
$ git fetch
From /home/robin/server
0f2bd93..66c2a05 main -> origin/main
$ git log HEAD..origin/main –oneline
66c2a05 (origin/main, origin/HEAD) Mate adds a file
$ git pull
Updating 0f2bd93..66c2a05
Fast-forward
mate.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 mate.txt
$ ls
app.txt
mate.txt
How it works
- After the fetch, the commit is known as
origin/main, but our branch did not move. git pullthen merged it (a fast-forward), and the new file is in our folder.
Read Git Fetch and Pull.