Exercises

Here is a collection of hands-on exercises to complement the chapters in the Version Control Book. These exercises can be used flexibly throughout a course about Git but also when you are learning on your own.

Instructions

You can view the exercises by clicking on the boxes in the individual sections that correspond to one of the chapters. Try to solve the exercises on your own first before looking at the solutions. Please note that the solutions do not always implement the tasks exactly, but can also use variations to show that different approaches are possible or so it works automatically. If you want to start each exercise with a clean repository, you can download the repository of the previous solution as a .zip file and start the exercises in this repository.

Overview

Command Line

Create files and folders

  1. Within your chosen folder, create a new subfolder and give it a relevant name.
  2. Navigate into the newly created subfolder.
  3. Create a new text file and name it appropriately.
  4. Confirm that the files was created by listing the contents of the folder.
Code
1cd /path/to/your/chosen/directory
1
Navigate into the chosen location. Replace /path/to/your/chosen/directory with a path on your computer. A good location might be within your /Documents folder or a dedicated /Projects or /University folder. This can help to easily find course-related files on your computer.
Code
#!/bin/bash

2pwd
3mkdir recipes
4cd recipes
5touch recipes.txt
6ls
2
Use pwd to display the path of your current working directory.
3
Use mkdir to create a new subfolder and give it a name, within your chosen folder.
4
Use cd to navigate into the newly created subfolder.
5
Use touch to create a new file and name it appropriately.
6
Use ls to confirm that the files was created by listing the contents of the folder.
Code
#!/bin/bash

2pwd
3mkdir city-guide
4cd city-guide
5touch city-guide.txt
6ls
2
Use pwd to display the path of your current working directory.
3
Use mkdir to create a new subfolder and give it a name, within your chosen folder.
4
Use cd to navigate into the newly created subfolder.
5
Use touch to create a new file and name it appropriately.
6
Use ls to confirm that the files was created by listing the contents of the folder.
Output
+ pwd
/home/runner/work/version-control-book/version-control-book
+ mkdir recipes
+ cd recipes
+ touch recipes.txt
+ ls
recipes.txt
Output
+ pwd
/home/runner/work/version-control-book/version-control-book
+ mkdir city-guide
+ cd city-guide
+ touch city-guide.txt
+ ls
city-guide.txt

Download recipes folder Download city-guide folder

Setup

Configure Git

  1. If needed, navigate into the project folder using the command line.
  2. Set your Git username.
  3. Set your Git email address.
  4. Change the default name of the initial branch to main
  5. 🚀 Optional: Change your default text editor.
  6. List the Git configuration settings.
Code
#!/bin/bash

1cd recipes
2git config --global user.name "Your Name"
3git config --global user.email "your.email@example.com"
4git config --global init.defaultBranch main
5git config --global core.editor "vim"
6git config --list
1
Optional: Use cd (in combination with absolute or relative paths) to navigate into the project subfolder.
2
Set your global Git username using git config --global user.name "Your Name". Replace Your Name with your name and don’t remove the quotation marks.
3
Set your global Git email address using git config --global user.email "your.email@example.com". Replace your.email@example.com with your email address and don’t remove the quotation marks.
4
Change the default name of the initial branch to main using git config --global init.defaultBranch main.
5
Optional: Change your default text editor. In this example, the default text editor is changed to Vim using git config --global core.editor "vim".
6
List the Git configuration.
Code
#!/bin/bash

1cd city-guide
2git config --global user.name "Your Name"
3git config --global user.email "your.email@example.com"
4git config --global init.defaultBranch main
5git config --global core.editor "vim"
6git config --list
1
Optional: Use cd (in combination with absolute or relative paths) to navigate into the project subfolder.
2
Set your global Git username using git config --global user.name "Your Name". Replace Your Name with your name and don’t remove the quotation marks.
3
Set your global Git email address using git config --global user.email "your.email@example.com". Replace your.email@example.com with your email address and don’t remove the quotation marks.
4
Change the default name of the initial branch to main using git config --global init.defaultBranch main.
5
Optional: Change your default text editor. In this example, the default text editor is changed to Vim using git config --global core.editor "vim".
6
List the Git configuration.
Output
+ cd recipes
+ git config user.name Your Name
+ git config user.email your.email@example.com
+ git config init.defaultBranch main
+ git config core.editor vim
+ git config --list --local
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.editor=vim
user.name=Your Name
user.email=your.email@example.com
init.defaultbranch=main
NA
Output
+ cd city-guide
+ git config user.name Your Name
+ git config user.email your.email@example.com
+ git config init.defaultBranch main
+ git config core.editor vim
+ git config --list --local
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.editor=vim
user.name=Your Name
user.email=your.email@example.com
init.defaultbranch=main
NA

Download recipes folder Download city-guide folder

First steps with Git

Initialize a Git repository

  1. If needed, navigate to the project folder using the command line.
  2. Initialize a new Git repository in the project folder.

Add content and commit changes

  1. Create a new text file and name it appropriately.
  2. Add a short entry to the text file (any favorite or an intriguing AI-generated one).
  3. Stage the new file.
  4. Commit the changes in the text file with a descriptive commit message.

🚀 Optional: Commit at least three additional changes in your new file.

Code
#!/bin/bash

1cd recipes
2git init
3touch recipes.txt
4cat > recipes.txt <<- EOM
Pasta

1. Bring water to the boil in a large saucepan.
2. Once the water is boiling, add a good pinch of salt.
3. Add the pasta.
4. Cook the pasta according to packet instructions until it's "al dente".
5. Drain the pasta in a colander.
EOM
5git add recipes.txt
6git commit -m "Add pasta recipe to recipes.txt"
1
If needed, navigate into the recipes subfolder using cd recipes (or a similar path).
2
Initialize a new Git repository in the recipes folder using git init.
3
Create a new file called recipes.txt using touch. Note that you can also use a regular text editor to do this.
4
Add a short recipe to recipes.txt. In this example, cat is used to add text to recipes.txt. This command would also create the file if recipes.txt wouldn’t exist yet. Note that you can also use a regular text editor to do this.
5
Stage the new recipes.txt file using git add.
6
Commit the changes in recipes.txt with a descriptive commit message using git commit.
Code
#!/bin/bash

