1. Install Git

2. Git Clients

  • Console !!!!!!!

  • IntelliJ

  • GitKraken (free for non-commercial projects, for Win, MacOS and Linux)

  • plugins for other IDEs

3. Git Console Prettifier

  • macOS: zsh with Git plugin

  • windows: posh-git

4. centralized vs distributed vcs

  • examples:

    • subversion,

    • ms team foundation server

centralvcs
Figure 1. centralized vcs
  • Single-point-of-failure

distributedvcs
Figure 2. distributed vcs

5. Initializing a Repository

mkdir my-first-repo
cd my-first-repo
git init
ls -a
open .git
rm -rf .git  # -> beim prompt verschwindet die git info
git init

6. Git Workflow

workflow01
  • with the staging area, you can choose the file(s) of the working copy for the commit.

Staging ist ein Prozess oder Bereich der Informationsintegration, in dem Daten in einem Datenbereich (engl.: staging area, der Bereitstellungsraum oder Sammelplatz beim Militär) temporär zwischengespeichert oder bearbeitet werden, um sie dort zu bereinigen, zu transformieren oder zu migrieren.

— de.wikipedia.org

6.1. A first Commit

touch file1
touch file2
workflow02
Figure 3. Two files are in the working copy folder
git add file1 file2
workflow03
Figure 4. Now the files are in the staging area
git commit -m "initial commit"
workflow04
Figure 5. Finally the files are copied to the local repo
  • a snapshot (version1) is stored in the local repo

  • -m → meaningful message

  • the staging area is not empty; it reflects the current "productive system" or includes already the changes for the next version

6.2. Exercise: change a file

After changing file1 we add it to the staging area
echo xxx >> file1
cat file1
git status
git add file1 (1)
git status
1 even the file ist deleted, we have to add it to the staging area
and commit the changes
git commit -m "remove unused code"
workflow05

6.3. Exercise: delete a file

After changing file1 we add it to the staging area
rm file2
ls
git status
git add file2
git status
git commit -m "remove unused code"
workflow06
  • Git doesn’t store the the differences between the snapshots, it always stores all files

  • the content is compressed

  • duplicate content is not stored

6.4. Exercise: Rename a File

mv file1 Main.java
git status

git mv oldfile newfile

6.5. Ignore Files

  • In einem File .gitignore werden sämtliche Dateien und Ordner angegeben, die NICHT ins Repo gespeichert werden, dh sie sind nicht Bestandteil einer Version (Schnappschuss)

  • Werden bereits im Repo enthaltene Files in die .gitignore eingetragen, so werden diese weiterhin committed

    • Diese Files sind vorher aus dem Repo zu löschen

6.6. Unstaging files

git restore --staged <files>
git restore --staged .

6.7. Short Version for git status

git status -s

6.8. Änderungen bis zum letzten Commit zurücknehmen

Falls ein geändertes File noch nicht commited wurde, kann man die Änderungen bis zum letzten commit zurücknehmen.

git restore <file>

oder

Sämtliche Änderungen des gesamten Snapshots werden zurückgesetzt
git restore .
  • Neu erstellte Files bleiben bestehen

  • Löschen neu erstellter Files

git clean -f
Dangerous operation

6.9. Den Zustand eines früheren Commits herstellen

ein File wurde zB gelöscht
git rm <file>
ein File wurde zB gelöscht
git restore --source=HEAD~1 <file-with-exact-path> (1)
1 HEAD~1 bedeutet, ein Commit vor dem letzten Commit (vorletzter Commit)

Das neu erstellte (bzw. zurückgeholte) File ist untracked.

6.10. Detached HEAD

  • In git gibt es mehrere Branches

    • Der Hauptbranch heißt in git master

    • in anderen VCS trunk

