1 Open Source Entwicklung
a) Suchen Sie sich 2 Open Source Projekte heraus:
i) Welche Lizenz nutzt das Projekt?
- StirlingPDF
- MIT LICENSE
- Langflow-AI
- MIT LICENSE
ii) Wie viele Entwickler:innen sind an dem Projekt ungefähr beteiligt?
- StirlingPDF
- 207
- Langflow-AI
- 203
iii) Welche Relevanz hat das Projekt?
- StirlingPDF
- hohe Relevanz 47.5k Sterne auf Github
- Langflow-AI
- hohe Relevanz 39.5k Sterne auf Github mit 1.122 Usern
b) Warum sollten Sie, falls Sie selber ein Projekt auf GitHub o.Ä. veröffentlichen immer eine Lizenz angeben?
Damit jeder, der das Projekt sieht, weiß was er alles legal mit dem Projekt machen kann. Man zudem Rechte hat, falls jemand den Code unrechtsmäßig benutzt. Lizenzen vereinfachen für andere die Nutzung des Codes, weil klar geregelt ist was sie damit machen können und man selber kann Rechte einschränken um zum Beispiel seine Codebase nicht für kommerzielle Zwecke bereitzustellen. Zudem die Verhinderung von unkontrollierter Weiterentwicklung als proprietäre Software.
c) Informieren Sie sich über SPDX License Identifier.
i) Welches Problem versuchen diese zu lösen?
Basierend der SPDX Seite
”The purpose of the SPDX License List is to enable efficient and reliable identification of such licenses and exceptions in an SPDX document, in source files or elsewhere.”
SPDX erstellt ein SPDX Dokument, welches die Identifizierung der jeweiligen Lizenz für Open-Source Projekte leichter gestaltet.
- Reduziert Mehrdeutigkeiten und Verwirrung, die durch unterschiedliche Lizenznamen oder -versionen entstehen können.
- Ermöglicht die automatische Verarbeitung von Lizenzinformationen durch Tools.
- Fördert die Konsistenz und Transparenz in der Open-Source-Welt.
ii) Warum sollte jede einzelne Datei in einem Projekt eine eigene Lizenz enthalten?
Es kann sein, dass man verschiedene Libraries für verschiendene Module und deren Dateien verwendet, die jeweils verschiedene Lizenzen haben. Mit einer Lizenz für jede Datei kann man so individuell die benötigten Lizenzen für die jeweiligen Module anpassen und gegegebnenfalls für seinen selbst geschriebenen Code eine eigene Lizenz anwenden, die von den anderen abweicht. Es ermöglicht eine genauere Nachverfolgung der Lizenzbedingungen für jede Komponente eines Projekts und hilft bei der Einhaltung der Lizenzpflichten (z.B. Angabe der Urheber:innen, Bereitstellung des Quellcodes).
2 Git I
Verwenden Sie für diese Aufgabe ausschließlich Git auf der Kommandozeile. Dokumentieren Sie die Git-Befehle die Sie jeweils verwendet haben in Ihrer Abgabe.
Führen Sie folgende Schritte aus.
- Erstellen Sie ein neues Git-Repository
git init
- Fügen Sie die Datei Navigation.java hinzu und comitten Sie die Änderung.
git add Navigation.java
git commit -m "feat: add Navigation.java"
- Schreiben Sie JavaDocs für die Methode
computeShortestPathBetweenCities
. Committen Sie die Änderungen anschließend.git add computeShortestPathBetweenCities
git commit -m "docs: add computeShortestPathBetweenCities
- Erstellen Sie einen neuen Branch „refactoring“ und wechseln Sie auf diesen.
git switch -c "refactoring"
- Ersetzen Sie nun alle
System.out.println
durch Ihre eigene Methodeprint
(diese kann selbst wiederum einfachSystem.out.println
aufrufen). Committen Sie die Änderungen anschließend (achten Sie darauf, dass Sie auf dem refactoring Branch sind).git commit -am "refactor: change sout to print"
- Wechseln Sie zurück zum Branch „main“.
git switch main
- Passen Sie nun die Fehlermeldung in Zeile 34 an, sodass diese auch die Nachricht der Exception enthält. Committen Sie Ihre Änderungen.
git commit -am "feat: add errormsg to exception"
- Mergen Sie nun den Branch „refactoring“ zurück in den Branch „main“. Erstellen Sie dafür einen Merge-Commit. Lösen Sie auch eventuelle Merge-Konflikte auf.
git merge refactoring
3 Git II
Verwenden Sie für diese Aufgabe ausschließlich Git auf der Kommandozeile. Dokumentieren Sie die Git-Befehle die Sie jeweils verwendet haben in Ihrer Abgabe.
Starten Sie jede Teilaufgabe mit einem leeren Repository. Erstellen Sie dann drei Commits. Der erste fügt eine neue Textdatei mit einer einzigen Zeile „a“ hinzu, der zweite hängt die Zeilen „b“ und „c“ an die Datei an und der dritte die Zeile „d“.
a) Rollen Sie die Änderungen bis auf den ersten Commit zurück.
git init
git add datei.txt
git commit -m "first commit a"
git add datei.txt
git commit -m "second commit b und c"
git add datei.txt
git commit -m "third commit d"
git reset --hard HEAD~2
b) Schreiben Sie die Historie so um, dass der zweite Commit (und seine Änderungen) verschwinden. Versuch Sie dabei den dritten Commit zu erhalten, statt die Änderungen manuell zu wiederholen und neu zu comitten.
git init
git add datei.txt
git commit -m "first commit a"
git add datei.txt
git commit -m "second commit b"
git add datei.txt
git commit -m "third commit c"
git rebase -i HEAD~3
# (Im Editor: Zeile des zweiten Commits löschen oder mit `drop` markieren)
c) Schreiben Sie die Historie so um, dass im ersten Commit die Zeile „a2“ in die neue Datei geschrieben wurde.
git init
git add datei.txt
git commit -m "first commit a"
git add datei.txt
git commit -m "second commit b"
git add datei.txt
git commit -m "third commit c"
git rebase -i --root
# (Im Editor: `pick` des ersten Commits zu `edit` ändern)
git add datei.txt
git commit --amend --no-edit
git rebase --continue
U Git III
a) Welche Rolle hat der HEAD
-Verweis in Git?
Der HEAD
verweis in Git spielt eine sehr bedeutsame Rolle, er gibt wieder was der aktuelle Pointer ist. Norrmalerweise zeigt der HEAD auf den aktuellsten Commit, man kann mit git chekout
etc aber auch detached HEADs benutzen
b) Erklären Sie den Unterschied zwischen 3-Way-Merge, Fast-Forward-Merge und Merge mit rebase.
- Fast Forward, wird benuzt um einfach den HEAD von einem alten Commit auf einen neuen Commit zu setzen. Der neuere Commit hat hierbei Changes, die ohne Merge Konflikt als HEAD akzeptiert werden
- 3-Way-Merge, checkt zwischen dem base-branch und der Änderung welcher von den Entwicklern durchgeführt wurde. Falls es keine mutual changes gibt, wird der merge ohne Konflikte zusammengeführt, sonst muss ein merge conflict resolved werden, was dazu dient verschiedene changes auf verschiedenen Branches gut zusammenzuführen
- Rebase verschiebt die Commits eines Branches auf eine andere Basis, wodurch eine lineare Historie entsteht, als hätte die gesamte Entwicklung auf dem Zielbranch stattgefunden. Anders als beim Mergen wird kein Merge-Commit erzeugt. Rebase fasst Commits nicht standardmäßig zusammen.
c) Weshalb wird ein pull
meist mit der Option rebase
ausgeführt?
Wenn man etwas pulled, aktualisiert man sein lokales git mit dem remote Repository. Es macht keinen Sinn diese changes als commit zu vermerken, man verwendet einfach rebase um so eine sauberere Commit-History zu behalten und unnötige Commits zu vermeiden
d) Was ist ein Merge-Konflikt? Unter welchen Umständen kann dieser auftreten?
- Merge Conflicts entstehen wenn mehrere Entwickler Änderungen des gleichen Codeabschnittes durchführen und beide beispielsweise in main mergen wollen. Git weiß dann nicht, welche Version der beiden Versionen in main zu mergen ist und ein Entwickler muss manuell angeben, welche Änderungen zu benuzten sind
K Versionskontrolle
In dieser Aufgabe erhalten Sie zur Selbstkontrolle eine Bewertung in Form von Punkten. Die maximale Punktzahl ist 10. Diese Punkte dienen lediglich der Einschätzung Ihrer Lösung und sind keine Bonuspunkte.
-
Ordnen Sie die Zustände des Repositories in chronologischer Reihenfolge an.
- (c) Gamma
- (b) Beta
- (d) Delta
- (a) Alpha
-
Ordnen Sie die git-Befehle (i)-(viii) den Zuständen des repositories (a)-(d) zu. Gehen Sie davon aus, dass zu beginn noch kein git repository angelegt ist. Jeder Befehl (i)-(viii) wird genau einmal benötigt. Es können pro Zustand mehrere git-Befehle verwendet werden: Geben Sie in diesem Fall die korrekte Reihenfolge der Befehle an. Berücksichtigen Sie die Reihenfolge aus a), wo dies notwendig ist.
git init
git commit
git commit
git switch -c foo
git commit
git switch main
git commit0
git merge foo
-
Erklären Sie die Begriffe „Branch“ und „Checkout“ in einem Versionskontrollsystem.
- Branch
- Ist ein Zweig, auf dem Code Commit für Commit erweitert wird. Auf dem main branch ist normalerweise der funktionstüchtige Code, wobei auf beispielsweise
feature-branches
oder anderen branches welche von jeweiligen Mitgliedern eines Repos erstellt werden können Änderungen in einem isolierten Zweig hergestellt werden ohne den main-branch zu beeinflussen. Erst bei einem Merge oder rebase wird der parallel geführte Zweig in den main branch geführt (oder im Falle eines rebases übernommen)
- Ist ein Zweig, auf dem Code Commit für Commit erweitert wird. Auf dem main branch ist normalerweise der funktionstüchtige Code, wobei auf beispielsweise
- Checkout
- Ist ein Git command um in der Git-Commit-Historie verschiedene Commands anzuschauen und die Codebase von dem jeweiligen Code
abzuchecken
. Mitgit checkout
kann man zudem auch auf branches zugreifen und diese anschauen.
- Ist ein Git command um in der Git-Commit-Historie verschiedene Commands anzuschauen und die Codebase von dem jeweiligen Code
(i)
git commit
(iii)git commit
(v)git init
(vii)git switch -c foo
(ii)
git commit
(iv)git commit
(vi)git merge foo
(viii)git switch main
- Branch