1cd city-guide
2git init
3touch city-guide.txt
4cat > city-guide.txt <<- EOM
Hamburg Planetarium

- It is one of the world's oldest, and one of Europe's most visited planetariums.
- It is located in the district of Winterhude, Hamburg, Germany.
EOM
5git add city-guide.txt
6git commit -m "Add Hamburg Planetarium to city-guide.txt"
1
If needed, navigate into the city-guide subfolder using cd city-guide (or a similar path).
2
Initialize a new Git repository in the city-guide folder using git init.
3
Create a new file called city-guide.txt using touch. Note that you can also use a regular text editor to do this.
4
Add a short entry to city-guide.txt. In this example, cat is used to add text to city-guide.txt. This command would also create the file if city-guide.txt wouldn’t exist yet. Note that you can also use a regular text editor to do this.
5
Stage the new city-guide.txt file using git add.
6
Commit the changes in city-guide.txt with a descriptive commit message using git commit.
Output
+ cd recipes
+ git init
Reinitialized existing Git repository in /home/runner/work/version-control-book/version-control-book/recipes/.git/
+ touch recipes.txt
+ cat
+ git add recipes.txt
+ git commit -m Add pasta recipe to recipes.txt
[main (root-commit) 96f421d] Add pasta recipe to recipes.txt
 1 file changed, 7 insertions(+)
 create mode 100644 recipes.txt
Output
+ cd city-guide
+ git init
Reinitialized existing Git repository in /home/runner/work/version-control-book/version-control-book/city-guide/.git/
+ touch city-guide.txt
+ cat
+ git add city-guide.txt
+ git commit -m Add Hamburg Planetarium to city-guide.txt
[main (root-commit) b4df735] Add Hamburg Planetarium to city-guide.txt
 1 file changed, 4 insertions(+)
 create mode 100644 city-guide.txt

Download recipes folder Download city-guide folder

Git Essentials

Amend a commit

  1. If needed, navigate to the project folder using the command line.
  2. Make additional changes to your project text file.
  3. Stage the changes.
  4. Amend the previous commit to include the new changes.
  5. Check the commit history to verify that the last commit message has not changed.

For example, add a new entry without a title first, commit, then add a title and amend the previous commit to add the title change to the same commit.

Code
#!/bin/bash

1cd recipes
2echo "6. Enjoy!" >> recipes.txt
3git add recipes.txt
4git commit --amend --no-edit
5git log --oneline
1
Optional: Navigate into the project repository using cd (in combination with an absolute or relative path).
2
Make an additional change to the project text file. In this example, echo is used to append text to text file. Note that you can also use a regular text editor to do this.
3
Stage the changes using git add.
4
Amend the previous commit to include the new changes using git commit --amend. In this example, the --no-edit flag is used to amend the commit without changing the commit message.
5
Check the commit history using git log to verify that the last commit message has not changed. Here, we add the --oneline flag to show a concise summary of the past commits.
Code
#!/bin/bash

1cd city-guide
2echo "- It is housed in a former water tower at the center of Hamburg Stadtpark." >> city-guide.txt
3git add city-guide.txt
4git commit --amend --no-edit
5git log --oneline
1
Optional: Navigate into the project repository using cd (in combination with an absolute or relative path).
2
Make an additional change to the project text file. In this example, echo is used to append text to text file. Note that you can also use a regular text editor to do this.
3
Stage the changes using git add.
4
Amend the previous commit to include the new changes using git commit --amend. In this example, the --no-edit flag is used to amend the commit without changing the commit message.
5
Check the commit history using git log to verify that the last commit message has not changed. Here, we add the --oneline flag to show a concise summary of the past commits.
Output
+ cd recipes
+ echo 6. Enjoy!
+ git add recipes.txt
+ git commit --amend --no-edit
[main 761edc7] Add pasta recipe to recipes.txt
 Date: Fri Dec 13 09:12:52 2024 +0000
 1 file changed, 8 insertions(+)
 create mode 100644 recipes.txt
+ git log --oneline
761edc7 Add pasta recipe to recipes.txt
Output
+ cd city-guide
+ echo - It is housed in a former water tower at the center of Hamburg Stadtpark.
+ git add city-guide.txt
+ git commit --amend --no-edit
[main 99cd761] Add Hamburg Planetarium to city-guide.txt
 Date: Fri Dec 13 09:12:52 2024 +0000
 1 file changed, 5 insertions(+)
 create mode 100644 city-guide.txt
+ git log --oneline
99cd761 Add Hamburg Planetarium to city-guide.txt

Download recipes folder Download city-guide folder

Create a .gitignore file

  1. If needed, navigate to the project folder using the command line.
  2. Add a random file to your repository that you want to ignore, for example an image file like image.jpg.
  3. Check the state of your repository to confirm that Git noticed the added file.
  4. Create a .gitignore file.
  5. Add the random file to the .gitignore file.
  6. Check the state of your repository again to confirm that Git now ignores the added file.
  7. Stage the changes in your repository.
  8. Commit the .gitignore file using a descriptive commit message.
  9. 🚀 All macOS users: Let your repository ignore .DS_Store.
Code
#!/bin/bash