commits
Figure 6. Auf den letzten Commit zeigen sowohl MASTER als auch HEAD
Anzeigen der Commit-Id’s
git log --oneline
output
8ade525 (HEAD, master) remove unused code
db633a9 make the repo clean
028fc7c add important code
cc9fd84 remove unused code
9f57ec0 add minutes-of-meeting-template
3fb9399 initial commit
Der HEAD wird auf den (zB) ersten Commit gesetzt
# git checkout <commit-id>
git checkout 3fb9399
git log --oneline  (1)
1 Anzeigen der neuen History
  • mit git log --oneline, würde man nur alle früheren commits sehen

  • mit git log --oneline --all, würde man alle commits (auch die späteren) sehen

output
3fb9399 (HEAD) initial commit
commits detached head
Figure 7. Detached HEAD
  • Wenn der HEAD-Pointer zu einem (früheren) Commit zeigt, spricht man von einem detached HEAD, dh MASTER und HEAD zeigen nicht mehr auf den selben (den letzten) Commit

  • Bei einem detached HEAD, sollten keinen neuen Commits durchgeführt werden

    • diese neuen Commits wären nicht mehr erreichbar

commits detached head lost commit
Figure 8. würde man einen neuen Commit erstellen (wie hier abgebildet), so wäre dieser nicht mehr erreichbar, nachdem HEAD wieder auf den letzten commit gesetzt wird
commits detached head lost commit 2

7. Summary

Initializing a repository git init

Staging files
git add file1.js                  # Stages a single file git
add file1.js file2.js             # Stages multiple files
git add *.js                      # Stages with a pattern
git add .                         # Stages the current directory and all its content
Viewing the status
git status                        # Full status
git status -s                     # Short status
Committing the staged files
git commit -m "Message"           # Commits with a one-line message
git commit                        # Opens the default editor to type a long message
Skipping the staging area
git commit -am "Message"
Removing files
git rm file1.js                  # Removes from working directory and staging area
git rm --cached file1.js         # Removes from staging area only
Renaming or moving files
git mv file1.js file1.txt
Viewing the staged/unstaged changes
git diff                         # Shows unstaged changes
git diff --staged                # Shows staged changes
git diff --cached                # Same as the above
Viewing the history
git log                          # Full history
git log --oneline                # Summary
git log --reverse                # Lists the commits from the oldest to the newest
Viewing a commit
git show 921a2ff                 # Shows the given commit
git show HEAD                    # Shows the last commit
git show HEAD~2                  # Two steps before the last commit
git show HEAD:file.js            # Shows the version of file.js stored in the last commit
Unstaging files (undoing git add)
git restore --staged file.js     # Copies the last version of file.js from repo to index
Discarding local changes
git restore file.js              # Copies file.js from index to working directory
git restore file1.js file2.js    # Restores multiple files in working directory
git restore .                    # Discards all local changes (except untracked files)
git clean -fd                    # Removes all untracked files
Restoring an earlier version of a file
git restore --source=HEAD~2 file.js

8. Git Workflow 2

8.1. Blame for Finding the Author of a Line

  • to blame → jmd. Vorwürfe machen; Schuld zuweisen

Gibt den Autor der einzelnen Commits einer Datei an.

git blame file1.txt
^2b40896 (htl-leonding 2020-10-19 09:29:57 +0200 1) hello 3ahif
^2b40896 (htl-leonding 2020-10-19 09:29:57 +0200 2) hallo 3ahif
Parameter -e zum Anzeigen des emails
git blame -e file1.txt
^2b40896 (<t.stuetz@htl-leonding.ac.at> 2020-10-19 09:29:57 +0200 1) hello 3ahif
^2b40896 (<t.stuetz@htl-leonding.ac.at> 2020-10-19 09:29:57 +0200 2) hallo 3ahif

8.2. Tagging

  • to tag → kennzeichnen, markieren

Kennzeichnen eines Commits (zB vergeben eines Namens oder einer Versionsnummer)

