Labor für Halbleiterbauelemente und Bussysteme


 

Inhalt

  1. Was ist ein GIT-Server
  2. Erzeugen eines lokalen Repositories
  3. Schreibzugang zum zentralen GIT-Server
  4. Write access to central GIT-Server
  5. RSA-Schlüsselpaar auf USB-Stick sichern
  6. Lesezugang zum öffentlichen GIT-Server
  7. Arbeiten mit dem GIT-Server
  8. Branches verwalten

Was ist ein GIT-Server?  ^

  Ein GIT-Server ist zentrales Element eines verteilten Revisionskontrollsystems.

Ein Revisionskontrollsystem ist die Erweiterung eines Speichersystems um die Zeitkoordinate.
Jedesmal, wenn ein Dokument im Revisionskontrollsystem abgelegt wird, bleiben sämtliche alten Stände
des Dokuments weiterhin gespeichert. Die Datenbank, welche den aktuellen und sämtliche alten Zustände speichert wird Repository genannt.
Zu jedem Zeitpunkt erlaubt das Revisionskontrollsystem jedes Dokument im Repository in einen älteren Zustand zurück zu versetzen.
Zusätzlich ist es üblich, jede Dokumentänderung mit einem Kommentar zu versehen.
Diese Kommentare können im Log des Repositories eingesehen werden.

Frühe Revisionskontrollsysteme (z.B. cvs und svn) haben nur ein einziges Repository verwendet.
Die Benutzer des Systems haben von jedem Dokument nur einen einzigen Stand auf ihren lokalen Rechner
herunter geladen (ausgecheckt). Um einen anderen Zeitzustand eines Dokumentes auszuchecken, musste bei diesen
Revisionskontrollsystemen jedesmal eine Verbindung zum zentralen Repositoryserver hergestellt werden.
War die Verbindung zum Repositoryserver unterbrochen, oder dessen Datenbank beschädigt, so waren alle
zeitlichen Veränderungen verloren.

Verteile Revisionskontrollsysteme (z.B. Git, Mercurial, Hg) speichern den aktuellen, sowie sämtliche älteren
Dokumentzustände auf allen Rechnern. Jeder Benutzer kann, auch ohne Verbindung zum zentralen Server, neue Zustände
in's Repository laden (committen), sowie ältere Zustände wieder herstellen. Es ist auch möglich, einfach ein
lokales Repository zu erstellen ohne zentralen Server. Der zentrale Server dient als gemeinsamer Knoten um
Änderungen zwischen mehreren Benutzern auszutauschen. Jeder Benutzer committed Änderungen zunächst in sein lokales
Repository. Von Zeit zu Zeit pusht er diese Änderungen dann gesammelt auf den zentralen Server.

Die hier gezeigten Beispiele funktionieren unter allen Linux und den meisten UNIX Derivaten.

Erzeugen eines lokalen Repositories  ^

  Um für eigene Projekte ein GIT-Repository anzulegen, ist kein zentraler Server notwendig.

Ein leeres GIT-Repository kann z.B. so angelegt werden:
  • cd ~/Source
  • mkdir REPOSITORY
  • cd REPOSITORY/
  • git init
Jetzt noch Dateien in den Ordner kopieren und diese zum Repository hinzufügen:
  • git add *
  • git commit -a
Nach jeder Änderung an einer oder mehrerer Dateien ist dann wieder ein Commit nötig. Die bisherigen Commits können im Log eingesehen werden:
  • git log

Verschiedene Integrierte Entwicklungsumgebungen bieten diese Funktionalität von Haus aus an
(z.B. QtCreator oder Eclipse).


Schreibzugang zum GIT-Server halbleiterbauelemente.de  ^

  Unter halbleiterbauelemente.de steht ein zentraler GIT-Server für Studenten und Mitarbeiter des
Halbleiterbauelemente & Bussysteme Labors der Fachhochschule Münster zur Verfügung.
Der Zugriff funktioniert nur von Linux und Mac OS Betriebsystemen aus. Gängige Git-Clients für Windows bieten keine aktuellen Verschlüsselungsmethoden und können den Dienst daher nicht nutzen.
Der Schreibzugriff auf existierende oder neue Repositories muss extra freigeschaltet werden.

