Exercise - Poem Part 1

In this exercise, participants will learn how to work with git branches, make changes, resolve conflicts, and collaborate on a repository.

For this we will use the following poem:

Poem
Erlkönig – Johann Wolfgang von Goethe

Team 1

Wer reitet so spät durch Nacht und Wind?
Es ist der Vater mit seinem Kind;
Er hat den Knaben wohn in dem Arm,
Er faβt ihn sicher, er hält ihn warm.

Mein Sohn, was birgst du so bang dein Gesicht?
“Siehst, Vater, du den Erlkönig nicht?
Den Erlenkönig mit Kron und Schweif?”
Mein Sohn, es ist ein Nebelstreif.

Team 2

‘Du liebes Kind, komm, geh mit mir!
Gar schöne Spiele spiel ich mit dir
Manch bunte Blumen sind an dem Strand.
Meine Mutter hat manch gülden Gewand.’

“Mein Vater, mein Vater, und hörest du nicht,
Was Erlenkönig mir leise verspricht?”
Sei ruhig, bleibe ruhig, mein Kind;
In dürren Blättern säuselt der Wind.

Team 3

‘Willst, feiner Knabe, du mit mir gehn?
Meine Töchter solln dich warten schön;
Meine Töchter führen den nächtlichen Reihn,
Und wiegen und tanzen und singen dich ein.’

“Mein Vater, mein Vater, und siehst du nicht dort
Erlkönigs Töchter am düstern Ort?”
Mein Sohn, mein Sohn, ich seh es genau;
Es scheinen die alten Weiden so grau.

Team 4

‘Ich liebe dich, mich reizt deine schöne Gestalt;
Und bist du nicht willig, so brauch ich Gewalt.’
“Mein Vater, mein Vater, jetzt fasst er mich an!
Erlkönig hat mir ein Leids getan!”

Dem Vater grauset’s, er reitet geschwind,
Er hält in Armen das ächzende Kind,
Erreicht den Hof mit Mühe und Not;
In seinen Armen das Kind war tot.

The teams are formed depending on the number of participants.

Team structure
Scenario A:
- 6 participants
- 3 Teams à 2 participants
- Each participant takes 4 verses

Scenario B:
- 8 participants
- 4 Teams à 2 participants
- Each participant takes 4 verses

Scenario C:
- 10 participants
- 2 Teams à 2 participants
- Each participant takes 4 verses
- 2 Teams à 3 participants
- 2 participants take 3 verses, 1 participant takes 2 verses

Scenario D:
- 12 participants
- 4 Teams à 3 participants
- 2 participants take 3 verses, 1 participant takes 2 verses

Scenario E:
- 14 participants
- 2 Teams à 3 participants
- 2 participants take 3 verses, 1 participant takes 2 verses
- 2 Teams à 4 participants
- Each participant takes 2 verses

Scenario F:
- 16 participants
- 4 Teams à 4 participants
- Each participant takes 2 verses

Good luck with the exercises!


Preparation

Step 1: Create and add a SSH Key

First make sure that you are in your previously created local repository.

pwd

$ pwd
/home/novatec/git-beginners

We will now locally create a SSH Key for your User and add the public key to your GitLab Profile.

Please run the following command in your Terminal:

ssh-keygen -t ed25519 -C "your-name@company.de"

When you’re prompted to ‘Enter a file in which to save the key’, you can press Enter to accept the default file location ‘/home/novatec/.ssh/’.

When you’re prompted to ‘Enter a passphrase’ just press Enter to skip that step.

Output
$ ssh-keygen -t ed25519 -C "your-name@company.de"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/novatec/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/novatec/.ssh/id_ed25519
Your public key has been saved in /home/novatec/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:WpLqlSs2hp2CXjJi7htfn/mVfkKtz/tr9VQezSGUULA "your-name@company.de"
The key's randomart image is:
+--[ED25519 256]--+
|           o=o.  |
|            .o . |
|           E  ..o|
|       .       .+|
|      o S   .  .o|
|     . =   ...  +|
|.* +.o+   .o.  .o|
|= O.O...o oo.. ..|
|o=.=.o.+.. .+++o.|
+----[SHA256]-----+

A public and a private key have been created in your ‘.ssh’ folder.

ls /home/novatec/.ssh

Output
$ ls /home/novatec/.ssh
authorized_keys  id_ed25519  id_ed25519.pub

You can now copy the public key from the ‘id_rsa.pub’ file.

cat /home/novatec/.ssh/id_ed25519.pub

$ cat /home/novatec/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVc40W4HbDsYTKqS2bJUMdMmVvgsMqf8MKXcPTaZXuD your-name@company.de

Copy the entire output of the command

Next go to GitLab using the URL provided by your trainer. When opening the GitLab website please click on ‘Keycloak SSO’. The keycloak website will open. Login with the credentials provided.

GitLabLoginSSO GitLabLoginSSO

When logged in click on your avatar and on ‘Edit Profile’ and navigate to the ‘SSH Keys’ section of your ‘user settings’.

SSHKeySettings SSHKeySettings