taggen des aktuellen commits (HEAD)
git tag v1.0.0
git log --oneline
a642e12 (HEAD -> master, tag: v1.0.0) Add header to all pages.
50db987 Include the first section in TOC.
555b62e Include the note about committing after staging the changes.
91f7d40 Explain various ways to stage changes.
...
taggen eines bestimmten (früheren) commits
# git tag v1.0.0 <commit-hash>
git tag v1.0.0 9b6ebfd

8.2.1. Exkurs: Semantische Versionierung

  • Semantik → Bedeutungsinhalt

  • Syntax → Struktur eines (hier) Codefragments

  • Versionsnummern haben folgende Struktur

    • MAJOR.MINOR.PATCH zB 1.0.0

      • MAJOR: Eine neue Version, die nicht kompatibel mit den bisherigen Versionen ist. Bruch der API. Meistens eine neue Hauptversion zB v2.0.0

        • Version 1.x.x bedeutet, dass diese Version bereits released (für einen Kunden freigegeben) wurde

        • Version 0.x.x → Software wurde noch nicht released, ist wahrscheinlich noch nicht fertig gestellt

      • MINOR: Neue Features werden hinzugefügt, jedoch Kompatibilität bleibt bestehen; zB 1.1.0

      • PATCH: Fehlerbehebung: Die API / Schnittstelle ändert sich nicht, es werden nur Fehler korrigiert zB v1.0.1

zB v1.0.1 Ist eine releaste Version (Kunde hat Version erhalten) → v1.x.x in diese Version wurden bereits Fehler behoben (bugfix) → vx.x.1

Liste aller erstellten Tags
git tag

8.2.2. Annotated Tag

  • Zu einem Tag kann eine Message hinzugefügt werden

Parameter -a
git tag -a v1.1.0 -m "My version 1.1.0"
Liste aller erstellten Tags mit Message
git tag -n
Informationen anzeigen für einen bestimmten Tag
git show v1.0.0

9. Branches

9.1. Fragen zu Branches

  • Unterschied zwischen Git und anderen VCS (zB Subversion), wie Branches verwaltet/erstellt werden

  • Was ist einer der häufigsten Fehler beim committen oder wieso gibt es Terminal-Erweiterungen für Git

  • Was versteht man unter einem "dirty working directory"

branches overview

In Git wird beim Erstellen eines neuen Branch nur ein neuer "Pointer" erstellt, der auf den neuesten Commits des neuen Branch zeigt.

  • Die anschließenden Beispiele verwenden Venus.zip

9.2. Erstellen eines Branch

git branch bugfix

9.3. Auflisten aller Branches

git branch
git branch
  bugfix
* master  (1)
1 Der Asterisk (*) bedeutet, dass momentan der Branch MASTER aktiv ist
branch bugfix create

9.4. Zu einem Branch wechseln

  • Früher wurde der Befehl checkout verwendet

Wechseln zum Branch "bugfix"
git switch bugfix
branch bugfix switch
  • Die weiteren Commits werden dem Branch bugfix zugeordnet.

9.5. Umbenennen eines Branch

Da der Branch nur bugfix heißt, ist diser Name nicht sprechend. Kommen weiter bugixes hinzu, kann man nicht mehr zuordnen, welcher Branch, welchen Bug fixed. Daher benennen wir den Branch zu bugfix/signup-form.

git branch -m bugfix bugfix/signup-form
branch bugfix rename

Nach einem Commit

branch bugfix rename

Nach einem Commit

git commit -m "fix that bug"
 $ git log --oneline
e4d35dc (HEAD -> master) fix that bug
a642e12 (tag: v1.0.0, bugfix/signup-form) Add header to all pages.
50db987 Include the first section in TOC.
555b62e Include the note about committing after staging the changes.
91f7d40 Explain various ways to stage changes.
edb3594 First draft of staging changes.
24e86ee Add command line and GUI tools to the objectives.
36cd6db Include the command prompt in code sample.
9b6ebfd Add a header to the page about initializing a repo.
fa1b75e Include the warning about removing .git directory.
dad47ed Write the first draft of initializing a repo.
fb0d184 Define the audience.
1ebb7a7 Define the objectives.
ca49180 Initial commit.