Um Schreibzugriff auf den GIT-Server zu erhalten muss ein RSA-Schlüsselpaar
erzeugt und der öffentliche Teil an den Verwalter des GIT-Servers geschickt werden.
Dazu dienen die folgenden Zeilen, welche in der Shell (Terminal/ Konsole) einzugeben sind (Copy & Paste).

  1. Ihr Benutzeraccount muss Ihren Namen tragen um den erstellten Schlüssel später eindeutig zuordnen zu können. Falls Ihr aktueller Benutzeraccount ein Pseudonym trägt, erstellen Sie einen neuen Account mit Ihrem Namen (kein unknown oder Pseudonyme). Anschliessend starten Sie den Rechner neu loggen sich unter dem neuen Account ein.

  2. Erzeugen eines RSA-Schlüsselpaares (falls nicht bereits geschehen)
    • ssh-keygen -t rsa -C VORNAME.NACHNAME
    VORNAME und NACHNAME sind entsprechend anzupassen und dürfen gerne GROSS-kleinschreibung benutzen!
    Wichtig: Auf alle Fragen einfach Return drücken!

  3. Public-Key kopieren und umbenennen
    • cp -v $HOME/.ssh/id_rsa.pub $HOME/`awk '{ print $NF }' <$HOME/.ssh/id_rsa.pub`.pub

    Diese kryptisch aussehende Zeile erstellt eine Kopie des Publickeys vom versteckten Ordner .ssh/ in den persönlichen Ordners unter dem Namen VORNAME.NACHNAME.pub

  4. Die .pub-Datei per EMail schicken an (EMails ohne Betreff landen im Junkordner!):
    gregorÄTfh-muensterDE

    --- Warten auf Antwort ---

 
Wichtig:  Die Datei $HOME/.ssh/id_rsa enthält den eigenen, privaten Schlüssel.
 Geht dieser verloren, dann funktioniert der Zugang nicht mehr!

Write access to central GIT-Server halbleiterbauelemente.de  ^

  A central GIT-server is provided by halbleiterbauelemente.de for students and employees of this lab.
It can be accessed from Linux and Mac OS clients. Git-clients for Windows OS does exist but it is difficult to generate the correct access keys on this system.

Write access to certain repositories must be activated individually by the server maintainer.

To obtain write access, the user first has to generate a pair of private and public RSA-keys. The public key then has to be mailed to the server maintainer.

A new key pair can be generated by copying (and modifying) the following lines into a shell (terminal/ konsole):
  1. Note: Your user account has to show your name to identify your key later. If your user account on your current machine uses a pseudonym, you have to create a new user account first. Keys which do not show the real name of their owner will be regretted.

  2. Creation of a new RSA key pair (if not already done)
    • ssh-keygen -t rsa -C FIRST_NAME.LAST_NAME
    Please replace FIRST_NAME and LAST_NAME accordingly. If ssh-keygen asks any questions, simply hit return.

  3. Copy and rename your public key
    • cp -v $HOME/.ssh/id_rsa.pub $HOME/`awk '{ print $NF }' <$HOME/.ssh/id_rsa.pub`.pub

    This cryptographic looking line creates a copy of your public key from the hidden folder ~/.ssh/ to ~/FIRST_NAME.LAST_NAME.pub

  4. Send your ~/FIRST_NAME.LAST_NAME.pub via EMail (use a decent subject!) to:
    gregorATfh-muensterDE

    --- Wait for answer ---

 
Important:  The file ~/.ssh/id_rsa your own private key.
 If this file gets lost then the access will not work anymore!

RSA-Schlüsselpaar auf USB-Stick sichern  ^

  Wird ein Schlüsselpaar auf einem Laborrechner erstellt, dann liegt dieses im .ssh-Ordner im Heimatverzeichnis des aktuellen Benutzers. Der Git-Zugang kann dann nur auf diesem Rechner benutzt werden. Zusätzlich kann natürlich jeder andere Student das Schlüsselpaar mit eigenen Schlüsseln überschreiben oder unter falschem Namen den Zugang nutzen.
