Skip to content

Commit 8f1e66f

Browse files
committed
Revise L11 & L12
1 parent 78dfc41 commit 8f1e66f

3 files changed

Lines changed: 207 additions & 120 deletions

File tree

11_VersionsverwaltungI.md

Lines changed: 98 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ Eine Versionsverwaltung ist ein System, das zur Erfassung von Änderungen an Dok
105105

106106
Ein Beispiel, wie ein Versionsmanagementsystem die Arbeit von verteilten Autoren unterstützt ist die Implementierung von Wikipedia. Jede Änderung eines Artikels wird dokumentiert. Alle Versionen bilden eine Kette, in der die letzte Version als gültige angezeigt wird. Entsprechend der Angaben kann nachvollzogen werden: wer wann was geändert hat. Damit ist bei Bedarf eine Rückkehr zu früheren Version möglich.
107107

108-
![VersionsmanagementWikipedia](./img/11_VersionsverwaltungI/VersionenVonVersionsverwaltung.png "Versionen des Artikels Versionsverwaltung auf der Webseite Wikipedia")
108+
Schauen Sie sich live an, wie Wikipedia die Versionsgeschichte des Artikels *Versionsverwaltung* verwaltet — jede Bearbeitung ist mit Zeitstempel, Autor und Diff dokumentiert:
109+
110+
<iframe src="https://de.wikipedia.org/w/index.php?title=Versionsverwaltung&action=history" width="100%" height="500px" style="border: 1px solid #ccc;"></iframe>
109111