9.6. Auflisten aller Commits (aller Branches)

git log --oneline --all

9.7. Löschen eines Branches

  • Nach einem merge wird der Branch nicht mehr benötigt und kann gelöscht werden

git branch -d bugfix/signup-form
  • Fehlermeldung, falls Branch noch nicht "fully merged"

Forcing the deletion
git branch -D bugfix/signup-form

9.8. Anzeigen aller Commits nur im Branch

Alle Commits des Branches werden angezeigt, jedoch nicht die Commits des Masters
git log master..bugfix/signup-form

9.9. Anzeigen aller Änderungen in einem Branch

git diff master..bugfix/signup-form
kürzere Schreibweise
git diff bugfix/signup-form

9.10. Stashing

to stash …​ verstecken, verstauen, versteckt halten

  • Bei einem switch setzt git das working directory auf den Snapshot des Zielbranches, dh die Dateien und Verzeichisse werden wieder so hergestellt, wie sie es beim letzten Commit des Zielbranches waren.

  • Problem

    • Wir könnten "local changes" an den Dateien / Verzeichnissen im Ausgangs-Branch durchgeführt haben, die noch nicht committed wurden.

    • Die lokale Änderungen könnten verloren gehen und daher erlaubt git den switch nicht.

  • Lösung

    • git schlägt vor die lokalen Änderungen zu "stashen"

    • also an einem "sichern" Platz zu speichern

    • die Inhalte dieses sichern Platzes sind nicht Teil der History

Erstellen eines Stash
git stash push -m "New tax rules"
  • Ändert man nun eine Datei kann man diese ebenfalls in einem separaten Stash speichern.

git stash push -am "My new stash"  (1) (2)
git stash list
1 -a …​ all
2 -m …​ message

9.11. Merges

  • Fast-forward merges

  • 3-way merges

9.11.1. Fast-Forward Merge

  • Es wird ein Branch (bugfix) erstellt.

  • In diesen Branch wird mehrmals comitted.

  • Im master-branch wird nichts comitted.

  • Nun möchte man den bugfix-branch in den master-branch einpflegen.

  • Da im master-branch noch keine weiteren Commits duchgeführt wurden, kann man einfach den master-branch-tag auf den HEAD-tag des bugfix-branches setzen

Fast-forward merge
git log --oneline --all --graph
git switch master
git merge bugfix/signup-form
git log --oneline --all --graph
  • con

    • pollutes the history

  • pro

    • true reflection of history

    • allows reverting a feature

Man kann fast-forward-merges ausschalten
git config ff no
oder
git config --global ff no

9.11.2. 3-Way-Merge

  • Es wird ein Branch (bugfix) erstellt.

  • Im bugfix-branch werden commits durchgeführt.

  • Im master-branch werden ebenfalls commits durchgeführt.

  • Werden master- und bugfix-branch gemerged, so wir ein neuer commit erstellt.

git switch -C bugfix/login-form (1)
echo "new line" >> toc.txt
git add .
git commit -m "Build the password form"
git log --oneline --all --graph
1 -C …​ erstellt gleichzeitig einen Branch
 $ git log --oneline --all --graph
* 1ede4ad (HEAD -> bugfix/login-form) Build the password form
* a642e12 (master) Add header to all pages.
* 50db987 Include the first section in TOC.
* 555b62e Include the note about committing after staging the changes.
* 91f7d40 Explain various ways to stage changes.
* edb3594 First draft of staging changes.
...
  • Der Branch ist noch nicht diverged (master hat noch keinen Commit)

  • diverged …​ auseinandergehend, abweichend

