Versionsverwaltung mit Git

Das Problem

Wie kann ich …

  • … mit mehreren Leuten an einem Projekt entwickeln
  • … die Historie der Änderungen der Quellen behalten
  • … in der Zeit zurückreisen und alte Stände wieder herstellen
  • … herausfinden, welcher Entwickler ein Problem ausgelöst hat
  • … verschiedene Versionen der Software entwickeln
  • … meine Code ablegen und konsistent per Backup sichern
  • … Änderungen aus verschiedenen Quellen zusammenführen

Die Lösung: Versionsverwaltung (VCS)

  • Versions-Verwaltungssysteme (Version Control Systems) (VCS) verwalten Source Code
  • Eigenschaften
    • Historie aller Änderungen
    • Vergleich (diff) verschiedener Stände
    • Abzweigen (branching) und Zusammenführen (merging)
    • Koordinierung des gemeinsamen Zugriffs auf Source Code
  • Man unterscheidet
    • Lokale Versionsverwaltungssysteme
    • Zentrale Versionsverwaltungssysteme
    • Verteilte Versionsverwaltungssysteme

Man spricht auch von Software Configuration Management Systems (SCM) und meint damit Systeme, die neben der Funktionalität von VCSs noch weitergehende Dienste anbieten. Häufig werden VCS und SCM aber synonym verwendet.

Zentrales VCS

Verteiltes VCS

Wichtige Begriffe und Konzepte

  • revision – Version einer Datei im Repository
  • branch – Verschiedene Code-Linien, um an parallelen Versionen arbeiten zu können
  • add – eine neue lokale Datei dem Repository hinzufügen
  • checkout – eine Kopie der Datei aus dem Repository holen, um sie lokal zu bearbeiten
  • commit – eine Datei in das Repository zurückstellen
  • revert – lokale Änderungen verwerfen und durch den letzten Stand aus dem Repository ersetzen
  • blame – anzeigen, wer welche Änderungen an einer Datei gemacht hat
  • tag – Revisionen im Repository mit einer Markierung versehen (z. B. „Release 1.0“)
  • merge – parallele Änderungen an einer Datei zusammenführen
  • resolve – Konflikte beim merge auflösen
  • diff – Unterschiede zwischen der lokalen und einer zentralen oder zwischen verschiedenen Revisionen einer Datei anzeigen
  • clone – Repository kopieren (nur bei verteilten VCSs)
  • push – Änderungen in ein anderes Repository übertragen (nur bei verteilten VCSs)
  • pull – Änderungen aus einem anderen Repository ziehen (nur bei verteilten VCSs)

Zentrale Versionsverwaltungssysteme

Open Source

  • CVS - Urvater, inzwischen veraltet
  • Subversion - Populärste zentrale System

Closed Source

  • Visual SourceSafe - Veraltet, viele Probleme
  • Team Foundation Server - Nachfolger von Visual Source Safe, Microsoft zentrisch
  • Perforce - Kostenlos für Open Source oder max. zwei Benutzer:innen

Verteilte Versionsverwaltungssysteme

Open Source

  • Git - Linux Kernel Community
  • Mercurial - Python Community
  • Bazaar - Ubuntu als Hauptnutzer

Closed Source

  • Bitkeeper
  • ClearCase
  • Subversion

Git

Beispiel: Git lokal verwenden

> cat ~/.gitconfig
[user]
        name = Thomas Smits
        email = t.smits@th-mannheim.de

> cd project
> git init
Initialized empty Git repository in /Users/thomas/project/.git/

> cat .gitignore
.DS_Store
bin/
.gitignore
.metadata
  • .gitconfig enthält die grundlegende Konfiguration von git
  • mit git init wird ein neues Verzeichnis für die Versionskontrolle vorbereitet
  • .gitignore enthält Dateien, die von git ignoriert werden sollen
> git add io
> git status

# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   io/.classpath
#       new file:   io/.project
#       new file:   io/src/de/smits_net/pr2/console/Echo.java.
...

Mit git add werden neue Dateien hinzugefügt, hier die beiden Ordner io und status.

git status zeigt den aktuellen Zustand an, insbesondere welche Dateien noch nicht unter Versionskontrolle stehen oder gegenüber dem Repository verändert wurden.

>  git commit -m "Erster Commit des Projektes"
[master (root-commit) b63be32] Erster Commit des Projektes
 40 files changed, 1240 insertions(+), 0 deletions(-)
 create mode 100644 io/.classpath
 create mode 100644 io/.project
 create mode 100644 io/src/de/smits_net/pr2/console/Echo.java
...

> git status
# On branch master
nothing to commit (working directory clean)

> git log
commit b63be3267c18e3f24db7b36498133a8183a1df49
Author: Thomas Smits <thomsmits@googlemail.com>
Date:   Sat Mar 27 17:28:05 2010 +0100

    Erster Commit des Projektes

git commit bringt die aktuellen Versionen der Dateien, die mit git add hinzugefügt wurden, in das Repository. git log zeigt die Historie des Projekts an.

> vi CreateDir.java
> git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes)
#
#       modified:   CreateDir.java
#
no changes added to commit (use "git add" and/or "git commit -a")

> git add CreateDir.java
> git commit -m "Fixed copyright date"
[master d565a0f] Fixed copyright date
 1 files changed, 1 insertions(+), 1 deletions(-)
> git log
macbook:file thomas$ git log
commit d565a0f757595c83ee265948476ea1ebb461c1ed
Author: Thomas Smits <thomsmits@googlemail.com>
Date:   Sat Mar 27 17:34:10 2010 +0100

    Fixed copyright date

commit b63be3267c18e3f24db7b36498133a8183a1df49
Author: Thomas Smits <thomsmits@googlemail.com>
Date:   Sat Mar 27 17:28:05 2010 +0100

    Erster Commit des Projektes

> git diff d565a b63be
diff --git a/io/src/de/smits_net/pr2/file/CreateDir.java
     b/io/src/de/smits_net/t
index ef41ca1..05e3ed9 100644
--- a/io/src/de/smits_net/pr2/file/CreateDir.java
+++ b/io/src/de/smits_net/pr2/file/CreateDir.java
@@ -1,5 +1,5 @@
 /*
- * (c) 2010 Thomas Smits
+ * (c) 2009 Thomas Smits
  */
 package de.smits_net.pr2.file;

Mit git diff kann man sich die Unterschiede zwischen Dateien anzeigen lassen.

Beispiel: Git verteilt verwenden

> git remote add sharedrepo /network/share/pr2/git
> git remote
sharedrepo

> git push sharedrepo
Counting objects: 17, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (9/9), 582 bytes, done.
Total 9 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
To /network/share/pr2/git
   e26823c..91adf73  master -> master

git remote legt in diesem Beispiel fest, dass mein Repository mit einem anderen verbunden werden soll und das andere als „sharedrepo“ benannt wird.

Mit git push wird der lokale Stand des Repositories in das zentrale geschoben.

> git clone /network/share/pr2/git
Initialized empty Git repository in /Users/thomas/git/.git/
sharedrepo

> git pull
remote: Counting objects: 17, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 9 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
From /Users/thomas/git/ /network/share/pr2/git
   91adf73..f83d24f  master     -> origin/master
Updating 91adf73..f83d24f
Fast-forward
 io/src/de/smits_net/pr2/nio/KopierprogrammNIO.java |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

git clone kopiert ein Repository und git pull importiert die Änderungen aus dem entfernten Repository in mein eigenes Repository.

Git und Eclipse

Git kann direkt aus Eclipse heraus verwendet werden


Copyright © 2025 Thomas Smits