Create a new ‘SSH Key’ for your User.

CreateSSHKey CreateSSHKey

Step 2: Add the remote GitLab repository

The next steps require that a password is set in our GitLab Profile. Please set it using the password that was provided by your instructor for the Keycloak SSO Login.

Click on your avatar and on ‘Edit Profile’ and go to the ‘Password’ section. Set the password there.

Now we will add the remote repository. ‘origin’ is the default name (alias) for the remote repository when we add it locally.

First click on the GitLab Icon in the top left corner. To get the ‘REMOTE_URL’ of the repository we navigate to the ‘Project’ section of GitLab.

Projects Projects

Then we open the ‘git-training’ repository and copy the ‘Clone with HTTPS’ URL.

Repository Repository

Use that URL to clone the remote repository locally.

git remote add origin <REMOTE_URL>

If prompted enter your username with the previously added password.

Check if the remote was added correctly by running:

git remote -v

Output

It should output something like:

$ git remove -v
origin https://git.gitlab.cloudtrainings.online/root/git-training.git (fetch)
origin https://git.gitlab.cloudtrainings.online/root/git-training.git (push)

Step 3: Create Branching Structure

Each team creates its own feature branch while keeping the main branch unchanged.

The initial setup requires that one team member creates the initial branch. Use the following command and replace X with your team number:

git switch --create feature-teamX

The next step will be to create a text file that will be used later by all team members.

Use your default editor ’nano’ to create and edit the text file:

nano erlkoenig.txt

Add Hi Team! to the text file. Exit nano with Ctrl+X and save it with typing ‘y’ and pressing enter.

Check if the file contains your message before committing:

cat erlkoenig.txt

Output
$ cat erlkoenig.txt
Hi Team!

Add the file to the staging area and commit the changes:

git add erlkoenig.txt

git commit --message "Initial text file"

Output
$ git commit --message "Initial text file"
[feature-teamX 4589ffe] Initial text file
 1 file changed, 1 insertion(+)
 create mode 100644 erlkoenig.txt

After the branch was created locally, you will now push it to the remote repository:

git push origin <your_branch_name>

Again, if prompted enter your username with the previously changed new password.

Solution

In case you forgot your branch name, type in git status and you will get an output similiar to this:

$ git status
On branch feature-teamX
nothing to commit, working tree clean

Expected output of the push command:

$ git push origin feature-teamX
Username for 'https://git.gitlab.cloudtrainings.online': your-user
Password for 'https://root@git.gitlab.cloudtrainings.online':
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 498 bytes | 498.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for feature-team1, visit:
remote:   https://git.gitlab.cloudtrainings.online/root/git-training/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature-team1
remote:
To https://git.gitlab.cloudtrainings.online/root/git-training.git
 * [new branch]      feature-team1 -> feature-team1

You forgot that you also commited the ‘first-revision.txt’ file you initialy created in the basics chapter and unintentionally pushed that file as well. No worries, we will delete the file now to have a clean branch !

List the files to see your first-revision file.

ls

$ ls
your-name-first-revision.txt  erlkoenig.txt

Go ahead and delete the ‘first-revision.txt’ file.

rm your-name-first-revision.txt

Add the deletion of the file to the staging area.

git add your-name-first-revision.txt

Commit and push your changes.

git commit --message 'Your-Name delete first-revision file

git push origin <your_branch_name>

The first-revision file is now also gone in the remote repository !

Step 4: Clean up your local repository

The one team member who created the initial branch will now delete the local branch to have the same setup as the other team members. But first switch to the ‘main’ branch to be able to delete your local branch. In the basics chapter we executed the ‘git init’ command with ‘main’ as the initial branch name.

git switch main

Now you can delete the branch:

git branch --delete <your_branch_name>

In case you receive an error message like the following, rerun the delete command with the provided command git branch -D <your_branch_name>:

$ git branch --delete feature-teamX
error: the branch 'feature-teamX' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-teamX'

Step 5: Switch to the newly created branch

@All team members: Please execute the following commands:

Fetch the latest changes from the remote repository.

git fetch

See all created branches with the following command.

git branch --all

Output
$ git branch --all
remotes/origin/feature-teamX
remotes/origin/main

Now, everyone can switch to the branch created by your team member.

git switch <branch_name_of_your_team>

Output
$ git switch feature-teamX
branch 'feature-teamX' set up to track 'origin/feature-teamX'.
Switched to a new branch 'feature-teamX'

Please check with your team members that everyone has the branch checked out locally before moving on to the next exercise.


Start with the poem

Step 1: Create verses

Each participant adds some unique lines (verses) from the poem Der Erlkönig by Johann Wolfgang von Goethe to the file ’erlkoenig.txt’.

Poem
Erlkönig – Johann Wolfgang von Goethe

Team 1

Wer reitet so spät durch Nacht und Wind?
Es ist der Vater mit seinem Kind;
Er hat den Knaben wohn in dem Arm,
Er faβt ihn sicher, er hält ihn warm.