1cd recipes
2wget -nv -O pasta.jpg https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Rigatoni.jpg/320px-Rigatoni.jpg
3git status
4touch .gitignore
5echo "*.jpg" > .gitignore
6git status
7git add --all
8git commit -m "Add .gitignore and ignore all files that end with .jpg"
9echo ".DS_Store" >> .gitignore
git add .gitignore
git commit -m "Ignore .DS_Store"
1
Optional: Navigate into the project repository using cd (in combination with an absolute or relative path).
2
Download an image from the internet using wget. This command download a picture of pasta from the internet and saves the output -O as pasta.jpg. The -nv (or --no-verbose) argument makes the command output less text.
3
Check the state of your repository using git status. Git will notice the new file and list it as untracked.
4
Create a .gitignore file using touch. Note that you can also use a regular text editor to do this.
5
Add *.jpg to the .gitignore file to ignore all files that end with the .jpg file extension. In this example, echo is used to append text to the text file. Note that you can also use a regular text editor to do this. This command would also create the file if .gitignore wouldn’t exist yet.
6
Check the state of your repository again using git status. The new file should disappear from the output and is not listed as untracked anymore.
7
Stage all changes using git add --all. This command should generally be avoided as it may lead to staging and committing changes that should not added to the repository’s history. Here, we use it to demonstrate that only the .gitignore will be staged but not the pasta image file because it is ignored.
8
Commit the changes in .gitignore with a descriptive commit message using git commit.
9
Add .DS_Store to the .gitignore file to ignore it. Again, echo is used to append text to the text file. Note that you can also use a regular text editor to do this. Stage and commit your changes using a descriptive commit message.
Code
#!/bin/bash

1cd city-guide
2wget -nv -O hamburg-planetarium.jpg https://upload.wikimedia.org/wikipedia/commons/3/3a/Hamburg_Planetarium_10881zh.jpg
3git status
4touch .gitignore
5echo "*.jpg" > .gitignore
git status
git add --all
git commit -m "Add .gitignore and ignore all files that end with .jpg"
echo ".DS_Store" >> .gitignore
git add .gitignore
git commit -m "Ignore .DS_Store"
1
Optional: Navigate into the project repository using cd (in combination with an absolute or relative path).
2
Make an additional change to the project text file. In this example, echo is used to append text to text file. Note that you can also use a regular text editor to do this.
3
Stage the changes using git add.
4
Amend the previous commit to include the new changes using git commit --amend. In this example, the --no-edit flag is used to amend the commit without changing the commit message.
5
Check the commit history using git log to verify that the last commit message has not changed. Here, we add the --oneline flag to show a concise summary of the past commits.
Output
+ cd recipes
+ wget -nv -O pasta.jpg https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Rigatoni.jpg/320px-Rigatoni.jpg
2024-12-13 09:12:53 URL:https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Rigatoni.jpg/320px-Rigatoni.jpg [22640/22640] -> "pasta.jpg" [1]
+ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    pasta.jpg

nothing added to commit but untracked files present (use "git add" to track)
+ touch .gitignore
+ echo *.jpg
+ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitignore

nothing added to commit but untracked files present (use "git add" to track)
+ git add --all
+ git commit -m Add .gitignore and ignore all files that end with .jpg
[main 1f0f1a8] Add .gitignore and ignore all files that end with .jpg
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
+ echo .DS_Store
+ git add .gitignore
+ git commit -m Ignore .DS_Store
[main 6cb76d3] Ignore .DS_Store
 1 file changed, 1 insertion(+)
Output
+ cd city-guide
+ wget -nv -O hamburg-planetarium.jpg https://upload.wikimedia.org/wikipedia/commons/3/3a/Hamburg_Planetarium_10881zh.jpg
2024-12-13 09:12:53 URL:https://upload.wikimedia.org/wikipedia/commons/3/3a/Hamburg_Planetarium_10881zh.jpg [415048/415048] -> "hamburg-planetarium.jpg" [1]
+ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    hamburg-planetarium.jpg

nothing added to commit but untracked files present (use "git add" to track)
+ touch .gitignore
+ echo *.jpg
+ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitignore

nothing added to commit but untracked files present (use "git add" to track)
+ git add --all
+ git commit -m Add .gitignore and ignore all files that end with .jpg
[main d41f35c] Add .gitignore and ignore all files that end with .jpg
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
+ echo .DS_Store
+ git add .gitignore
+ git commit -m Ignore .DS_Store
[main 2ee9106] Ignore .DS_Store
 1 file changed, 1 insertion(+)

Download recipes folder Download city-guide folder

Branches

Create and merge a new branch

  1. If needed, navigate to the project repository using the command line.
  2. Create a new branch called feature.
  3. Switch to the new branch.
  4. Add a new entry to your project text file.
  5. Stage and commit the changes to the project text file on the feature branch.
  6. View the contents of project text file to verify your changes.
  7. Switch back to the default branch (main or master).
  8. View the contents of the project text file again to confirm that the previous changes do not exist on the default branch.
  9. Merge the feature branch into your default branch.
  10. Delete the feature branch.
  11. View the contents of project text file yet again to confirm that the previous changes have been merged into the default branch.
Code
#!/bin/bash

1cd recipes
2git branch feature
3git switch feature
4cat >> recipes.txt <<- EOM

Potatoes

1. Wash the potatoes and cut them into evenly sized chunks.
2. Bring water to the boil in a large saucepan.
3. Once the water is boiling, add a good pinch of salt.
3. Add the potatoes.
4. Cook the potatoes for 15 - 20 minutes or until fork-tender.
5. Drain the pasta in a colander.
EOM
5git add recipes.txt
git commit -m "Add potatoes recipe to recipes.txt"
6cat recipes.txt
7git checkout main
8cat recipes.txt
9git merge feature
10git branch -d feature
11cat recipes.txt
1
Optional: Navigate into the project repository using cd (or a similar path).
2
Create a new branch called feature using git branch feature.
3
Switch to the new branch using git switch feature. You can also create and switch the branch in one step using git checkout -b feature.
4
Add a new entry to your project text file file. You can use your regular text editor. Here, we add a new entry from the command line using cat.
5
Stage and commit the changes to your project text file using git add and git commit.
6
View the contents of your project text file to verify your changes. Here, we use the cat command again.
7
Switch back to the default branch (main in this example). Here, we use git checkout main but you can also use git switch main.
8
View the contents of your project text file again to confirm that the previous changes do not exist on the main branch.
9
Merge the changes feature branch into the main branch.
10
Delete the merged feature branch using git branch -d feature.
11
View the contents of your project text file yet again to confirm that the previous changes have been merged into the main branch.
Code
#!/bin/bash