110112
{{1-2}}
111113
******************************************************************************
@@ -432,15 +434,59 @@ lcs_algo(S1, S2, m, n)
432434
```
433435
@LIA.eval(`["main.py"]`, `none`, `python3 main.py`)
434436

435-
> Erschließen Sie sich den Algorithmus mit einem LLM! Gesucht ist eine grafische Darstellung des Algorithmus, die den Aufbau der Matrix und die Rückverfolgung der LCS zeigt.
437+
**Warum ist das Ergebnis `ADH`?**
438+
439+
LCS steht für *Longest Common **Subsequence*** — nicht *Substring*! Der Unterschied ist entscheidend:
440+
441+
- Eine **Substring** wäre ein zusammenhängender Teil (z. B. `ABC` in `ABCDGH`).
442+
- Eine **Subsequence** ist eine Folge von Zeichen, die in *beiden* Strings in der *gleichen Reihenfolge* vorkommen — aber **nicht zusammenhängend** sein müssen.
443+
444+
Gehen wir Zeichen für Zeichen durch:
445+
446+
```
447+
S1: A B C D G H
448+
S2: A E D F H R
449+
```
450+
451+
Welche Zeichen erscheinen in **beiden** Strings, und zwar in der **gleichen Reihenfolge**?
452+
453+
| Zeichen | Position in S1 | Position in S2 | Reihenfolge konsistent? |
454+
| ------- | -------------- | -------------- | ----------------------- |
455+
| **A** | 0 | 0 ||
456+
| **D** | 3 | 2 | ✓ (kommt nach A) |
457+
| **H** | 5 | 4 | ✓ (kommt nach D) |
458+
459+
Daraus ergibt sich `ADH` — Länge 3.
460+
461+
Die Matrix `L[i][j]` im Python-Code speichert für jedes Präfix-Paar `(S1[:i], S2[:j])` die Länge der jeweils längsten gemeinsamen Subsequence; die Rückverfolgung am Ende rekonstruiert dann die Zeichenfolge selbst.
462+
463+
> **Bezug zur Versionsverwaltung:** Genau das ist das Prinzip hinter `diff` — das Tool findet die längste gemeinsame Subsequence zwischen zwei Dateien und markiert alles, was *nicht* dazugehört, als Änderung (hinzugefügt oder gelöscht).
436464
437465
**Schritt 2: Mischen**
438466

467+
Das LCS-Ergebnis ist die **Grundlage für das Mischen**. Bleiben wir bei unserem Beispiel `S1 = "ABCDGH"` und `S2 = "AEDFHR"` mit LCS = `ADH`:
468+
469+
```
470+
S1: A B C D G H
471+
S2: A E D F H R
472+
LCS: A D H <- gemeinsames Skelett
473+
```
474+
475+
Die LCS bildet das **gemeinsame Skelett** beider Versionen. Alles, was *zwischen* den LCS-Zeichen liegt, ist eine Änderung gegenüber der jeweils anderen Seite:
476+
477+
| Position relativ zur LCS | Nur in S1 (entfernt in S2) | Nur in S2 (hinzugefügt in S2) |
478+
| ------------------------ | -------------------------- | ----------------------------- |
479+
| nach `A`, vor `D` | `B C` | `E` |
480+
| nach `D`, vor `H` | `G` | `F` |
481+
| nach `H` || `R` |
482+
483+
Beim **Mischen** stellt sich nun für jede dieser Lücken die Frage: *Was übernehmen wir?* Wenn beide Seiten an derselben Lücke unterschiedliche Inhalte einfügen (wie `B C` vs. `E`), entsteht ein **Konflikt**.
484+
439485
In der Praxis wird zwischen zwei Szenarien unterschieden:
440486

441-
1. Mischen unabhängiger Dokumente (2-Wege-Mischen) - Ziel ist die Erzeugung eines neuen Dokumentes, dass die gemeinsamen Komponenten und individuelle Teilmengen vereint.
487+
1. Mischen unabhängiger Dokumente (2-Wege-Mischen) - Ziel ist die Erzeugung eines neuen Dokumentes, dass die gemeinsamen Komponenten und individuelle Teilmengen vereint. Die LCS liefert hier direkt das gemeinsame Skelett.
442488

443-
2. Mischen von Dokumenten mit gemeinsamen Ursprung (3-Wege-Mischen) - Ziel ist die Integration möglichst aller Änderungen der neuen Dokumente in eine weiterentwickelte Version des Ursprungsdokumentes
489+
2. Mischen von Dokumenten mit gemeinsamen Ursprung (3-Wege-Mischen) - Ziel ist die Integration möglichst aller Änderungen der neuen Dokumente in eine weiterentwickelte Version des Ursprungsdokumentes. Hier werden *zwei* LCS-Berechnungen durchgeführt: D0↔D1 und D0↔D2. Aus dem Vergleich beider Diffs erkennt das System, ob Änderungen kompatibel sind oder kollidieren.
444490

445491
> Ein Paar von Änderung aus D1 bzw. D2 gegenüber einen Ausgangsdokument D0 kann unverträglich sein, wenn die Abbildung beider Änderungen in einem gemeinsamen Dokument nicht möglich ist. In diesem Fall spricht man von einem Konflikt.
446492
@@ -561,8 +607,8 @@ Die Entwicklungsgeschichte von git ist mit der des Linux Kernels verbunden:
561607
| ---- | -------------------------------------------------------------- |
562608
| 1991 | Änderungen am Linux Kernel via patches und archive files |
563609
| 2002 | Linux Kernel mit dem Tool BitKeeper verwaltet |
564-
| 2005 | Bruch zwischen der vertreibenden Firma und der Linux Community |
565-
| 2023 | Die aktuelle Version ist 2.40.1 |
610+
| 2005 | Bruch zwischen der vertreibenden Firm> Erschließen Sie sich den Algorithmus mit einem LLM! Gesucht ist eine grafische Darstellung des Algorithmus, die den Aufbau der Matrix und die Rückverfolgung der LCS zeigt.a und der Linux Community |
611+
| 2026 | Die aktuelle Version ist 2.43.x |
566612

567613
2005 wurde einen Anforderungsliste für eine Neuentwicklung definiert. Dabei wurde hervorgehoben, dass sie insbesondere sehr große Projekte (Zahl der Entwickler, Features und Codezeilen, Dateien) unterstützen können muss. Daraus entstand `Git` als freie Software zur verteilten Versionsverwaltung von Dateien.
568614

@@ -722,69 +768,48 @@ Nun wird es aber interessanter! Lassen Sie uns jetzt aber zwischen den Varianten
722768

723769
`git reset` löscht die Historie bis zu einem Commit. Adressieren können wir die Commits relativ zum `HEAD` `git reset HEAD~1` oder mit der jeweiligen ID `git reset <commit-id>`.
724770

725-
Wichtig sind dabei die Parameter des Aufrufes:
726-
727-
| Attribut | | Vorgang |
728-
| ------------------- | ------- | ------------------------------------------------------------- |
729-
| `git reset --soft` | | uncommit changes, changes are left staged (index). |
730-
| `git reset --mixed` | default | uncommit + unstage changes, changes are left in working tree. |
731-
| `git reset --hard` | | uncommit + unstage + delete changes, nothing left. |
732-
733771
``` text @ExplainGit.eval
734772
git commit -m V1
735773
git commit -m V2
736774
git commit -m V3
737775
```
738776

777+
Wichtig sind dabei die Parameter des Aufrufes. Erinnern Sie sich an die drei Ebenen aus dem Zustandsmodell: **Arbeitsverzeichnis** (Ihre Dateien auf der Platte), **Staging-Bereich** (das, was mit `git add` markiert wurde) und **Repository** (die committeten Versionen). Die drei Reset-Varianten unterscheiden sich darin, *wie weit* sie diese Ebenen zurückdrehen:
778+
779+
| Attribut | Standard? | Repository (HEAD) | Staging-Bereich | Arbeitsverzeichnis | Wirkung in Worten |
780+
| ------------------- | ----------------- | ----------------- | --------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
781+
| `git reset --soft` | | zurückgesetzt | unverändert | unverändert | Der Commit wird "rückgängig gemacht" — die Änderungen liegen aber weiterhin staged bereit. **Anwendungsfall:** Sie wollen einen Commit aufteilen oder neu formulieren. |
782+
| `git reset --mixed` | ✓ (Default) | zurückgesetzt | zurückgesetzt | unverändert | Commit und Staging werden zurückgenommen, Ihre Datei-Änderungen bleiben aber erhalten. **Anwendungsfall:** Sie wollen `git add`-Entscheidungen neu treffen. |
783+
| `git reset --hard` | | zurückgesetzt | zurückgesetzt | zurückgesetzt | Alles wird auf den Stand des Ziel-Commits zurückgesetzt — **Ihre lokalen Änderungen gehen verloren!** ⚠️ **Anwendungsfall:** Sie wollen einen Fehlversuch komplett wegwerfen. |
784+
785+
**Konkretes Mini-Szenario:** Sie haben gerade `git commit -m "Add feature X"` gemacht und merken sofort, dass die Commit-Message Murks ist:
786+
787+
- `git reset --soft HEAD~1` → Commit weg, Dateien bleiben staged. Sie können sofort mit einer besseren Message neu committen.
788+
- `git reset --mixed HEAD~1` → Commit weg, Staging weg. Sie können einzelne Dateien selektiv neu staged committen.
789+
- `git reset --hard HEAD~1` → Commit weg, Dateien zurückgesetzt. **Alle Änderungen seit dem Vor-Commit sind gelöscht.**
790+
791+
> **Merke:** `--hard` ist eine der wenigen Git-Operationen, die wirklich Daten *vernichten* kann. Wenn Sie unsicher sind, prüfen Sie vorher mit `git status` und `git log`, was Sie verlieren würden.
792+
793+
739794
**Variante 2 - Revert**
740795

741-
Häufig möchte man nicht die gesamte Historie zurückgehen und alle Änderungen verwerfen, sondern vielmehr eine Anpassung zurücknehmen und deren Auswirkung korrigieren. Eine Anpassung würde aber bedeuten, dass alle nachgeordneten Commits angepasst werden müssten.
796+
Häufig möchte man nicht die gesamte Historie zurückgehen und alle Änderungen verwerfen, sondern vielmehr eine einzelne Anpassung zurücknehmen. Genau das leistet `git revert`: Statt einen Commit aus der Historie zu *entfernen*, erzeugt es einen **neuen Commit**, der die Änderungen des Ziel-Commits aufhebt.
797+
798+
| Aspekt | `git reset` | `git revert` |
799+
| ------------------- | ---------------------------------------- | ------------------------------------------------------- |
800+
| Wirkung auf Historie | **Schreibt sie um** — Commits verschwinden | **Erweitert sie** — neuer "Anti-Commit" |
801+
| Sicher für Remote? | ❌ Nein (Force-Push nötig) | ✓ Ja (ganz normaler Push) |
802+
| Anwendung | Lokale Fehlversuche wegwerfen | Bereits gepushte Commits zurücknehmen |
803+
804+
> **Faustregel:** Geteilte Historie nie umschreiben. Sobald ein Commit gepusht ist und andere damit arbeiten könnten, ist `revert` der einzige saubere Weg.
742805
743806
``` text @ExplainGit.eval
744807
git commit -m V1
745808
git commit -m V2
746809
git commit -m V3
747810
```
748811

749-
**Variante 3 - Rebase**
750-
751-
Ein sehr mächtiges Werkzeug ist der interaktive Modus von `git rebase`. Damit kann die
752-
Geschichte neugeschrieben werden, wie es die git Dokumentation beschreibt. Im Grund können Sie damit Ihre Versionsgeschichte "aufräumen". Einzelne Commits umbenennen, löschen oder fusionieren. Dafür besteht ein eigenes Interface, dass Sie mit dem folgenden Befehl aufrufen können:
753-
754-
```console
755-
▶git rebase -i HEAD~5
756-
757-
pick d2a06e4 Update main.yml
758-
pick 78839b0 Reconfigures checkout
759-
pick f70cfc7 Replaces wildcard by specific filename
760-
pick 05b76f3 New pandoc command line
761-
pick c56a779 Corrects md filename
762-
763-
# Rebase a3b07d4..c56a779 onto a3b07d4 (5 commands)
764-
#
765-
# Commands:
766-
# p, pick = use commit
767-
# r, reword = use commit, but edit the commit message
768-
# e, edit = use commit, but stop for amending
769-
# s, squash = use commit, but meld into previous commit
770-
# f, fixup = like "squash", but discard this commit's log message
771-
# x, exec = run command (the rest of the line) using shell
772-
# d, drop = remove commit
773-
#
774-
# These lines can be re-ordered; they are executed from top to bottom.
775-
#
776-
# If you remove a line here THAT COMMIT WILL BE LOST.
777-
#
778-
# However, if you remove everything, the rebase will be aborted.
779-
#
780-
# Note that empty commits are commented out
781-
```
782-
783-
Als Anwendungsfall habe ich mir meine Aktivitäten im Kontext einiger Experimente
784-
mit den GitHub Actions, die im nächsten Abschnitt kurz eingeführt werden, ausgesucht.
785-
Schauen wir zunächst auf den ursprünglichen Stand. Alle Experimente drehten sich darum, eine Datei anzupassen und dann auf dem Server die Korrektheit zu testen.
786-
787-
> Wir werden `git rebase` im Zusammenhang mit der Arbeit in Branches wieder aufgreifen.
812+
> Eine dritte Variante — `git rebase` — werden wir in Versionsverwaltung II im Kontext der Arbeit mit Branches kennenlernen.
788813
789814
### Was kann schief gehen?
790815

@@ -796,7 +821,8 @@ Schauen wir zunächst auf den ursprünglichen Stand. Alle Experimente drehten si
796821
... wir wollen schnell sein und fügen alle Änderungen als staged ein
797822
git add *
798823
... Aber halt! Die beiden Dinge gehören doch nicht zusammen!
799-
git reset
824+
git reset # default Konfiguration entspricht reset --mixed HEAD
825+
... Alle Änderungen sind jetzt unstaged, wir können sie jetzt selektiv hinzufügen
800826
```
801827

