Version Control with Git
Authors
Writing code is often not a linear process, involving exploration, tinkering, and trial-and-error. Without the right tools, this can result in a messy codebase with multiple, slightly modified versions of the same code, making it hard to understand, maintain and reproduce the project. Version control systems provide a solution for this: They record snapshots of your project at different points in time, which allows you to see what changed and why and to revert to previous versions of your code if needed.
Git is a distributed version control system and it is by far the most popular one with an adoption rate of over 90% in the software industry. In this lesson, you’ll learn the basics of Git: how to track changes, view the project’s history and restore old versions.
The materials feature two different ways of using Git: the terminal and VS Code’s graphical user interface (GUI). It is recommended that you test out both methods because they each have their distinct advantages: The GUI provides a convenient interface that makes it easier to integrate Git into your workflow while the terminal allows you to use more advanced functionalities of Git that are not implemented in the GUI.
If you haven’t installed Git already, go to the website, download the installer for your operating system and follow the instructions (there are a lot of options in the installation - you can accept the defaults). Then run the following commands in your terminal (replacing the text in quotations with your actual name and email address) so Git can associate your commits with your identity.
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"Section 1: Tracking Files with Git
Background
With Git, you create regular snapshots of your project files and save them in the version control system. This is a two-step process: first, you add files from your working directory to the staging area, then you commit all changes in the staging area to the repository where they are stored permanently.
The two-step process allows you to define exactly what goes into every snapshot. In a typical workflow, you stage any change you make to the files in the temporary staging area and once you are happy with the changes you have made, you commit them. The points where you stage and commit are up to you. Ideally, every snapshot reflects one unit of work, such as adding data, editing a script or creating a figure, and has a message that identifies the purpose of the commit. This gives you a history that is easy to read, understand, and undo if required.
Note that Git can only see your changes once they have been saved. In VS Code, if you have made a change to a file but haven’t saved it yet, there will be a white dot next to the filename in the tab in the editor (see red line in the screenshot below). For Git to detect the change, you need to save by pressing Ctrl + S (or Cmd + S on a Mac keyboard) or enable “Auto Save” via the “File” menu in the top left corner of VS Code.
Exercises
In this section, you are going to create your first git repository, add files to it and track their changes. Below is a table with the required commands that can be run in the terminal. There are also instructions for the same operations in the graphical interface of VS Code (other editors have similar interfaces). You can switch between both approaches as you like.
| Code | Description | VS Code GUI |
|---|---|---|
git init |
Initialize a new Git repository in the current directory | Click Source Control (Ctrl + Shift + G) → Click “Initialize Repository” |
git status |
Show the status of changes in the working directory | Click Source Control (Ctrl + Shift + G) → See the file changes |
git add file1.txt |
Stage file1.txt for commit |
Click ➕ (plus) icon next to the file in Source Control |
git add . |
Stage all modified and new files | Click ➕ (plus) icon next to each file OR Click “Stage All Changes” |
git commit -m "<message>" |
Commit staged files with a message | Click ✔ (checkmark) icon, enter commit message, and press Enter |
git commit -am "<message>" |
Stage and commit all modified files in one step | Click “Stage All Changes”, then ✔ (checkmark) icon |
First, create a new, empty folder and open it in VS Code or do it in the terminal:
mkdir /tmp/new_repo # create directory
cd /tmp/new_repo # change working directory/tmp/new_repoExercise: Initialize a new Git repository in this folder.
Solution
git initInitialized empty Git repository in /tmp/new_repo/.git/Exercise: Check the status of the repository - there should be nothing to commit yet.
Solution
git statusOn branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)Example: Create a new file called experiment_1.txt with any content and add it to the staging area.
# after creating experiment_1.txt:
git add experiment_1.txtExercise: Create experiment_2.txt and experiment_3.txt and stage both files.
Solution
# after creating experiment_2.txt and experiment_3.txt:
git add .Exercise: Commit the staged changes and add a message like "Add data from experiments".
Solution
git commit -m "Add data from experiments"[main (root-commit) d97c96c] Add data from experiments
3 files changed, 3 insertions(+)
create mode 100644 experiment_1.txt
create mode 100644 experiment_2.txt
create mode 100644 experiment_3.txtMake a change to experiment_1.txt and check the status - it should show you a modified file.
Solution
# after modifying experiment_1.txt:
git statusOn 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: experiment_1.txt
no changes added to commit (use "git add" and/or "git commit -a")
Exercise: Add and commit the change (Hint: in the terminal, you can use commit -am to add and commit in one go.). Check the status to confirm there are no untracked changes.
Solution
#After modifying experiment_1.txt:
git commit -am "Add data to experiment 1"
git status[main 53d0862] Add data to experiment 1
1 file changed, 2 insertions(+)
On branch main
nothing to commit, working tree cleanExercise: Make changes to experiment_2.txt and experiment_3.txt and save them in a single commit. Check the status whenever you need to.
Solution
#After modifying experiment_2.txt and experiment_3.txt:
git status
git add .
git status
git commit -m "New data for experiments 2 & 3"
git statusOn branch main nothing to commit, working tree clean On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: experiment_2.txt modified: experiment_3.txt
[main 6f6bedb] New data for experiments 2 & 3
2 files changed, 2 insertions(+)
On branch main
nothing to commit, working tree cleanExercise: Delete experiment_3.txt, check the status and commit the change.
Solution
# after deleting experiment_3.txt:
git status
git commit -am "Delete experiment 3"On branch main
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: experiment_3.txt
no changes added to commit (use "git add" and/or "git commit -a")
[main 471695c] Delete experiment 3
1 file changed, 2 deletions(-)
delete mode 100644 experiment_3.txtSection 2: Inspecting the Commit History
Background
Commits are saved in order, creating a history of changes in the project. You can see past commits using git log or in the “Graph” panel of VS Code’s “Source Control” interface. Each entry contains a unique identifier (hash), a message as well as the time and author of the commit so you know who did what when.
The commit history also allows us to compare specific commits with git diff. The diff algorithm compares two files line-by-line to tell us exactly what has changed. We can select commits for git diff in two ways: either by using the commit hash or by the position of the commit relative to the most recent commit called HEAD (for example, HEAD~1 refers to the second most recent commit). Note that the commit hashes are unique for every repository so the ones you’ll see in the exercises and solutions in this notebook will not match the ones you’ll see on your machine.
Exercises
In this section, you’ll start by inspecting the commit history of your project. You’ll then use diff and compare specific commits to see what has changed. Some of these operations can be executed via the terminal and VS Code’s graphical interface while others are terminal only.
| Code | Description | VS Code GUI |
|---|---|---|
git log |
View the full commit history of the repository | Expand the Graph in Source Control |
git log --oneline |
View a compact version of the commit history | N/A (terminal only) |
git log -2 |
Display the last two commits | N/A (terminal only) |
git diff a1b2c3d |
Compare the working directory to the commit with the hash a1b2c3d |
Click on the file in Source Control and check the inline diff |
git diff HEAD~1 |
Compare the working directory to the second most recent commit | Click on the file in Source Control and check the inline diff |
git diff HEAD~3 HEAD~2 |
Compare the third and second most recent commits | N/A (terminal only) |
git diff <commit1> <commit2> |
Compare two specific commits (the older commit goes first) | N/A (terminal only) |
Exercise: View the full commit history of the repository.
Solution
git logcommit 471695c1322b7286449b25dcab795852b3abbed1 (HEAD -> main) Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:53:18 2026 +0200 Delete experiment 3 commit 6f6bedb37a946a29ec3624caf3c17ecaafb01763 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:51:18 2026 +0200 New data for experiments 2 & 3 commit 53d0862ad4154a537807b877f9f8b50678886e77 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:51:11 2026 +0200 Add data to experiment 1 commit d97c96cc4a8c23e93524fffe8b31435342dfa100 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:49:59 2026 +0200 Add data from experiments
Exercise: Check your commit history, find the second most recent commit and copy its hash.
Solution
git log -2commit 471695c1322b7286449b25dcab795852b3abbed1 (HEAD -> main) Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:53:18 2026 +0200 Delete experiment 3 commit 6f6bedb37a946a29ec3624caf3c17ecaafb01763 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:51:18 2026 +0200 New data for experiments 2 & 3
Exercise: Use the hash from the previous exercise to compare the commit to the working directory.
Solution
git diff a1b2c3ddiff --git a/experiment_3.txt b/experiment_3.txt deleted file mode 100644 index 6e1ddff..0000000 --- a/experiment_3.txt +++ /dev/null @@ -1,2 +0,0 @@ -This is the 3rd experiment -There are 4 conditions
Exercise: Compare the same commit to the working directory using HEAD~1.
Solution
git diff HEAD~1 # alternatively, use the commit hashdiff --git a/experiment_3.txt b/experiment_3.txt deleted file mode 100644 index 6e1ddff..0000000 --- a/experiment_3.txt +++ /dev/null @@ -1,2 +0,0 @@ -This is the 3rd experiment -There are 4 conditions
Exercise: Compare the differences between the third-most-recent commit and the working directory using HEAD or the hash.
Solution
git diff HEAD~2 # alternatively, use the commit hashdiff --git a/experiment_2.txt b/experiment_2.txt index bfa0eae..72b7631 100644 --- a/experiment_2.txt +++ b/experiment_2.txt @@ -1 +1,2 @@ This is the 2nd experiment +There are 2 conditions diff --git a/experiment_3.txt b/experiment_3.txt deleted file mode 100644 index ea480b1..0000000 --- a/experiment_3.txt +++ /dev/null @@ -1 +0,0 @@ -This is the 3rd experiment
Exercise: Compare two specific commits.
Solution
git diff HEAD~3 HEAD~2 # alternatively, use the commit hashesdiff --git a/experiment_1.txt b/experiment_1.txt index e9d916c..f6bbf50 100644 --- a/experiment_1.txt +++ b/experiment_1.txt @@ -1 +1,3 @@ This is the 1st experiment +There are 3 conditions +aaa
Section 3: Reverting and Undoing Changes
Background
Because Git keeps the full history of all files, it allows you to go back to a previous version of your work if needed. You can run git checkout <commit> to set your repository to the exact state of that commit. This puts you in a “detached HEAD” state - this may sound scary but it simply means Git is no longer remembering new commits as part of your normal project history. This means that the detached HEAD state is useful for inspecting and experimenting with old commits but not for committing new work. To return to the latest commit on your default branch, use git checkout main or git checkout master, depending on the branch name in your repository.
You can also restore older commits permanently by using git reset. There are different reset modes: --soft and --hard. With a soft reset, you are keeping all modifications that happened after the reset point as staged changes in your working directory. With a hard reset, you immediately lose all modifications after the reset point which makes the operation dangerous. Resets can also be problematic in shared repositories because rewriting the git history can cause problems for your collaborators.
Another way of restoring older commits is git revert. Instead of removing changes, revert creates a new commit that undoes the changes made by the given commit. This is safer because it keeps the commit history intact. The downside is that reverts may cause merge conflicts. If you are trying to undo a line that has been modified again in later commits, Git does not know what to do. Should it undo the requested commit as well as the later one or keep the later one and ignore the revert? In these cases, Git will warn you about a merge conflict which means that you have to select manually what to keep and what to drop.
Exercises
In this section, you’ll start by using git checkout to inspect older versions of your repository and then use git reset and git revert to restore those older versions.
Because most of these operations are not exposed by VS Code’s graphical interface, you’ll have to use the terminal. Here are the relevant commands:
| Command | Description |
|---|---|
git checkout HEAD~1 |
“Rewind one step”: Update the working directory to match the second latest commit. |
git checkout <commit> |
“Jump to a specific commit”: Update the working directory to match the given <commit>. |
git checkout main |
Return to the latest commit on the main branch. Use master instead if that is your default branch name. |
git reset --soft <commit> |
Rewind the history to commit hash <commit>, keeping all changes after in the staging area (dangerous in shared repos). |
git reset --hard <commit> |
Rewind the history to commit hash <commit>, dumping all commits made afterward (dangerous in shared repos) |
git revert <commit> |
Make a new commit to undo the given <commit> (great in shared repos). |
Exercise: Check the last entry in your commit history, then use git checkout HEAD~1 to update the working directory to the second latest commit and check the commit history again.
Solution
git log -3 --oneline
git checkout HEAD~1
git log -3 --oneline471695c (HEAD -> main) Delete experiment 3 6f6bedb New data for experiments 2 & 3 53d0862 Add data to experiment 1 Note: switching to 'HEAD~1'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at 6f6bedb New data for experiments 2 & 3 6f6bedb (HEAD) New data for experiments 2 & 3 53d0862 Add data to experiment 1 d97c96c Add data from experiments
Exercise: Use git checkout main (or git checkout master) to move the working directory back to the most recent commit on your default branch and check the commit history.
Solution
git checkout main # use master instead if that is your default branch
git log -3 --onelinePrevious HEAD position was 6f6bedb New data for experiments 2 & 3 Switched to branch 'main' 471695c (HEAD -> main) Delete experiment 3 6f6bedb New data for experiments 2 & 3 53d0862 Add data to experiment 1
Exercise: Check the commit history, pick a commit from the past and checkout to that commit. Explore the files to see how the repository looked at that time. When you are done, checkout to the most recent commit on your default branch again.
Solution
git checkout HEAD~3 # or use the commit hash
# after exploring the files:
git checkout main # use master instead if that is your default branchNote: switching to 'HEAD~3'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at d97c96c Add data from experiments
Previous HEAD position was d97c96c Add data from experiments
Switched to branch 'main'Exercise: Undo the latest commit using git revert HEAD. This may open the text editor VIM to edit your commit message. To exit VIM, press Esc, type :wq (w for write, q for quit) and hit Enter.
Solution
git revert HEAD[main a0fc378] Revert "Delete experiment 3"
Date: Thu Jun 4 12:54:20 2026 +0200
1 file changed, 2 insertions(+)
create mode 100644 experiment_3.txtExercise: Check the commit history to view the entry made by revert. Then run git revert HEAD again to undo the undoing of the previous commit.
Solution
git log -1
git revert HEADcommit a0fc3786da341621aed4d46f1ccd1a76b541f581 (HEAD -> main) Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:54:20 2026 +0200 Revert "Delete experiment 3" This reverts commit 471695c1322b7286449b25dcab795852b3abbed1. [main 6c89aee] Reapply "Delete experiment 3" Date: Thu Jun 4 12:54:29 2026 +0200 1 file changed, 2 deletions(-) delete mode 100644 experiment_3.txt
Exercise: Check the commit history to view the entry made by revert. Then run git revert HEAD again to undo the undoing of the previous commit and check the history again.
Solution
git log -1
git revert HEAD
git log -2commit 6c89aee6255469f46d72ebeb6355ac9aa007553c (HEAD -> main) Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:54:29 2026 +0200 Reapply "Delete experiment 3" This reverts commit a0fc3786da341621aed4d46f1ccd1a76b541f581. [main 8c77a0b] Revert "Reapply "Delete experiment 3"" Date: Thu Jun 4 12:54:32 2026 +0200 1 file changed, 2 insertions(+) create mode 100644 experiment_3.txt commit 8c77a0bff80f8b26110436978143a6277a08b5c0 (HEAD -> main) Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:54:32 2026 +0200 Revert "Reapply "Delete experiment 3"" This reverts commit 6c89aee6255469f46d72ebeb6355ac9aa007553c. commit 6c89aee6255469f46d72ebeb6355ac9aa007553c Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:54:29 2026 +0200 Reapply "Delete experiment 3" This reverts commit a0fc3786da341621aed4d46f1ccd1a76b541f581.
Exercise: Pick a commit from the past and use git reset --soft to reset the repository to that state. Then, check git status - you should see the modifications that happened after the reset point as staged changes. Commit the staged changes again.
Solution
git reset --soft HEAD~2
git status
git add .
git commit -m "re-commit after soft reset"On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: experiment_2.txt modified: experiment_3.txt
[main 5aabcbe] re-commit after soft reset
2 files changed, 2 insertions(+)Exercise: Pick a commit from the past and use git reset --hard to reset the repository to that state. Then, check git status - you should not see any changes because the modifications after the reset point have been dropped.
Solution
git reset --hard HEAD~2
git statusHEAD is now at d97c96c Add data from experiments
On branch main
nothing to commit, working tree cleanSection 4: Ignoring Files
Background
By default, Git tracks every file in the directory. However, some files and folders should not be tracked. For example, Git is not intended to be used for large files, so you should not let Git track your neural recordings. To prevent Git from tracking specific files, we can create a file called .gitignore and add the to-be-ignored files. .gitignore is simply a text file where you can either list individual files or patterns such as *.pdf or subject*, which mean “ignore every file/folder ending with .pdf or starting with subject”. There are also .gitignore generators that provide ready-made templates with files and patterns that are commonly ignored for a given language.
Importantly, adding a file to .gitignore that is already tracked by Git will not automatically make Git drop it. To do this, you need to call git rm --cached <file> which will remove it from Git’s index but keep it as a file in your working directory. While Git will ignore changes in this file going forward, it will not remove it from the commit history so it can still be restored later.
Note that editing .gitignore and running git rm --cached are changes that need to be committed to be effective.
Exercises
In the following exercises you will create a .gitignore file, add files to ignore and observe how this affects Git’s behavior. Here are the commands you need to know:
| Code | Description | VS Code GUI |
|---|---|---|
git status |
Show the status of changes in the working directory | Click Source Control (Ctrl + Shift + G) → See the file changes |
git add f1.txt f2.txt |
Stage specific files for commit | Click ➕ (plus) icon next to the files in Source Control |
git add . |
Stage modifications of all files | Click ➕ (plus) icon next Changes |
git commit -m "Commit message" |
Commit staged files with a message | Click ✔ (checkmark) icon, enter commit message, and press Enter |
git commit -am "Commit message" |
Stage and commit all modified files in one step | Click “Stage All Changes”, then ✔ (checkmark) icon |
git rm --cached <file> |
Remove the file from Git’s index | N/A (command line only) |
Exercise: Create the .gitignore file in your folder and add experiment_4.txt to it. Then stage and commit the file.
Solution
# after creating .gitignore and adding experiment_4.txt:
git add .
git commit -m "add .gitignore"[main 09d1502] add .gitignore
1 file changed, 1 insertion(+)
create mode 100644 .gitignoreExercise: Create experiment_4.txt and check git status. You should not see any untracked changes because the file should be ignored.
Solution
git statusOn branch main
nothing to commit, working tree cleanExercise: Add *.txt to .gitignore to ignore all text files and commit.
Solution
# after adding *.txt to .gitignore
git commit -am "ignore all text files"[main e295f6c] ignore all text files
1 file changed, 1 insertion(+), 1 deletion(-)Example: Use git rm --cached to remove experiment_1.txt from Git’s index but keep it in your working directory and commit.
Solution
git rm --cached experiment_1.txt
git commit -am "rm experiment_1.txt"rm 'experiment_1.txt'
[main fc5f115] rm experiment_1.txt
1 file changed, 1 deletion(-)
delete mode 100644 experiment_1.txtExercise: Use git rm --cached to remove experiment_2.txt from Git’s index but keep it in your working directory and commit.
Solution
git rm --cached experiment_2.txt
git commit -am "rm experiment_2.txt"rm 'experiment_2.txt'
[main e4edd72] rm experiment_2.txt
1 file changed, 1 deletion(-)
delete mode 100644 experiment_2.txtExercise: Modify experiment_2.txt and check git status - it should not show any changes.
Solution
git statusOn branch main
nothing to commit, working tree cleanSection 5: Bonus: Working with Branches
Background
When experimenting with code, we usually want to avoid breaking the project. Git branches are great for this - they allow you to create a separate copy of your repository that can be modified without affecting anything else. When a repository is initialized, Git creates a single default branch called main (or master in older versions) but you can create additional branches using the git branch command. The working directory always shows the currently selected branch which is shown in the VS Code GUI next to the repository name or when you call git status. When you switch branches with git checkout your working directory will change to the new branch.
If you made commits to a new branch that you want to incorporate into your main branch you can merge the branches. This is a typical workflow for collaborative coding: everyone creates their own branch off the default branch, makes their commits and then (after review) merges them back.
Git creates a new commit for every merge that contains the entire commit history of the merged branch. A useful variant is git merge --squash which treats all commits in the merged branch as a single commit. This is nice when you experimented on a side branch, made a bunch of commits and want to avoid cluttering the git history with them.
Exercises
In this bonus section you are going to create new branches in your repository, edit those branches and then merge them into main or master. You can do this via the terminal or using the branch menu in VS Code’s graphical interface (see screenshot below).
If you are working in the terminal and merge a branch without adding a message with -m the terminal may open the editor Vim where you can edit the default message.
To exit Vim press Esc, type :wq (write + quit) and hit enter.
| Command | Description | VS Code GUI |
|---|---|---|
git branch |
List the branches in the repo (active one has a star by it) | Source Control -> click on the current branch |
git branch <name> |
Make a new branch from the current commit, named <name> |
Branches -> Create Branch … (VS Code immediately switches to the new branch) |
git branch -d <name> |
Delete the branch <name> and all the commits with it. |
Branches -> Delete Branch … |
git branch -D <name> |
Delete the branch <name> and all the commits with it, even if they aren’t merged somewhere else already. |
Branches -> Delete Branch … and confirm |
git checkout <name> |
Switch the working directory to the specified branch. | Source Control -> click on the current branch -> select another one |
git merge <name> |
Merge the commits from the branch <name> into the current branch. |
Branches -> Merge … |
git merge --squash <name> |
Stage the combined changes from the branch <name> as one commit in the current branch. |
N/A (terminal only) |
Exercise: Create a tracked Markdown file called notes.md that you can modify on different branches.
Solution
echo "# Project notes" > notes.md
git add notes.md
git commit -m "Add project notes"[main a763c0b] Add project notes
1 file changed, 1 insertion(+)
create mode 100644 notes.mdExercise: Create a new branch called feature1 and switch to that branch. Confirm you are on feature1 by checking git status or the Source Control panel in VS Code.
Solution
git branch feature1
git checkout feature1
git statusSwitched to branch 'feature1'
On branch feature1
nothing to commit, working tree cleanExercise: Make at least two commits to feature1.
Solution
# after modifying notes.md:
git commit -am "Update project notes"
git commit -am "Update project notes again"[feature1 131f4e8] Update project notes
1 file changed, 1 insertion(+)
[feature1 41624f9] Update project notes again
1 file changed, 1 insertion(+)Exercise: Switch back to main (might also be called master) and merge feature1. Check the commit history to confirm your default branch contains the commits from feature1.
Solution
git checkout main # use master instead if that is your default branch
git merge feature1
git log -3Switched to branch 'main' Merge made by the 'ort' strategy. notes.md | 2 ++ 1 file changed, 2 insertions(+) commit bb8ee1aa10939798c6a62fd20f30f34cdf425113 (HEAD -> main) Merge: a763c0b 41624f9 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:56:59 2026 +0200 merge feature1 into default branch commit 41624f9335d04f248edf6abffa185426650d4975 (feature1) Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:56:57 2026 +0200 Update project notes again commit 131f4e86859f12fc534f3cc47aa47bc2d4a761a7 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:56:57 2026 +0200 Update project notes
Exercise: Delete the branch feature1.
Solution
git branch -d feature1Deleted branch feature1 (was 41624f9).Exercise: Switch to a new branch feature2 and make at least two commits to that branch.
Solution
git branch feature2
git checkout feature2
# after modifying notes.md:
git commit -am "Update notes on feature2"
# after another change:
git commit -am "Update notes on feature2 again"Switched to branch 'feature2'
[feature2 dab5de7] Update notes on feature2
1 file changed, 1 insertion(+)
[feature2 2fb43ec] Update notes on feature2 again
1 file changed, 1 insertion(+)Exercise: Switch back to main (or master) and merge feature2 with --squash. Then, check the commit history - you should only see a single commit for the merge.
Solution
git checkout main # use master instead if that is your default branch
git merge --squash feature2
git commit -m "squash merge feature2 into default branch"
git log -3Switched to branch 'main' Updating bb8ee1a..2fb43ec Fast-forward Squash commit -- not updating HEAD notes.md | 2 ++ 1 file changed, 2 insertions(+) [main 4cfb798] squash merge feature2 into default branch 1 file changed, 2 insertions(+) commit 4cfb7980a0d70a461282dcf3bede8d8a93da416e (HEAD -> main) Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:57:19 2026 +0200 squash merge feature2 into default branch commit bb8ee1aa10939798c6a62fd20f30f34cdf425113 Merge: a763c0b 41624f9 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:56:59 2026 +0200 merge feature1 into default branch commit 41624f9335d04f248edf6abffa185426650d4975 Author: obi <ole.bialas@posteo.de> Date: Thu Jun 4 12:56:57 2026 +0200 Update project notes again