Mein Sohn, was birgst du so bang dein Gesicht?
“Siehst, Vater, du den Erlkönig nicht?
Den Erlenkönig mit Kron und Schweif?”
Mein Sohn, es ist ein Nebelstreif.

Team 2

‘Du liebes Kind, komm, geh mit mir!
Gar schöne Spiele spiel ich mit dir
Manch bunte Blumen sind an dem Strand.
Meine Mutter hat manch gülden Gewand.’

“Mein Vater, mein Vater, und hörest du nicht,
Was Erlenkönig mir leise verspricht?”
Sei ruhig, bleibe ruhig, mein Kind;
In dürren Blättern säuselt der Wind.

Team 3

‘Willst, feiner Knabe, du mit mir gehn?
Meine Töchter solln dich warten schön;
Meine Töchter führen den nächtlichen Reihn,
Und wiegen und tanzen und singen dich ein.’

“Mein Vater, mein Vater, und siehst du nicht dort
Erlkönigs Töchter am düstern Ort?”
Mein Sohn, mein Sohn, ich seh es genau;
Es scheinen die alten Weiden so grau.

Team 4

‘Ich liebe dich, mich reizt deine schöne Gestalt;
Und bist du nicht willig, so brauch ich Gewalt.’
“Mein Vater, mein Vater, jetzt fasst er mich an!
Erlkönig hat mir ein Leids getan!”

Dem Vater grauset’s, er reitet geschwind,
Er hält in Armen das ächzende Kind,
Erreicht den Hof mit Mühe und Not;
In seinen Armen das Kind war tot.

Decide in your team how you divide the verses evenly among each other.

Use the default editor ’nano’ to add your verses. Please remove the first line ‘Hi Team!’ from the initial commit.

nano erlkoenig.txt

Exit nano with Ctrl+X and save it with typing ‘y’ and pressing enter.

Check if the file contains your verses before committing:

cat erlkoenig.txt

Solution

Depending on the verses you’ve been assigned the output looks something like:

$ cat erlkoenig.txt
Wer reitet so spät durch Nacht und Wind?
Es ist der Vater mit seinem Kind;

Commit the changes:

git add erlkoenig.txt

git commit -m "<your_name> adds verses

Step 2: Merge conflict

All team members edited the same file ’erlkoenig.txt’ in the same feature branch and added their verses. Now each participant pushes their changes:

git push origin <branch_name_of_your_team>

Since multiple team members are modifying the same file, merge conflicts will occur.

Hint: If you are the first person who pushes their changes no merge conflicts will occur. You will experience a merge conflict later in the exercise. Please reach out to your team members to see their merge conflicts.

Your output should look like this:

Output
$ git push origin feature-teamX
Username for 'https://git.gitlab.cloudtrainings.online': your-user
Password for 'https://novatec1@git.gitlab.cloudtrainings.online':
To https://git.gitlab.cloudtrainings.online/root/git-training.git
 ! [rejected]        feature-teamX -> feature-teamX (fetch first)
error: failed to push some refs to 'https://git.gitlab.cloudtrainings.online/root/git-training.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Because some team members have already pushed their changes to the same file you will get notified that the remote contains work that you do not have locally. Run the following to get the remote changes:

git pull

You will have a merge conflict.

Output
$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 314 bytes | 314.00 KiB/s, done.
From https://git.gitlab.cloudtrainings.online/root/git-training
   4589ffe..4d2a06b  feature-teamX -> origin/feature-teamX
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

Step 3: Resolve merge conflict

First, use the following commands to get the latest changes from the other team members.

git fetch

git config pull.rebase false

git pull

After using git pull, your output should look like this:

Output
Auto-merging erlkoenig.txt
CONFLICT (content): Merge conflict in erlkoenig.txt
Automatic merge failed; fix conflicts and then commit the result.

If a merge conflict occurs, resolve it using an editor (’nano’).

nano erlkoenig.txt

Output

Depending on the team you are part of and the different pushes of your teammates the output might look like this:

<<<<<<< HEAD
Er hat den Knaben wohn in dem Arm,
Er faβt ihn sicher, er hält ihn warm.
=======
Wer reitet so spät durch Nacht und Wind?
Es ist der Vater mit seinem Kind;
>>>>>>> 4d2a06bbb331feb9d770f773d1e9180992da83b0

Please make sure that the verses are in the correct order (check the poem at the beginning of the exercise for the correct order). Remove the conflict markers ‘=======’ and the lines with ‘«««< HEAD’ and ‘»»»> 4d2a06bbb331feb9d770f773d1e9180992da83b0’.

Solution
Er hat den Knaben wohn in dem Arm,
Er faβt ihn sicher, er hält ihn warm.

Wer reitet so spät durch Nacht und Wind?
Es ist der Vater mit seinem Kind;

Exit and save the file.

You resolved the conflict. It’s time to commit again:

git add erlkoenig.txt

git commit -m "<your_name> resolved conflict

Push the changes:

git push origin <branch_name_of_your_team>

Your changes are now part of the remote repository.


Please find the next part of the poem here Exercise Poem Part 2 .