1cd city-guide
2git branch feature
3git switch feature
4cat >> city-guide.txt <<- EOM

Paddle tour of the Alster canals

- If you're not afraid of the water and would like to enjoy a really super day whilst at the same time doing a bit of upper body exercise, then why not pick up a paddle and work your way down the Alster canals in a canoe.
- Just go to any one of the countless boat and canoe hire points on the Alster to begin your adventure.

taken from https://www.hamburg-travel.com/see-explore/sports-recreation/sports-physical-activity/paddle-tour-of-the-alster-canals/
EOM
5git add city-guide.txt
git commit -m "Add paddle tour of the Alster canals to city-guide.txt"
6cat city-guide.txt
7git checkout main
8cat city-guide.txt
9git merge feature
10git branch -d feature
11cat city-guide.txt
1
Optional: Navigate into the project repository using cd (or a similar path).
2
Create a new branch called feature using git branch feature.
3
Switch to the new branch using git switch feature. You can also create and switch the branch in one step using git checkout -b feature.
4
Add a new entry to your project text file file. You can use your regular text editor. Here, we add a new entry from the command line using cat.
5
Stage and commit the changes to your project text file using git add and git commit.
6
View the contents of your project text file to verify your changes. Here, we use the cat command again.
7
Switch back to the default branch (main in this example). Here, we use git checkout main but you can also use git switch main.
8
View the contents of your project text file again to confirm that the previous changes do not exist on the main branch.
9
Merge the changes feature branch into the main branch.
10
Delete the merged feature branch using git branch -d feature.
11
View the contents of your project text file yet again to confirm that the previous changes have been merged into the main branch.
Output
+ cd recipes
+ git branch feature
+ git switch feature
Switched to branch 'feature'
+ cat
+ git add recipes.txt
+ git commit -m Add potatoes recipe to recipes.txt
[feature 46ddebd] Add potatoes recipe to recipes.txt
 1 file changed, 9 insertions(+)
+ cat recipes.txt
Pasta

1. Bring water to the boil in a large saucepan.
2. Once the water is boiling, add a good pinch of salt.
3. Add the pasta.
4. Cook the pasta according to packet instructions until it's "al dente".
5. Drain the pasta in a colander.
6. Enjoy!

Potatoes

1. Wash the potatoes and cut them into evenly sized chunks.
2. Bring water to the boil in a large saucepan.
3. Once the water is boiling, add a good pinch of salt.
3. Add the potatoes.
4. Cook the potatoes for 15 - 20 minutes or until fork-tender.
5. Drain the pasta in a colander.
+ git checkout main
Switched to branch 'main'
+ cat recipes.txt
Pasta

1. Bring water to the boil in a large saucepan.
2. Once the water is boiling, add a good pinch of salt.
3. Add the pasta.
4. Cook the pasta according to packet instructions until it's "al dente".
5. Drain the pasta in a colander.
6. Enjoy!
+ git merge feature
Updating 6cb76d3..46ddebd
Fast-forward
 recipes.txt | 9 +++++++++
 1 file changed, 9 insertions(+)
+ git branch -d feature
Deleted branch feature (was 46ddebd).
+ cat recipes.txt
Pasta

1. Bring water to the boil in a large saucepan.
2. Once the water is boiling, add a good pinch of salt.
3. Add the pasta.
4. Cook the pasta according to packet instructions until it's "al dente".
5. Drain the pasta in a colander.
6. Enjoy!

Potatoes

1. Wash the potatoes and cut them into evenly sized chunks.
2. Bring water to the boil in a large saucepan.
3. Once the water is boiling, add a good pinch of salt.
3. Add the potatoes.
4. Cook the potatoes for 15 - 20 minutes or until fork-tender.
5. Drain the pasta in a colander.
Output
+ cd city-guide
+ git branch feature
+ git switch feature
Switched to branch 'feature'
+ cat
+ git add city-guide.txt
+ git commit -m Add paddle tour of the Alster canals to city-guide.txt
[feature b2b7c49] Add paddle tour of the Alster canals to city-guide.txt
 1 file changed, 7 insertions(+)
+ cat city-guide.txt
Hamburg Planetarium

- It is one of the world's oldest, and one of Europe's most visited planetariums.
- It is located in the district of Winterhude, Hamburg, Germany.
- It is housed in a former water tower at the center of Hamburg Stadtpark.

Paddle tour of the Alster canals

- If you're not afraid of the water and would like to enjoy a really super day whilst at the same time doing a bit of upper body exercise, then why not pick up a paddle and work your way down the Alster canals in a canoe.
- Just go to any one of the countless boat and canoe hire points on the Alster to begin your adventure.

taken from https://www.hamburg-travel.com/see-explore/sports-recreation/sports-physical-activity/paddle-tour-of-the-alster-canals/
+ git checkout main
Switched to branch 'main'
+ cat city-guide.txt
Hamburg Planetarium

- It is one of the world's oldest, and one of Europe's most visited planetariums.
- It is located in the district of Winterhude, Hamburg, Germany.
- It is housed in a former water tower at the center of Hamburg Stadtpark.
+ git merge feature
Updating 2ee9106..b2b7c49
Fast-forward
 city-guide.txt | 7 +++++++
 1 file changed, 7 insertions(+)
+ git branch -d feature
Deleted branch feature (was b2b7c49).
+ cat city-guide.txt
Hamburg Planetarium

