Versionsverwaltung
und Git

Softwaretechnik Tutorium – WiSe 2017/2018
2017-10-20
$ git config --global user.name "Natanael Arndt"
$ git config --global user.email "arndt@informatik.uni-leipzig.de"
https://white-gecko.github.io/GitTutorial
cc-by-sa
https://white-gecko.github.io/GitTutorial
## Warum brauche ich eine Versionsverwaltung? * Protokollierung der Softwareentwicklung * Archivierung der Softwareversionen * Wiederherstellung eines beliebigen Entwicklungstands * Synchronisation des Entwicklungstands mit Kollegen * Verschiedene Entwicklungstände zum „Ausprobieren“ https://white-gecko.github.io/GitTutorial
## Systemvoraussetzungen * Welches Betriebssystem habt ihr? * Linux, Windows, MacOS, BSD, … * Welche IDEs verwendet ihr? * Atom, Eclipse, Sublime, … * Habt ihr schon Git installiert? * Wichtig direkt auf der Konsole: … https://white-gecko.github.io/GitTutorial
## Installation [https://git-scm.com/book/de/v1/Los-geht’s-Git-installieren](https://git-scm.com/book/de/v1/Los-geht%E2%80%99s-Git-installieren) ```bash you@linux:~$ apt-get install git # Debian GNU/Linux u.ä. you@linux:~$ yum install git-core # Yellowdog, Fedora, openSUSE, … you@macos:~$ brew install git C:\> # Windows: http://msysgit.github.com/ ``` https://white-gecko.github.io/GitTutorial
* [Lektion 1](#lektion-1) (2017-10-13) * [Wiederholung Lektion 1](#wdh-lektion-1) (2017-10-20) * [Lektion 2](#lektion-2) (2017-10-20) * [Lektion 3](#lektion-3) https://white-gecko.github.io/GitTutorial
# Lektion 1 ## Lernziele für heute * Git Repository anlegen * Dateien unter Versionskontrolle stellen * Commits hinzufügen * Änderungen übertragen * GitLab Repository anlegen Note: - Den Studenten mitteilen, dass sie den Folien folgen sollen und die Beipiele nachvollziehen sollen
## Geschichte: Lokaler Ansatz * Versionen der Entwicklung liegen lokal vor * Zugriff auf Versionen ist schnell * Versionen können verglichen werden * Kein Austausch mit Mitarbeitern

Geschichte: Zentraler Ansatz

  • Änderungen werden an einen zentralen Server übertragen
  • Austausch mit Mitarbeitern
  • Zugriff auf Versionen ist langsamer
  • Es muss ein Konsens hergestellt werden
  • Rudimentäre Unterstützung für Branches
  • Bsp. Concurrent Versions System (CVS), Subversion (SVN)

Geschichte: Verteilerter Ansatz

  • Es können mehrere Server existieren
  • Lokale Version beinhaltet die komplete Versionsgeschichte
  • Zugriff auf Versionen ist schnell
  • Es muss kein Konsens existieren
  • Beliebige Branches auf unterschiedlichen Systemen erlaubt
  • Bsp. Mercurial, Bazar, …, Git

Git

  • 2005 von Linus Torvalds begonnen
  • … um BitKeeper für die Kernel Entwicklung zu ersetzen
  • Aktuell sehr weit verbreitet: GitHub, GitLab, Bitbucket, …
  • Version 2.14.2 (2017-09-22)
  • https://www.git-scm.com/

git init

  • Initialisieren eines neuen leeren Repositories
$ cd
$ mkdir git-tutorial
$ cd ~/git-tutorial
$ git init repo
Initialisierte leeres Git-Repository in
/home/natanael/git-tutorial/repo/.git/

.git

  • Was liegt in dem versteckten Ordner
$ cd ~/git-tutorial/repo
$ ls

$ ls -a
.  ..  .git
$ cd .git
$ ls
branches  config  description  HEAD  hooks  info  objects  refs
what's inside your .git directory

git status

  • Was ist in meinem Repository los?
$ cd ~/git-tutorial/repo
$ git status
Auf Branch master

Initialer Commit

nichts zu committen (Erstellen/Kopieren Sie Dateien und benutzen
Sie "git add" zum Beobachten)

git add

  • Eine Datei unter Versionskontrolle stellen
$ cd ~/git-tutorial/repo
$ echo "Hallo Git" > file.txt
$ git status
Auf Branch master

Initialer Commit

Unbeobachtete Dateien:
(benutzen Sie "git add <Datei>...", um die Änderungen zum
Commit vorzumerken)

file.txt

nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien
(benutzen Sie "git add" zum Beobachten)

git add …

$ git add file.txt
$ git status
Auf Branch master

Initialer Commit

zum Commit vorgemerkte Änderungen:
(benutzen Sie "git rm --cached <Datei>..." zum Entfernen aus
derStaging-Area)

neue Datei:     file.txt

git commit (Konfiguration)

  • Vor dem ersten Commit muss der Namen und die E-Mail des commiters konfiguriert werden
$ git config --global user.name "Natanael Arndt"
$ git config --global user.email "arndt@informatik.uni-leipzig.de"

git commit

$ git commit -m "Hallo Git"
[master (Basis-Commit) 6b7add4] Hallo Git
1 file changed, 1 insertion(+)
create mode 100644 file.txt
$ git status
Auf Branch master
nichts zu committen, Arbeitsverzeichnis unverändert

git commit …

$ echo "again" >> file.txt
$ git status
Auf Branch master
Änderungen, die nicht zum Commit vorgemerkt sind:
(benutzen Sie "git add <Datei>...", um die Änderungen zum
Commit vorzumerken)
(benutzen Sie "git checkout -- <Datei>...", um die Änderungen
im Arbeitsverzeichnis zu verwerfen)

geändert:       file.txt

keine Änderungen zum Commit vorgemerkt (benutzen Sie "git add"
und/oder "git commit -a")
$ git add file.txt

git commit …

$ git commit -m "again"
[master 0a777cb] again
1 file changed, 1 insertion(+)
$ git status
Auf Branch master
nichts zu committen, Arbeitsverzeichnis unverändert

git log

$ git log
commit 0a777cba46cd556a1246d033e0b11dedbfee6815
Author: Natanael Arndt <arndt@informatik.uni-leipzig.de>
Date:   Fri Dec 16 01:55:56 2016 +0100

again

commit 6b7add4815e9c99d1f3f44c03cea58339b408f4d
Author: Natanael Arndt <arndt@informatik.uni-leipzig.de>
Date:   Fri Dec 16 01:49:44 2016 +0100

Hallo Git

git push (und git remote)

  • Dient zur aktiven Übertragung eines Branches an ein entferntes Repository
$ cd ~/git-tutorial/remote-repo
$ git init --bare remote-repo
Initialisierte leeres Git-Repository in
/home/natanael/git-tutorial/remote-repo
$ cd remote-repo
$ ls -a
.   branches  description  hooks  objects
..  config    HEAD         info   refs
$ git log
fatal: bad default revision 'HEAD'

git push (und git remote)

  • Zur Übertragung muss das entfernte Repository als remote eingetragen werden
$ cd ~/git-tutorial/repo
$ git remote add anderes ../remote-repo
$ git remote -v
anderes	../remote-repo (fetch)
anderes	../remote-repo (push)
$ git push --set-upstream anderes master
Zähle Objekte: 6, Fertig.
Delta compression using up to 4 threads.
Komprimiere Objekte: 100% (2/2), Fertig.
Schreibe Objekte: 100% (6/6), 444 bytes | 0 bytes/s, Fertig.
Total 6 (delta 0), reused 0 (delta 0)
To ../remote-repo
* [new branch]      master -> master

--set-upstream bzw. -u ist nur einmal notwendig, um den Branch dem remote Branch zuzuordnen. Alternativ git branch --set-upstream-to=anderes/master.

git push (und git remote)

$ cd ~/git-tutorial/remote-repo
$ git log
commit 0a777cba46cd556a1246d033e0b11dedbfee6815
Author: Natanael Arndt <arndt@informatik.uni-leipzig.de>
Date:   Fri Dec 16 01:55:56 2016 +0100

again

commit 6b7add4815e9c99d1f3f44c03cea58339b408f4d
Author: Natanael Arndt <arndt@informatik.uni-leipzig.de>
Date:   Fri Dec 16 01:49:44 2016 +0100

Hallo Git
## Git Lab ![](img/gitlab-1.png)
![](img/gitlab-2.png)
![](img/gitlab-3.png)
## Wiederholung Lektion 1 * git init * git status * git commit * git log * git push
# Git Konfiguration * Vor dem ersten Commit muss der Namen und die E-Mail des commiters konfiguriert werden ```bash $ git config --global user.name "Natanael Arndt" $ git config --global user.email "arndt@informatik.uni-leipzig.de" ``` Überprüfen mit: ```bash $ git config --global user.name $ git config --global user.email ```
# git init * Initialisieren eines neuen leeren Repositories ```bash $ cd $ mkdir git-tutorial $ cd ~/git-tutorial $ git init repo Initialisierte leeres Git-Repository in /home/natanael/git-tutorial/repo/.git/ ```
# git status * Was ist in meinem Repository los? ```bash $ cd ~/git-tutorial/repo $ git status Auf Branch master Initialer Commit nichts zu committen (Erstellen/Kopieren Sie Dateien und benutzen Sie "git add" zum Beobachten) ```
# git add * Eine Datei unter Versionskontrolle stellen ``` $ # PWD=~/git-tutorial/repo $ echo "Hallo Git" > file.txt $ git status Auf Branch master Initialer Commit Unbeobachtete Dateien: (benutzen Sie "git add <Datei>...", um die Änderungen zum Commit vorzumerken) file.txt nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien (benutzen Sie "git add" zum Beobachten) ```
# git add … ```bash $ # PWD=~/git-tutorial/repo $ git add file.txt $ git status Auf Branch master Initialer Commit zum Commit vorgemerkte Änderungen: (benutzen Sie "git rm --cached <Datei>..." zum Entfernen aus derStaging-Area) neue Datei: file.txt ```
# git log ```bash $ # PWD=~/git-tutorial/repo $ git log commit 0a777cba46cd556a1246d033e0b11dedbfee6815 Author: Natanael Arndt <arndt@informatik.uni-leipzig.de> Date: Fri Dec 16 01:55:56 2016 +0100 again commit 6b7add4815e9c99d1f3f44c03cea58339b408f4d Author: Natanael Arndt <arndt@informatik.uni-leipzig.de> Date: Fri Dec 16 01:49:44 2016 +0100 Hallo Git $ # aus git log kommt man mit 'q' raus ```
![](img/gitlab-4.png)

git push (und git remote)

  • Zur Übertragung muss das entfernte Repository als remote eingetragen werden
# PWD=~/git-tutorial/repo
$ git remote add gitlab ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git
$ git remote -v
gitlab	ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git (fetch)
gitlab	ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git (push)
$ git push --set-upstream gitlab master
Zähle Objekte: 6, Fertig.
Delta compression using up to 4 threads.
Komprimiere Objekte: 100% (2/2), Fertig.
Schreibe Objekte: 100% (6/6), 442 bytes | 0 bytes/s, Fertig.
Total 6 (delta 0), reused 0 (delta 0)
To ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git
* [new branch]      master -> master

--set-upstream bzw. -u ist nur einmal notwendig, um den Branch dem remote Branch zuzuordnen. Alternativ git branch --set-upstream-to=anderes/master.

# Lektion 2 ## Lernziele für heute * Repositories und Änderungen Herunterladen * Branching * Merging * Merge Konflikte * Mit anderen Teammitgliedern zusammenarbeiten Note: - Den Studenten mitteilen, dass sie den Folien folgen sollen und die Beipiele nachvollziehen sollen

git clone

  • Dient zur Replikation eines entfernten Repositories
$ cd ~/git-tutorial/
$ git clone ifigit@git.….de:arndt/git-tutorial.git local/
Klone nach 'local'...
remote: Zähle Objekte: 6, Fertig.
remote: Komprimiere Objekte: 100% (2/2), Fertig.
remote: Total 6 (delta 0), reused 0 (delta 0)
Empfange Objekte: 100% (6/6), Fertig.
Prüfe Konnektivität... Fertig.
$ cd local/
$ ls -a
.  ..  file.txt  .git
$ git remote -v
origin	ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git (fetch)
origin	ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git (push)

git clone und ein neuer Beitrag

$ # PWD=~/git-tutorial/local
$ echo "Beitrag" > file2.txt
$ git status
Auf Branch master
Ihr Branch ist auf dem selben Stand wie 'origin/master'.
Unbeobachtete Dateien:
(benutzen Sie "git add <Datei>...", um die Änderungen zum
Commit vorzumerken)

file2.txt

nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien
(benutzen Sie "git add" zum Beobachten)

… git add …

$ # PWD=~/git-tutorial/local
$ git add file2.txt
$ git status
Auf Branch master
Ihr Branch ist auf dem selben Stand wie 'origin/master'.
zum Commit vorgemerkte Änderungen:
(benutzen Sie "git reset HEAD <Datei>..." zum Entfernen aus
der Staging-Area)

neue Datei:     file2.txt

… git commit …

$ # PWD=~/git-tutorial/local
$ git commit -m "Ein neuer Beitrag"
[master a7155b7] ein neuer Beitrag
1 file changed, 1 insertion(+)
create mode 100644 file2.txt
$ git status
Auf Branch master
Ihr Branch ist vor 'origin/master' um 1 Commit.
(benutzen Sie "git push", um lokale Commits zu publizieren)
nichts zu committen, Arbeitsverzeichnis unverändert

… git push

$ # PWD=~/git-tutorial/local
$ git push
Zähle Objekte: 3, Fertig.
Delta compression using up to 4 threads.
Komprimiere Objekte: 100% (2/2), Fertig.
Schreibe Objekte: 100% (3/3), 280 bytes | 0 bytes/s, Fertig.
Total 3 (delta 0), reused 0 (delta 0)
To ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git
0a777cb..a7155b7  master -> master
$ git status

git fetch

$ cd ~/git-tutorial/repo/
$ ls -a
.  ..  file.txt  .git
$ git fetch gitlab
remote: Zähle Objekte: 3, Fertig.
remote: Komprimiere Objekte: 100% (2/2), Fertig.
remote: Total 3 (delta 0), reused 0 (delta 0)
Entpacke Objekte: 100% (3/3), Fertig.
Von ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git
0a777cb..a7155b7  master     -> gitlab/master
$ ls -a
.  ..  file.txt  .git

git fetch

$ cd ~/git-tutorial/repo/
$ ls -a
.  ..  file.txt  .git
$ git fetch gitlab
remote: Zähle Objekte: 3, Fertig.
remote: Komprimiere Objekte: 100% (2/2), Fertig.
remote: Total 3 (delta 0), reused 0 (delta 0)
Entpacke Objekte: 100% (3/3), Fertig.
Von ifigit@git.informatik.uni-leipzig.de:arndt/git-tutorial.git
0a777cb..a7155b7  master     -> gitlab/master
$ ls -a
.  ..  file.txt  .git

git fetch und git merge

$ # PWD=~/git-tutorial/repo
$ git status
Auf Branch master
Ihr Branch ist zu 'gitlab/master' um 1 Commit hinterher, und kann
vorgespult werden.
(benutzen Sie "git pull", um Ihren lokalen Branch zu
aktualisieren)
nichts zu committen, Arbeitsverzeichnis unverändert
$ git merge gitlab/master
Aktualisiere 0a777cb..a7155b7
Fast-forward
file2.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 file2.txt

git fetch und git merge

$ # PWD=~/git-tutorial/repo
$ git status
Auf Branch master
Ihr Branch ist zu 'gitlab/master' um 1 Commit hinterher, und kann
vorgespult werden.
(benutzen Sie "git pull", um Ihren lokalen Branch zu
aktualisieren)
nichts zu committen, Arbeitsverzeichnis unverändert
$ git merge gitlab/master
Aktualisiere 0a777cb..a7155b7
Fast-forward
file2.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 file2.txt

git fetch und git merge

$ # PWD=~/git-tutorial/repo
$ git status
Auf Branch master
Ihr Branch ist auf dem selben Stand wie 'gitlab/master'.
nichts zu committen, Arbeitsverzeichnis unverändert
$ ls -a
.  ..  file2.txt  file.txt  .git

git fetch + git merge
= git pull

$ # PWD=~/git-tutorial/repo
$ git pull
Aktualisiere a7155b7..910e6f9
Fast-forward
file2.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ ls -a
.  ..  file2.txt  file.txt  .git

branch

  • Mit git ist eine Verzweigung der Entwicklung einfach möglich
$ cd ~/git-tutorial/local/
$ git branch feature
$ git branch
feature
* master
$ echo "beitrag auf master" >> file.txt
$ git add file.txt
$ git commit -m "beitrag auf master"
[master 3ff104e] beitrag auf master
1 file changed, 1 insertion(+)

branch

$ # PWD=~/git-tutorial/local
$ git checkout feature
$ git branch
* feature
master
$ echo "beitrag auf feature" >> file2.txt
$ git add file2.txt
$ git commit -m "beitrag auf feature"
[master 3ff104e] beitrag auf master
1 file changed, 1 insertion(+)

git merge

$ # PWD=~/git-tutorial/local
$ git checkout master
$ git branch
feature
* master
$ git merge feature # vim -> :wq
Aktualisiere 3ff104e..85de3a4
Fast-forward
file2.txt | 1 +
1 file changed, 1 insertion(+)
$ tail -n 1 file*
==> file2.txt <==
beitrag auf feature

==> file.txt <==
beitrag auf master

Konflikte

  • Merge Konflikte können auftreten, wenn zwei Bearbeiterinnnen oder Bearbeiter an der gleichen Stelle in der gleichen Datei Änderungen durchführen
  • Ein Push kann verweigert werden (reject), wenn eine lokale Änderung durch eine Entfernte Änderung überholt wurde (divergiert)
# Merge Konflikt ```bash $ # PWD=~/git-tutorial/local $ echo "konflikt von master" >> file.txt $ git add file.txt $ git commit -m "konflikt von master" $ git checkout feature $ echo "konflikt von feature" >> file.txt $ git add file.txt $ git commit -m "konflikt von feature" $ git checkout master ``` ```bash $ # in branch master $ # in branch feature $ cat file.txt $ cat file.txt Hallo Git Hallo Git again again beitrag auf master konflikt von feature konflikt von master ```
# Merge durchführen ```bash $ git merge feature automatischer Merge von file.txt KONFLIKT (Inhalt): Merge-Konflikt in file.txt Automatischer Merge fehlgeschlagen; beheben Sie die Konflikte und committen Sie dann das Ergebnis. $ git status Auf Branch master … (beheben Sie die Konflikte und führen Sie "git commit" aus) Nicht zusammengeführte Pfade: (benutzen Sie "git add/rm <Datei>...", um die Auflösung zu markieren) von beiden geändert: file.txt keine Änderungen zum Commit vorgemerkt (benutzen Sie "git add" und/oder "git commit -a") ```

Merge Konflikt

$ cat file.txt
Hallo Git
again
<<<<<<< HEAD
beitrag auf master
konflikt von master
=======
konflikt von feature
>>>>>>> feature
$ vim file.txt
$ cat file.txt
Hallo Git
again
beitrag auf master
konflikt von master und feature behoben
$ git add file.txt
$ git commit
# Push Konflikt ```bash $ # PWD=~/git-tutorial/local $ git push $ cd ~/git-tutorial/repo $ echo "konflikt von repo" >> file.txt $ git add file.txt $ git commit -m "konflikt von repo" $ git push ```

Push Konflikt

$ cd ~/git-tutorial/local/
$ git push
To /home/natanael/git-tutorial/remote-repo
! [rejected]        master -> master (fetch first)
error: Fehler beim Versenden einiger Referenzen nach '/tmp/gituebung/remote-repo'
Hinweis: Aktualisierungen wurden zurückgewiesen, weil das Remote-Repository Commits enthält,
Hinweis: die lokal nicht vorhanden sind. Das wird üblicherweise durch einen "push" von
Hinweis: Commits auf dieselbe Referenz von einem anderen Repository aus verursacht.
Hinweis: Vielleicht müssen Sie die externen Änderungen zusammenzuführen (z.B. 'git pull ...')
Hinweis: bevor Sie erneut "push" ausführen.
Hinweis: Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'
Hinweis: für weitere Details.
# Zusammenarbeiten mit GitLab
![](img/gitlab-4.png)
![](img/gitlab-5.png)
![](img/gitlab-6.png)
![](img/gitlab-7.png)
# Lektion 3 ## Lernziele für heute * Git Branching Modells * Rebasing Note: - Den Studenten mitteilen, dass sie den Folien folgen sollen und die Beipiele nachvollziehen sollen

Push Konflikt (rebase)

$ git rebase origin/master