802828
2. **Ups, eine Datei in der Version vergessen! (Unvollständiger Commit)**
@@ -916,7 +942,7 @@ create origin
916942

917943
Die Editoren unterstützen den Nutzer bei der Arbeit, in dem Sie die eigentlichen Commandozeilentools rund um die Arbeitsfläche anordnen.
918944

919-
![ScreenShot](./img/12_VersionsverwaltungII/ArbeitmitGitImEditor.png)<!-- width="100%" -->
945+
![ScreenShot](./img/11_VersionsverwaltungI/ArbeitmitGitImEditor.png)<!-- width="100%" -->
920946

921947
| Bereich | Bedeutung |
922948
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
@@ -930,51 +956,37 @@ Die identischen Informationen lassen sich auch auf der Kommandozeile einsehen:
930956

931957
```console
932958
▶git status
933-
On branch SoSe2020dev
934-
Your branch is up to date with 'origin/SoSe2020dev'.
959+
On branch master
960+
Your branch is up to date with 'origin/master'.
935961

936962
Changes to be committed:
937-
(use "git reset HEAD <file>..." to unstage)
963+
(use "git restore --staged <file>..." to unstage)
938964

939965
modified: .gitignore
940966

941967
Changes not staged for commit:
942-
(use "git add/rm <file>..." to update what will be committed)
943-
(use "git checkout -- <file>..." to discard changes in working directory)
944-
968+
(use "git add <file>..." to update what will be committed)
969+
(use "git restore <file>..." to discard changes in working directory)
945970

946-
modified: 02_Versionsverwaltung.md
947-
deleted: 03_ContinuousIntegration.md
971+
modified: 11_VersionsverwaltungI.md
972+
deleted: alt_ContinuousIntegration.md
948973

949974
Untracked files:
950975
(use "git add <file>..." to include in what will be committed)
951976

952-
03_VersionsverwaltungII.md
977+
12_VersionsverwaltungII.md
953978
code/
954-
img/03_VersionsverwaltungII/
979+
img/11_VersionsverwaltungI/
955980
```
956981