git switch master
echo "new line to objectives" >> objectives.txt
git add .
git commit -m "Update objectives.txt"
git log --oneline --all --graph
output
$ git log --oneline --all --graph
* 0f9a0d9 (HEAD -> master) Update objectives.txt
| * 1ede4ad (bugfix/login-form) Build the password form
|/
* a642e12 Add header to all pages.
* 50db987 Include the first section in TOC.
* 555b62e Include the note about committing after staging the changes.
* 91f7d40 Explain various ways to stage changes.
* edb3594 First draft of staging changes.
* 24e86ee Add command line and GUI tools to the objectives.
git merge feature/bugfix/login-form
git log --oneline --all --graph

9.12. Viewing Merged and Unmerged Branches

Liste aller merged branches
git branch --merged
  • Nun können diese Branches gelöscht werden

git branch -d bugfix/login-form
Liste aller noch nicht merged branches
git branch --no-merged

9.13. Merge Conflicts

  • Conflicts

    • Change1, Change2

    • Change, Delete

    • Add1, Add2

Now we create a conflict
git switch -C bugfix/change-password
echo x >> change-password.txt
git add .
git commit -m "Update change-password.txt"
git switch master
echo "Change in the master branch" > change-password.txt (1)
git add .
git commit -m "Update change-password.txt"
git merge bugfix/change-password
1 a new file has to be created, because in the master brach it doesn’t exist
Now we get a conflict
CONFLICT (add/add): Merge conflict in change-password.txt
Auto-merging change-password.txt
Automatic merge failed; fix conflicts and then commit the result.
git status
  • → Unmerged paths

9.13.1. List branches

git branch --merged
git branch --no-merged  (1)
1 List of branches not merged
git switch -C bugfix/change-password
Switched to and reset branch 'bugfix/change-password'
idea change-password.txt
change-password.txt
hello
Change in the bugfix branch
git add change-password.txt
git commit -m "Update change-password.txt"
git switch master
idea change-password.txt
change-password.txt
hello
Change in the master branch.
git add change-password.txt
git commit -m "Update change-password.txt"
git merge bugfix/change-password
Auto-merging change-password.txt
CONFLICT (content): Merge conflict in change-password.txt
Automatic merge failed; fix conflicts and then commit the result.
git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   change-password.txt
idea change-password.txt
change-password.txt
hello
<<<<<<< HEAD
Change in the master branch.
=======
Change in the bugfix branch
>>>>>>> bugfix/change-password
change-password.txt
hello
Change in the master branch.
Change in the bugfix branch
add to stage in master-branch
git add change-password.txt
git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
	modified:   change-password.txt
ohne Kommentar commiten
git commit
[master b7f555e] Merge branch 'bugfix/change-password'

10. Fork-and-Branch Workflow

  • Bei einem fork wird ein bestehendes Repo (in einem anderen git-account) mit sämtlichen Inhalten in ein neues Repo im eigenen git-account erstellt.

  • Dabei bleibt die Verbindung zum ursprünglichen Repository (dem upstream repo) bestehen + forked from

  • Bei anderen git-hostern wird ein "pull request" anders benannt, bei gitlab zB "merge request"

  • Forks werden verwendet, um open-source - Projekte als eigne Projekte weiterzuführen. Beispiele:

    • MySQL wurde geforkt und als MariaDB weitergeführt

    • openOffice wurde geforkt und als libreOffice weitergeführt.

fork and branch

10.1. Git Upstream

11. Template Repositories

  • Man kann damit ein neues Repo erstellen.

  • Ein Template-Repository kann als Vorlage für die Erstellung des neuen Repositories verwendet werden.

  • Es ist dann nicht leer, sondern enthält:

    • die gleiche directory - Struktur,

    • alle files und

    • sämtliche branches

  • Template Repositories werden zB von github-classroom verwendet, um für die Schüler jeweils ein Repo zu erstellen, dass die Angabedaten bereits enthält.

template repository