Daher ist es wichtig, das frisch erstellte Schlüsselpaar auf einen eigenen USB-Stick zu sichern. Dazu reicht bereits ein 128MB Stick. Wichtig ist, dass der USB-Stick mit einem UNIX-Dateisystem (z.B. EXT4) formatiert wird. Das geht folgendermaßen:
  1. Dateimanager starten (z.B. dolphin)
  2. USB-Stick einstecken ⇒ ein neuer USB-Datenträger erscheint im Dateimanager
  3. USB-Datenträger im Dateimanager öffnen ⇒ Inhalt wird angezeigt
  4. Konsole öffnen (Rechtsklick ⇒ Ausführen ⇒ eintippen: konsole)
  5. Auswahl des richtigen Dateisystems.
    df -h
    Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
    udev            7,8G       0  7,8G    0% /dev
    tmpfs           1,6G    9,3M  1,6G    1% /run
    /dev/sda4        49G     33G   14G   71% /
    tmpfs           7,9G    212K  7,9G    1% /dev/shm
    tmpfs           5,0M    4,0K  5,0M    1% /run/lock
    tmpfs           7,9G       0  7,9G    0% /sys/fs/cgroup
    /dev/sda5       172G    106G   57G   66% /home
    /dev/sda2        96M     23M   74M   24% /boot/efi
    tmpfs           1,6G       0  1,6G    0% /run/user/123
    tmpfs           1,6G     16K  1,6G    1% /run/user/1000
    /dev/sdf        472M    6,4M  466M    2% /media/foo/USB_500MB

    In dieser Auflistung muss jetzt der richtige Datenträger herausgesucht werden. In diesem Fall ist es der 472 MB große Datenträger mit dem Dateisystem /dev/sdf.

  6. Vor dem Formatieren muss der Datenträger abgemeldet werden:

    umount /dev/sdf # ← HIER DAS RICHTIGE DATEISYSTEM AUSWÄHLEN!

    Im Dateimanager sollte die Abmeldung sichtbar sein.

  7. Formatieren des Datenträgers mit EXT4:
    sudo mkfs.ext4 -L MEIN_USB_KEY -Eroot_owner=`id -u`:`id -u` /dev/sdf # ← AB HIER WIRD EIN DATENTRÄGER FORMATIERT (Hoffentlich der richtige!)

  8. USB-Stick aus- und wiedereinstecken ⇒ Ein neuer, leerer Datenräger mit dem vorher angegebenen Label taucht im Dateimanager auf.

  9. USB-Datenträger im Dateimanager öffnen ⇒ Ein Ordner namens lost+found wird angezeigt.
  10. Feststellen wo der USB-Stick aktuell eingehängt ist.
    df -h
    Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
    ...
    /dev/sdf        472M    6,4M  466M    2% /media/foo/MEIN_USB_KEY

    ⇒ Der USB-Stick ist in diesem Fall in /media/foo/MEIN_USB_KEY eingehängt.

  11. Den versteckten Ordner .ssh aus dem Heimatverzeichnis auf den frisch formatierten USB-Stick verschieben.
    mv ~/.ssh /media/foo/MEIN_USB_KEY/ # ← Pfad entsprechend anpassen

  12. Den versteckten Ordner .ssh aus dem Heimatverzeichnis auf den frisch formatierten USB-Stick verschieben.
    mv ~/.ssh /media/foo/MEIN_USB_KEY/ # ← Pfad entsprechend anpassen

  13. Damit der, jetzt auf dem USB-Stick liegende .ssh-Ordner auch genutzt werden kann, erstellen wir jetzt noch ein Shellskript.

    cat <<"END_OF_SCRIPT" >~/linkSSH.sh #!/bin/bash

    MyDir=`dirname "$0"`
    echo "MyDir='$MyDir'"

    if [ -d "$HOME/.ssh" ]; then
        echo "$0 - ERROR: An .ssh-folder already exists for current user in $HOME/.ssh !"
        exit 10
    fi
    if [ -d "$MyDir/.ssh" ]; then
        rm -f "$HOME/.ssh"
        ln -svf "$MyDir/.ssh" "$HOME/.ssh"
        echo "$0 - Successfully installed symbolic link."
        echo "chowning USB-files to $USER ..."
        sudo chown -R $USER:$USER $MyDir
    fi
    END_OF_SCRIPT
    chmod 0777 ~/linkSSH.sh

  14. Das frisch erstellte Skript auf den USB-Stick verschieben:
    mv ~/linkSSH.sh /media/foo/MEIN_USB_KEY/ # ← Pfad entsprechend anpassen

  15. Und so wird der Stick dann benutzt:

    1. dolphin starten
    2. USB-Stick einstecken
    3. USB-Stick anmelden
    4. konsole starten
    5. Skript linkSSH.sh vom dolphin in die Konsole ziehen (Speicherort einfügen)
    6. Befehl ausführen (Return drücken) ⇒ Das Skript meldet Erfolg.

  16. Funktionstest
    Nach dem Einlegen des USB-Sticks und Ausführen des Skriptes sollten Git-Aktionen auf freigegebenen Repositories möglich sein. Für das nichtexistente Beispielrepository REPOSITORY sieht ein Klonbefehl folgendermaßen aus:
    git clone git@halbleiterbauelemente.de:REPOSITORY

    Sollte git nach einem Passwort fragen, dann ist der Privatekey
    • Nicht auffindbar
    • Nicht lesbar
    • Von anderen lesbar (SSH verlangt das nur der Eigentümer seinen Privatekey lesen können darf!)

    Die obigen Punkte sind einfach zu testen. Für den Benutzer foo muss ein ls auf die gesuchten Dateien folgendes liefern:

    ls -l ~/.ssh/id*
    -rw------- 1 foo foo 1,7K ... /home/foo/.ssh/id_rsa
    -rw------- 1 foo foo  396 ... /home/foo/.ssh/id_rsa.pub