957982
```console
958-
▶git log
959-
commit d7603554c958c478f1ec600bd3ccea437d91ae9a (HEAD -> SoSe2020dev, origin/SoSe2020dev)
960-
Author: Sebastian Zug <Sebastian.Zug@informatik.tu-freiberg.de>
961-
Date: Thu Apr 9 13:16:38 2020 +0200
962-
963-
First version of L3
964-
965-
commit 39fc168222f4c7a7d062adcaccff17fe34bccbe3
966-
Author: Sebastian Zug <Sebastian.Zug@informatik.tu-freiberg.de>
967-
Date: Thu Apr 9 13:16:12 2020 +0200
968-
969-
First version of L02
970-
971-
commit 350c127c7dfbc61a81edc8bd148f605ee681a07a
972-
973-
Author: Sebastian Zug <Sebastian.Zug@informatik.tu-freiberg.de>
974-
Date: Tue Apr 7 07:01:02 2020 +0200
975-
976-
Final version of L1
977-
....
983+
▶git log --oneline
984+
5b04f0b (HEAD -> master, origin/master) Merge branch 'master'
985+
4563132 Revise L07 and L09
986+
585f88c ci: update LiaScript badge
987+
8143af0 Merge branch 'master'
988+
54dc14e Replace Wildcards
989+
...
978990
```
979991

980992
## Aufgaben

0 commit comments

Comments
 (0)