- It is one of the world's oldest, and one of Europe's most visited planetariums.
- It is located in the district of Winterhude, Hamburg, Germany.
- It is housed in a former water tower at the center of Hamburg Stadtpark.

Paddle tour of the Alster canals

- If you're not afraid of the water and would like to enjoy a really super day whilst at the same time doing a bit of upper body exercise, then why not pick up a paddle and work your way down the Alster canals in a canoe.
- Just go to any one of the countless boat and canoe hire points on the Alster to begin your adventure.

taken from https://www.hamburg-travel.com/see-explore/sports-recreation/sports-physical-activity/paddle-tour-of-the-alster-canals/

Download the repository

Create and resolve a merge conflict

  1. Deliberately create a merge conflict by editing the same section of a file on two separate branches and attempting to merge them. An example can be found in the branches chapter.
  2. Resolve the merge conflict.
  3. Delete the merged branch afterwards.
Code
#!/bin/bash

1cd recipes
2git branch feature
3git switch feature
4cat >> recipes.txt <<- EOM

Chocolate Cake

1. Preheat the oven to 350°F (175°C).
2. Mix flour, sugar, cocoa powder, baking powder, and salt in a bowl.
3. Add eggs, milk, oil, and vanilla extract, and mix well.
4. Pour the batter into a greased baking pan.
5. Bake for 30-35 minutes.

EOM
5git add recipes.txt
git commit -m "Add chocolate cake recipe to recipes.txt"
6git checkout main
7cat >> recipes.txt <<- EOM

Vanilla Cake

1. Preheat the oven to 350°F (175°C).
2. Mix flour, sugar, baking powder, and salt in a bowl.
3. Add eggs, milk, oil, and vanilla extract, and mix well.
4. Pour the batter into a greased baking pan. 
5. Bake for 25-30 minutes.

EOM

8git add recipes.txt
git commit -m "Add vanilla cake recipe to recipes.txt"
9git merge feature
10sed -i '' -e '/^<<<<<<< /d' -e '/^=======/d' -e '/^>>>>>>> /d' recipes.txt
11git add recipes.txt
12git commit -m "Resolve merge conflict by adding both chocolate and vanilla cake recipes"
13git branch -d feature
1
Navigate into the recipes repository using cd (or a similar path).
2
Create a new branch called feature using git branch feature.
3
Switch to the new branch using git switch feature. You can also create and switch the branch in one step using git checkout -b feature.
4
Add a new recipe to your recipes.txt file using cat.
5
Stage and commit the changes to recipes.txt using git add and git commit.
6
Switch back to the default branch (main in this example) using git checkout main. You can also use git switch main.
7
Make conflicting changes in the main branch to recipes.txt using cat.
8
Stage and commit the conflicting changes to recipes.txt using git add and git commit.
9
Attempt to merge the feature branch with the default branch to create a merge conflict using git merge feature.
10
Resolve the merge conflict by editing recipes.txt. You can use a regular text editor to do this. In this example, we remove the conflict markers that Git added to recipes.txt using sed which results in keeping both recipes. This is not a recommended way to resolve merge conflicts and we only do it here to resolve the merge conflict without manual intervention. Merge conflicts usually always require manual resolution by the user.
11
Stage the resolved changes to recipes.txt using git add.
12
Commit the resolved changes in recipes.txt with a descriptive commit message using git commit.
13
Delete the merged feature branch using git branch -d feature.
Output
+ cd recipes
+ git branch feature
+ git switch feature
Switched to branch 'feature'
+ cat
+ git add recipes.txt
+ git commit -m Add chocolate cake recipe to recipes.txt
[feature c1ab84b] Add chocolate cake recipe to recipes.txt
 1 file changed, 9 insertions(+)
+ git checkout main
Switched to branch 'main'
+ cat
+ git add recipes.txt
+ git commit -m Add vanilla cake recipe to recipes.txt
[main ff5cdb5] Add vanilla cake recipe to recipes.txt
 1 file changed, 9 insertions(+)
+ git merge feature
Auto-merging recipes.txt
CONFLICT (content): Merge conflict in recipes.txt
Automatic merge failed; fix conflicts and then commit the result.
+ sed -i  -e /^<<<<<<< /d -e /^=======/d -e /^>>>>>>> /d recipes.txt
sed: can't read : No such file or directory
+ git add recipes.txt
+ git commit -m Resolve merge conflict by adding both chocolate and vanilla cake recipes
[main 63c6947] Resolve merge conflict by adding both chocolate and vanilla cake recipes
+ git branch -d feature
Deleted branch feature (was c1ab84b).

Download recipes folder Download city-guide folder

Remotes: Intro

Connect to remote repositories using SSH

  1. Generate an SSH key.
  2. Copy the SSH key to your clipboard.
  3. Add the SSH key to the remote repository (for example, GitHub or GitLab).
Code
#!/bin/bash

1ssh-keygen -t ed25519 -C "your_email@example.com"
2cat ~/.ssh/id_ed25519.pub
3# Copy the SSh key to your account
1
In the command line, create a new SSH key. Make sure to change the example email to your email address. Optionally, provide a passphrase.
2
Copy the SSH key to your clipboard. Here, we use cat to print the contents of the SSH key to the command line. Copy the contents displayed in the Terminal to your clipboard.
3
Add the SSH key to your remote repository account.

Connect to GitHub using a PAT

  1. Generate a personal access token (PAT) on GitHub.
  2. Use the PAT for GitHub authentication.
  1. Go to GitHub.
  2. Click on your profile picture in the upper-right corner and select “Settings”.
  3. In the left sidebar, click “Developer settings”.
  4. In the left sidebar, click “Personal access tokens”.
  5. Click “Generate new token”.
  6. Give your token a descriptive name.
  7. Select the scopes or permissions you’d like to grant this token. For uploading a repository, select the repo scope. 1 .Click Generate token.
  8. Copy the token and store it in a secure place. You won’t be able to see it again.
  9. Use the PAT for GitHub authentication. When prompted for a username and password for GitHub operations (like git push), use your GitHub username as the username and the generated PAT as the password.