Lesezugang zum öffentlichen GIT-Server halbleiterbauelemente.de   ^

  Unter halbleiterbauelemente.de steht auch ein öffenlicher GIT-Server mit Lesezugang bereit. Auf diesem Server werden einige Repositories öffentlich angeboten.

Der Lesezugriff ist für jeden Internetnutzer frei zugänglich. Die Adresse unterscheidet sich leicht vom Schreibzugang. Ein Repository kann folgendermaßen heruntergeladen werden:
  • git clone git://halbleiterbauelemente.de/REPOSITORY

Arbeiten mit dem GIT-Server (Beispiel-Repository: REPOSITORY)  ^

 
    Wichtig:  Sämtliche Git Operationen (außer clone) müssen im Verzeichnis des Repositories (hier REPOSITORY) ausgeführt werden!

    Tip:  An jedem Tag, an dem Änderungen am Repository durchgeführt werden sollen, zuerst ein
    "git pull" ausführen um auf den aktuellen Stand zu kommen. Dadurch können aufwendige
    Merge-Operationen vermieden werden.

  • Repository neu vom Git-Server klonen
    cd ~/Source
    git clone git@halbleiterbauelemente.de:REPOSITORY
    Anmerkung: git@halbleiterbauelemente.de: URLs benötigen einen Schreibzugriff per SSH-Schlüssel wie oben beschrieben

    Nach dem erfolgreichen Klonen des Repositories befindet sich im aktuellen Ordner
    ein neuer Ordner namens REPOSITORY.
    • cd REPOSITORY
  • Lokale Dateien geändert: Schnappschuss lokal speichern
    • cd REPOSITORY
    • git pull      # aktuellen Stand herunterladen
    • git commit -a # eigene Änderungen kommentieren
    • git add ...   # neue Dateien hinzufügen (von commit -a as untracked aufgelistet)
    • git commit -a # neue Dateien kommentieren
    • git push      # aktuellen Stand zm Server hochladen
    Bei Verwendung eines zentralen Git-Servers passiert es leicht, das committed wird obwohl auf dem Server bereits ein neuer Stand existiert. Dadurch kann automatisch ein Branch entstehen was zu Missverständnissen führen kann.
    Daher ist folgende Zeile sicherer wenn mehrere Entwickler am selben Repository arbeiten:
    git pull && git commit -a


  • Datei neu erstellt: Zum Repository hinzufügen
    • cd ~/Source/REPOSITORY
    • git add DATEINAME
    • commit -a
  • Lokale Änderungen auf den zentralen GIT-Server hochladen
    • cd ~/Source/REPOSITORY
    • git push
  • Lokal gelöschte Dateien erneut vom Repository herunterladen
    • cd ~/Source/REPOSITORY
    • git checkout -f
  • Aktuellen Stand taggen
    • cd ~/Source/REPOSITORY
    • git tag NEUER_TAG
    Benennt den aktuellen Stand aller Dateien im Repository. Tags werden oft für Release Versionen verwendet, wenn eine Software ausgeliefert wird. Sämtliche vergebenen Tags können mittels "git tag" aufgelistet werden.

  • Fehlermeldung bei push
    Wenn zwei Benutzer A und B dieselbe Datei im Zustand X geändert haben und dann pushen wollen, kommt es zu einem Konflikt.
    Es existieren dann zwei parallele Zustände A und B, die beide direkt von X abgeleitet wurden.
        A
       /
    --X--B

    Ein merge (Verschmelzung) der Änderungen ist dann nötig:
    1. cd ~/Source/REPOSITORY
    2. git pull Die Änderungsreihenfolge wird dadurch wieder zu einer Kette repariert: --X--A--B
    3. Falls git den Merge nicht automatisch durchführen kann -> "Fehlermeldung bei pull"
    4. git push

  • Fehlermeldung bei pull
    Benutzer A und B haben dieselbe Datei verändert. A committet und pusht vor B.
    Wenn B nun pullt, dann versucht git die verschiedenen Zustände der Datei zu mergen.
    Das kann automatisch funktionieren, wenn die Änderungen in der Textdatei in verschiedenen
    Zeilen stattgefunden haben.
    Falls der Merge nicht automatisch durchgeführt werden kann, endet der Pull mit einer Fehlermeldung.
    In diesem Fall ist Handarbeit angesagt um zu entscheiden, welche Zeilen als neuer Stand übernommen werden sollen.

    Für den Merge hat Git die Konfliktzeilen aus der lokalen Datei und derjenigen im Repository gegenübergestellt.
    Oberhalb der ======= Linie befindet sich die Textpassage aus der lokalen Datei. Darunter liegt die Änderung,
    welche bereits im Repository abgelegt wurde.

    Beispiel:
    <<<<<<< HEAD
    Hallo345
    =======
    Hallo678
    >>>>>>> c47e04696642e5ee092af5ee2b0df1bb5c784fc3

    Sobald die von git hinzugefügten Zeilen entfernt sind, kann die Datei committet und gepusht werden.

  • Merge nicht durchführbar
    • cd ~/Source
    • mv REPOSITORY REPOSITORY_alt
    • git clone git@halbleiterbauelemente.de:REPOSITORY

    Jetzt müssen die geänderten Dateien aus REPOSITORY_alt von Hand nach REPOSITORY kopiert werden.
    Anschliessend noch
    • cd ~/Source/REPOSITORY
    • commit -a
    • git push