Upload your local repository to a remote repository

  1. Create an empty repository on the remote repository hosting platform, for example GitHub or GitLab. Make sure to not initialize the repository with any files!
  2. If needed, navigate to your project repository using the command line.
  3. Set the remote URL of your local repository to your remote repository.
  4. Push the changes on your default branch (main or master) to your remote repository.
Code
#!/bin/bash

1# create an empty remote repository
2cd my-project
3git remote add origin https://github.com/your-username/your-repo-name.git
4git push -u origin main
1
To create an empty repository on GitHub: (1) Go to GitHub and click the + icon in the upper-right corner, then select New repository. (2) Name your repository. (3) Do not select Initialize this repository with a README. (4) Click Create repository.
2
Optional: Navigate into the project repository using cd (or a similar path).
3
Set the remote URL of the local repository to the repository using git remote add origin <URL>. Remember to use the correct <URL> depending on whether you authentication method (typically SSH or PAT).
4
Push the changes on the default branch (here, main) to the remote repository using git push -u origin main.

Add a README.md

  1. Find the option to create a new file on your remote repository in the browser.
  2. Name the file README.md, add a brief description, and provide a commit message.
  3. 🚀 Optional: Play around with Markdown syntax.
  4. Save the README.md file to the repository.
  5. Pull the changes to your local repository.
  1. In your browser, go to your remote repository (for example, on GitHub), click Add file, and select Create new file.
  2. Name the file README.md. Add a brief description of your project. Provide a descriptive commit message at the bottom.
  3. Play around with Markdown syntax
  4. Click the green Commit new file button to save the README.md file to the repository.
  5. Use git pull origin main to pull the changes to your local repository.

“Private” collaboration with pull requests (using GitHub Flow)

  1. Add your exercise partner as a collaborator to your project repository on GitHub.
  2. Clone your partner’s repository.
  3. Create a new branch in your collaborator’s repository.
  4. Add a new entry to your collaborator’s project file (e.g., .txt or .qmd (if you are unsure, where to add the entry, ask your collaborator!)
  5. Add and commit the changes.
  6. Push the changes on the new branch to the remote repository.
  7. Create a Pull Request (on GitLab: Merge Request).
  8. Review the Pull Request that your collaborator made in your repository.
  9. 🚀 Optional: Add additional changes on the branch pushed by your collaborator.
  10. Merge the pull request into your repository.
Code
#!/bin/bash

1# Add your exercise partner as a collaborator to your recipes repository
2cd ~
3git clone https://github.com/partner-username/partner-repo-name.git
4git checkout -b new-branch-name
5echo "New Recipe" >> recipes.txt
6git add recipes.txt
git commit -m "Add new recipe to recipes.txt"
7git push origin new-branch-name
8# Create a Pull / Merge Request.
9# Review the PR your partner made in your repository.
10# Merge the PR into your repository.
1
Add your exercise partner as a collaborator to your recipes repository: (1) Go to your repository on GitHub. (2) Click on Settings. (2) Click on Manage access in the left sidebar. (3) Click Invite a collaborator and enter your partner’s GitHub username.
2
Move to the location on your computer where you would like to clone your partner’s repository into, using cd in the command line. Here, we cd into the user’s home directory (~).
3
Clone your partner’s repository using git clone. Make sure that you not cloning into an existing repository.
4
Create a new branch in your partner’s repository.
5
Add a recipe to your partner’s recipes.txt file.
6
Add and commit the changes using a descriptive commit message.
7
Push the changes on the new branch to GitHub.
8
Create a Pull Request: (1) Go to your partner’s repository on GitHub. (2) Click Compare & pull request for your branch. (3) Provide a title and description, then click Create pull request.
9
Review the PR your partner made in your repository: (19) Go to your repository on GitHub. (2) Click on the Pull requests tab. (3) Click on the PR made by your partner. (4) Review the changes and provide feedback.
10
Merge the PR into your repository: (1) After reviewing, click the green Merge pull request button. (2) Click Confirm merge.

Clone and sync your repository

  1. Move to a location on your computer where you want to clone a repository.
  2. Clone your remote repository to a different location on your computer.
  3. Stage and commit changes in the new location (consider using a new branch).
  4. Push these new changes to GitHub.
  5. Pull the changes to the repository in the original location.
  6. Delete your newly cloned repository.
Code
#!/bin/bash

1cd /new/location/for/repo
2git clone https://github.com/your-username/your-repo-name.git /new/location/for/repo
3git checkout -b new-branch
echo "New Recipe" >> recipes.txt
git add recipes.txt
git commit -m "Add new recipe to recipes.txt"
4git push -u origin new-branch
5cd /original/location/for/repo
git fetch
git switch new-branch
6rm -rf /new/location/for/repo
1
Move to the location on your computer where you would like to clone your own repository into, using cd in the command line.
2
Clone your repository from GitHub to a different location on your computer.
3
Stage and commit changes in the new location (consider using a new branch).
4
Push the new changes to GitHub.
5
Fetch these new changes to the repository in the original location.
6
Delete your newly cloned repository.

Remotes: Advanced

“Public” collaboration with pull requests (using a fork and GitHub Flow)

  1. Find out what forking is.
  2. Fork the recipes repository of another course participant (ideally someone who is not your collaborator from the previous exercise).
  3. Create an Issue in your new collaborator’s repository (maybe their repository is missing a great recipe?).
  4. Repeat the steps from the exercise on collaboration with remote repositories using the forked repository:
    1. Clone the forked repository into a sensible location on your computer.
    2. Create a new branch and create one or multiple commits “fixing” the Issue that you opened. If available, follow the contributing guide of your collaborator’s repository.
    3. Push your changes to the remote repository.
    4. Create a pull / merge request with your changes (hint: from the forked to the original repository) and refer to the Issue in your pull / merge request.
  1. Forking is a process where you create a copy of someone else’s repository under your own account. It allows you to freely experiment with changes without affecting the original project.
  2. To fork the recipes repository of another course participant: (1) Go to the GitHub repository you want to fork. (2) Click the Fork button at the top-right corner of the repository page. (3) Select your GitHub account to fork the repository.
  3. Create an Issue, suggesting a missing recipe: (1) Go to the Issues tab of your partner’s repository on GitHub. (2) Click New issue. Provide a title and description for the Issue, suggesting a missing recipe. (3) Click Submit new issue.
  4. Clone the forked repository into a sensible location on your computer.
Code
git clone https://github.com/your-username/forked-repo-name.git /path/to/your/forked/directory
cd /path/to/your/forked/directory
  1. Create a new branch and create one or multiple commits “fixing” the Issue that you opened.
Code
git checkout -b issue-fix-branch
echo "New Recipe Content" >> recipes.txt
git add recipes.txt
git commit -m "Add new recipe to fix #1"
  1. Push your changes to the remote repository:
Code
git push origin issue-fix-branch
  1. Create a pull request with your changes (from the forked to the original repo) and refer to the issue in your pull request:

    1. Go to your forked repository in your browser.
    2. Click the Compare & pull request button.
    3. Ensure that the base repository is the original and the base branch is main.
    4. Provide a title and description for your pull request.
    5. Refer to the issue by adding Fixes #issue-number in the description.
    6. Click Create pull request.
    7. Review any pull requests in your repository.

Reviewing pull requests

  1. View any pull requests that are created in your recipes repository.
  2. Review the changes made by the contributor in the pull request.
  3. If needed, discuss additional changes with the contributor in the pull request.
  4. Close the pull request by merging the proposed changes.

Tags and Releases

Create a tag

  1. Create a lightweight or an annotated tag named v1.0.0.

Create a GitHub Release

  1. Go to your repository on GitHub and create a release of the tag v1.0.0.

Create a lightweight or an annotated tag named v1.0.0.

  1. For a lightweight tag:
git tag v1.0.0

For an annotated tag:

git tag -a v1.0.0 -m "Release version 1.0.0"
  1. Push the tag to GitHub:
git push origin v1.0.0

Create a GitHub Release

  1. Go to your repository on GitHub.
  2. Click on “Releases” then “Draft a new release”.
  3. Choose the tag v1.0.0 from the list
  4. Fill in the release title and description.
  5. Click “Publish release”.

Graphical User Interfaces

Install a Git GUI

  1. Install a Git GUI
  2. Login to the client using your GitHub account.
  3. View your recipes repository in the Git GUI.

Open a Git repository in RStudio

  1. Open your recipes repository in RStudio.
  2. Edit the recipes.txt or recipes.qmd file by adding or modifying a recipe.
  3. Commit your changes using RStudio’s Git interface.

Open a Git Repository in RStudio

  1. Open your recipes repository in RStudio:
    • Open RStudio.
    • Open a Project:
      • Click on File -> New Project -> Version Control -> Git.
      • Enter the URL of your recipes repository or choose the local path if already cloned.
      • Click Create Project.
  2. Edit the recipes.txt or recipes.qmd file by adding or modifying a recipe:
    • Open the file:
      • In the RStudio File Explorer, navigate to the recipes repository and open recipes.txt or recipes.qmd.
    • Edit the file:
      • Make your desired changes to the file by adding or modifying a recipe.
    • Save the file:
      • Click on File -> Save or press Ctrl + S.
  3. Commit your changes using RStudio’s Git interface:
    • Open the Git pane:
      • In RStudio, find the Git pane, usually located in the top-right or bottom-right corner.
    • Stage the changes:
      • In the Git pane, you should see the modified files listed. Check the box next to the files you want to commit to stage the changes.
    • Commit the changes:
      • Click on Commit.
      • Enter a commit message describing your changes.
      • Click Commit again to finalize the commit.
    • Push the changes:
      • After committing, click on Push to upload your changes to the remote repository on GitHub.

Stashing

  1. Navigate to the recipes repository using the command line.
  2. Create a new branch called feature/stash-exercise.
  3. Switch to the new branch.
  4. Make any change to any of the files in your project directory.
  5. Stash your changes without adding a message.
  6. Verify that your working directory is clean.
  7. Apply the stash to your working directory.
  8. Verify that your changes are restored.
Code
#!/bin/bash

1cd recipes
2git branch feature/stash-exercise
3git switch feature/stash-exercise
4echo "This is yummy!" >> recipes.txt
5git stash
6git status
7git stash apply
8tail -1 recipes.txt
1
Navigate into the recipes repository using cd (or a similar path).
2
Create a new branch called feature/stash-exercise using git branch.
3
Switch to the new branch using git switch. Alternatively, you could have also done the two last steps with one command using git checkout -b feature/stash-exercise.
4
Make any change to any of the files in your project directory. Here, we use the echo command to append text to the end of recipes.txt.
5
Stash your changes without adding a message using git stash.
6
Verify that the working directory is clean using git status. Check that the output indeed indicates a clean working directory.
7
Apply the stash to your working directory using git stash apply.
8
Verify that your changes are restored. Here, we use tail -1 recipes.txt to print the last line of recipes.txt.
Output
+ cd recipes
+ git branch feature/stash-exercise
+ git switch feature/stash-exercise
Switched to branch 'feature/stash-exercise'
+ echo This is yummy!
+ git stash
Saved working directory and index state WIP on feature/stash-exercise: 63c6947 Resolve merge conflict by adding both chocolate and vanilla cake recipes
+ git status
On branch feature/stash-exercise
nothing to commit, working tree clean
+ git stash apply
On branch feature/stash-exercise
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:   recipes.txt

no changes added to commit (use "git add" and/or "git commit -a")
+ tail -1 recipes.txt
This is yummy!

Download the repository

Reverting

  1. Navigate to the recipes repository using the command line.
  2. Create a new branch called feature/revert-exercise.
  3. Switch to the new branch.
  4. Make any change to any of the files in your project directory.
  5. Stage your changes.
  6. Commit your changes.
  7. Check the commit hash of your last commit.
  8. Revert your last commit.
Code
#!/bin/bash

1cd recipes
2git branch feature/revert-exercise
3git switch feature/revert-exercise
4echo "This is delicious!" >> recipes.txt
5git add recipes.txt
6git commit -m "Add text"
7last_commit_hash=$(git log -1 --format="%H")
8git revert --no-edit $last_commit_hash
1
Navigate into the recipes repository using cd (or a similar path).
2
Create a new branch called feature/revert-exercise using git branch.
3
Switch to the new branch using git switch. Alternatively, you could have also done the two last steps with one command using git checkout -b feature/revert-exercise.
4
Make any change to any of the files in your project directory. Here, we use the echo command to append text to the end of recipes.txt.
5
Stage your change using git add <filename>.
6
Commit your changes using git commit -m "Commit message".
7
Retrieve the commit hash of the last commit using git log. Here, we save the commit hash as variable and use this variable in the next step. Normally, you would just run git log and find the hash of the commit that you want to revert. (This code does this differently for automation) You can also use git log -1 to only see your most recent commit.
8
Revert the commit using git revert <commithash>. This will open your editor where you can specify a commit message for the revert. If you use the --no-edit flag, Git will use a default commit message.
Output
+ cd recipes
+ git branch feature/revert-exercise
+ git switch feature/revert-exercise
Switched to branch 'feature/revert-exercise'
M   recipes.txt
+ echo This is delicious!
+ git add recipes.txt
+ git commit -m Add text
[feature/revert-exercise ab71c0d] Add text
 1 file changed, 2 insertions(+)
+ git log -1 --format=%H
+ last_commit_hash=ab71c0d040f161b5cece4b4fa0146111c3bb25f2
+ git revert --no-edit ab71c0d040f161b5cece4b4fa0146111c3bb25f2
[feature/revert-exercise 28e2e20] Revert "Add text"
 Date: Fri Dec 13 09:12:53 2024 +0000
 1 file changed, 2 deletions(-)

Download the repository

Rebasing

  1. Navigate to the recipes repository using the command line.
  2. Create a new branch called feature/rebase-exercise.
  3. Switch to the new branch.
  4. Make any change to any of the files in your project directory.
  5. Stage the changes.
  6. Commit the your staged changes.
  7. Switch back to the main branch
  8. Make any change to any of the files in your project directory.
  9. Stage the changes.
  10. Commit the your staged changes.
  11. Switch back to the feature/rebase-exercise branch
  12. Rebase the commit of the feature/rebase-exercise branch onto your main branch.
  13. Verify that the commits from feature/rebase-exercise are now on top of the commits from main.
Code
#!/bin/bash

1cd recipes
2git branch feature/rebase-exercise
3git switch feature/rebase-exercise
4echo "New feature content" >> feature.txt
5git add feature.txt
6git commit -m "Add feature content"
7git switch main
8echo "Main branch content" >> main.txt
9git add main.txt
10git commit -m "Update main content"
11git switch feature/rebase-exercise
12git rebase main
13git switch main
14git log --oneline
1
Navigate into the recipes repository using cd (or a similar path).
2
Create a new branch called feature/rebase-exercise using git branch.
3
Switch to the new branch using git switch. Alternatively, you could have also done the two last steps with one command using git checkout -b feature/rebase-exercise.
4
Make any change to any of the files in your project directory. Here, we append the text "New feature content" to the file feature.txt.
5
Stage your change using git add <filename>.
6
Commit your changes using git commit -m "commit message".
7
Switch back to the main branch using git switch.
8
Make any change to any of the files in your project directory. Here, we append "Main branch content" to a file named main.txt. This change simulates working on the main branch simultaneously.
9
Stage your changes using git add <filename>.
10
Commit your changes using git commit -m "commit message".
11
Switch back to the feature branch using git switch feature/rebase-exercise.
12
Rebase the commit of the feature/rebase-exercise branch onto your main branch using git rebase main.
13
Switch back to the main branch using git switch main.
14
Verify that the commit from feature/rebase-exercise is now on top of the commits from main using git log.
Output
+ cd recipes
+ git branch feature/rebase-exercise
+ git switch feature/rebase-exercise
Switched to branch 'feature/rebase-exercise'
+ echo New feature content
+ git add feature.txt
+ git commit -m Add feature content
[feature/rebase-exercise b3eae00] Add feature content
 1 file changed, 1 insertion(+)
 create mode 100644 feature.txt
+ git switch main
Switched to branch 'main'
+ echo Main branch content
+ git add main.txt
+ git commit -m Update main content
[main d7d2a38] Update main content
 1 file changed, 1 insertion(+)
 create mode 100644 main.txt
+ git switch feature/rebase-exercise
Switched to branch 'feature/rebase-exercise'
+ git rebase main
Rebasing (1/3)
Rebasing (2/3)
Rebasing (3/3)
Successfully rebased and updated refs/heads/feature/rebase-exercise.
+ git switch main
Switched to branch 'main'
+ git log --oneline
d7d2a38 Update main content
63c6947 Resolve merge conflict by adding both chocolate and vanilla cake recipes
ff5cdb5 Add vanilla cake recipe to recipes.txt
c1ab84b Add chocolate cake recipe to recipes.txt
46ddebd Add potatoes recipe to recipes.txt
6cb76d3 Ignore .DS_Store
1f0f1a8 Add .gitignore and ignore all files that end with .jpg
761edc7 Add pasta recipe to recipes.txt

Download the repository