Branches verwalten  ^

  Oft soll ein existierendes Projekt als Ausgangsbasis für ein ähnliches Projekt verwendet werden.
Ein naiver Ansatz wäre ein neues Repository aufzusetzen und die Dateien eines bestimmten Standes vom alten Repository hineinzukopieren. Abgesehen vom recht großen Aufwand (neues Repository, alle Dateien neu hinzufügen, ...) hat diese Vorgehensweise vor allem den Nachteil, dass im neuen Repository die Historie einen harten Schnitt erfährt. Es ist dann nicht mehr möglich Änderungen davor einzusehen.

Für derart abgeleitete Projekte bieten Versionskontrollsysteme sogenannete Branches an.

Branches mit Git

  • verfügbare Branches anzeigen
    • cd ~/Source
    • git branch
  • neuen Branch erstellen
    • cd ~/Source
    • git branch BRANCH_NAME
    Erstellt einen neuen Branch mit dem Namen BRANCH_NAME.

  • neuen Branch ab einem Zeitstempel erstellen
    • cd ~/Source
    • git branch BRANCH_NAME START_POINT
    Erstellt einen neuen Branch mit dem Namen BRANCH_NAME basierend auf einem älteren Stand.
    START_POINT kann sein
    • BRANCH_NAME
      Der Name eines bereits erstellten Branches.

    • COMMIT_ID
      Jedem commit wird eine eindeutige hexadezimale ID zugewiesen. Diese IDs können mit "git log" aufgelistet werden.

    • TAG
      Der Name eines bereits vergebenen Tags (git tag).

    Beispiel:  git branch Spielwiese 1caa3811cb89d6bf287809c88cf395a63ecef809

  • Branch zum Server hochladen
    git push origin BRANCH_NAME
geschrieben von Gregor Rebel 2011-2015