Git, Gitosis, Gitweb (the Debian way)

Git Logo

Installation und Konfiguration von Git,
Gitosis
und Gitweb unter Debian 5 (Lenny).

Das folgende Setup erstreckt sich über 3 Rechner:

  1. birgit, das zentrale Repository welches über gitosis verwaltet wird und die Gitweb Weboberfläche bereitstellt
  2. nora, der Server auf dem entwickelt wird
  3. demine, eine lokale Workstation

Warum man seinen Code versionieren sollte, müsste eigentlich jedem Entwickler klar sein, das Drupal in Zukunft auf Git setzen wird, dürfte wohl der Anreiz für Drupalentwickler sein sich frühzeitig mit dem Thema Git zu auseinanderzusetzen.

Hätte, würde, wäre
Hätte ich an der Session von Daniel und Eugen über Git, die meiner Meinung nach eine der besten Session auf dem DrupalCamp Essen war einen Monat früher teilgenommen,
hätte ich Gitoltite bei unserem jetzigen Projekt eingesetzt und dieses Howto würde eben von Gitolite handeln...
...wäre besser, da gitolite unter anderem Berechtigungen auf Branch-Ebene vergeben kann...

Installation und Einrichtung von Gitosis

Installation von git, gitosis und gitweb über aptitude als Benutzer root auf birgit:

aptitude install git-core gitosis gitweb

Bei der Installation von gitosis wird unter Debian der Systembenutzer gitosis mit /srv/gitosis als Heimatverzeichnis angelegt.

Auf nora ein SSH-Schlüsselpaar für den Benutzer florian erstellen:

ssh-keygen -t rsa

Öffentlichen Schlüssel auf den Server birgit, der später als zentrales Repository fungieren soll kopieren:

scp .ssh/id_rsa.pub birgit:/tmp

Auf birgit Gitosis mit dem eben kopiertem Public-Key initialisieren:

sudo -H -u gitosis gitosis-init < /tmp/id_rsa.pub

Dies erzeugt die folgende Ausgabe:

Initialized empty Git repository in /srv/gitosis/repositories/gitosis-admin.git/
Reinitialized existing Git repository in /srv/gitosis/repositories/gitosis-admin.git/

Durch die Initialisierung sind in /srv/gitosis die folgenden Verzeichnisse entstanden:

  1. /srv/gitosis/repositories, welches die von gitosis verwalteten Repositories beinhaltet, es enthält bereits gitosis-admin.git, das Repository, welches zur Verwaltung von gitosis selbst dient.
  2. /srv/gitosis/gitosis/, welches die noch leere Datei projects.list enthält, die in den nächsten Schritten pro Zeile durch Leerzeichen getrennt Repository und Eigentümer enthalten wird.

Als Benutzer florian auf nora das Repository gitosis-admin klonen:

git clone gitosis@birgit:gitosis-admin.git

Das durch das Klonen entstandene Verzeichnis gitosis-admin/ hat den folgenden Inhalt:

SSH Port und GIT URLS

Achtung!
Falls auf dem Server, auf dem Gitosis und somit in unserm Fall auch SSH läuft
ein Non Default Port verwendet wird, also nicht Port 22,
so ändert sich die in den folgenden Schritten die Git-URL.

In unserem Fall wird

gitosis@birgit:${REPOSITORY}.git

zu

ssh://gitosis@lbirgit:${PORT}/${REPOSITORY}.git

Beispielhaft für das Repository gitosis-admin mit einem SSHD welcher auf Port 1337 lauscht:

ssh://gitosis@lbirgit:1337/gitosis-admin.git

Mehr zu Git URLS findet sich in der Manpage zu git-clone.

Der Gruppe gitosis-admin einen neuen Benutzer hinzufügen

Damit der neue Benutzer, hier florian@demine später selbständig weitere Repositories anlegen kann
muss er Mitglied in der Gruppe gitosis-admin werden.

Auf nora als Benutzer florian, die Datei gitosis.conf im bereits geklonten gitosis-admin Resopitory bearbeiten, um in der members Direktive von [group gitosis-admin] den Benutzer florian@demine hizufügen:

[group gitosis-admin]
writable = gitosis-admin
members = florian@nora florian@demine

Anschließend, ein Commit mit aussagekräftiger Commit-Message (-m)...

git commit -a -m 'Added "florian@demine" to group gitosis-admin.'

Output

Created commit 819f0f0: Added "florian@demine" to group gitosis-admin
 1 files changed, 1 insertions(+), 1 deletions(-)

...und ein push um den Commit auf den Server zu übertragen:

git push

Output:

Counting objects: 6, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 534 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To gitosis@birgit:gitosis-admin.git
   b2240d3..819f0f0  master -> master

SSH-Public-Key für neuen Benutzer hinzufügen

Zuerst muss wieder für den jew. Benutzer ein SSH-Key angelegt werden, falls noch kein Key da ist, damit sich der Benutzer über diesen Key am gitiosis Konto anmelden kann.

Als florian auf demine:

ssh-keygen -t rsa

Defaults übernehmen

Falls Windows Rechner als Clients verwendet werden sollen,
hilft PuttyGen von der Putty Downloadseite bei der Erstellung des SSH-Public-Keys.
Hier muss ggf. nach der öffentliche SSH-Schlüssel in ein für OpenSSH verständliches Format konvertiert werden.

ssh-keygen -i -f is_rsa.pub > id_rsa2.pub

Anschießend den Teil mit dem öffentlichen Schlüssel per nach /tmp/ auf nora kopieren und gleichzeitig nach Schema user@host.pub umbenennen:

scp ~/.ssh/id_rsa.pub nora:/tmp/florian@demine.pub

Weiter im Kontext mit florian auf nora um florian@demine.pub in der Verzeichnis keydir zu kopieren:
Achtung: Der Key muss die Dateiendung .pub haben!

cp /tmp/florian\@demine.pub keydir/

Die Datei florian@demine.pub in das gitosis-admin Repository aufnehmen:

git add keydir/florian\@demine.pub

Und wieder ein commit...

git commit -m 'Added Key "florian@demine.pub"'

...und wieder ein push, damit die Änderungen auf birgit auch wirksam werden.

git push

Neues Repository hinzufügen

Jetzt können wir mit unserem frischgebackenem Admin-User florian@demine neue Repositories anlegen.

Als florian@demine auf der lokalen Workstation:

gitosis-admin.git auschecken

git clone gitosis@birgit:gitosis-admin.git

Da sich florian@demine bis jetzt noch nicht verbunden hat, muss dem ersten Verbindungsversuch über SSH mit yes zugestimmt werden:

Initialized empty Git repository in /home/florian/gitosis-admin/.git/
The authenticity of host 'birgit (88.198.7.214)' can't be established.
RSA key fingerprint is b4:c0:e6:e9:7c:fa:6b:a4:b1:d0:d2:4c:b5:b7:11:d1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'birgit,88.198.7.214' (RSA) to the list of known hosts.

Wechsel in das soeben geklonte Repository:

cd gitosis-admin/

Die folgende Sektion, hier examplarisch die Gruppe developers, die auf hongomat unter writable Schreibzugriff haben soll der Datei gitosis.conf hinzufügen:

[group developers]
writable = hongomat
members = florian@demine

...wieder ein commit:

git commit -a -m 'Added group "developers" with member "florian@demine" and write access to "hongomat"'

...und wieder ein push:

git push

Neues Repository anlegen

Jetzt kann als florian@demine ein neues Repository, hier "hongomat"
angelegt werden:

mkdir hongomat
cd hongomat
git init
vi foo
vi bar
git add foo bar
git commit -m 'Initial commit'

Mit git init wird das Repository initialisiert,
es ist ein initialer Commit nötig.

git remote add origin gitosis@birgit:hongomat.git
git push origin master:refs/heads/master

Bei dem git remote add Statement wird mit birgit:hongomat.git das Remote Repository bestimmt.

Siehe SSH Port und GIT URLS bei Abweichung vom SSH-Standard-Port (22).

Der push Befehl schiebt alles in unser zentrales Repository auf brigit.

Konfiguraton von gitweb

Einrichtung von gitweb der Weboberfläche für Git.

/etc/gitweb.conf

Die Konfigurationsdatei für Gitweb,
hier angepasst $projectroot welche auf das Verzeichnis /srv/gitosis/repositories, in dem gitosis seine Repos ablegt zeigt.

# path to git projects (<project>.git)
# $projectroot = "/var/cache/git";
$projectroot = "/srv/gitosis/repositories";

# directory to use for temp files
$git_temp = "/tmp";

# target of the home link on top of all pages
#$home_link = $my_uri || "/";

# html text to include at home page
$home_text = "indextext.html";

# file with project list; by default, simply scan the projectroot dir.
$projects_list = $projectroot;

# stylesheet to use
$stylesheet = "/gitweb.css";

# logo to use
$logo = "/git-logo.png";

# the 'favicon'
$favicon = "/git-favicon.png";

'

Virtual Host für gitweb anlegen

Auf birgit, die Datei /etc/apache2/sites-available/birgit.example.com mit dem folgendem Inhalt anlegen:

<VirtualHost *>
  ServerName birgit.example.com
  ServerAdmin webmaster@example.com
  DocumentRoot /srv/gitosis/repositories
  SetEnv GITWEB_CONFIG /etc/gitweb.conf
  Alias /gitweb.css /usr/share/gitweb/gitweb.css
  Alias /git-logo.png /usr/share/gitweb/git-logo.png
  Alias /git-favicon.png /usr/share/gitweb/git-favicon.png
  ScriptAlias /gitweb.cgi /usr/lib/cgi-bin/gitweb.cgi
  DirectoryIndex gitweb.cgi
</VirtualHost>

Da wir in einem verteiltem Team arbeiten und Gitweb aus dem Internet aufrufbar ist,

In unserem Fall ist dies eine Atrium Installation, in der jeder Entwickler ein Benutzerkonto besitzt.

.htaccess mit Authentifizierung an einer MySQL Datenbank (Drupal)

Htaccess mit Authentifizierung an einer MySQL basierten Drupal-Installation.

Installation des benötigten Apache Moduls

aptitude install libapache2-mod-auth-mysql

Aktivierung des authmysql-Moduls

a2enmod auth_mysql
<Directory /var/www/git>
  AuthName "Authentication required"
  AuthType Basic
  require valid-user
  AuthUserFile /dev/null
  AuthBasicAuthoritative Off
  Auth_MYSQL On
  Auth_MySQL_Host mysqlhost
  Auth_MySQL_User mysqluser
  Auth_MySQL_Password mysqlpasswd
  Auth_MySQL_DB drupaldb
  Auth_MySQL_Authoritative On
  Auth_MySQL_Password_Table users
  Auth_MySQL_Encryption_Types PHP_MD5
  Auth_MySQL_Encrypted_Passwords On
  Auth_MySQL_Empty_Passwords Off
  Auth_MySQL_Username_Field name
  Auth_MySQL_Password_Field pass
</Directory>

Was in Kontext des VirtualHost's so aussieht:

<VirtualHost *>
  ServerName birgit.example.com
  ServerAdmin webmaster@example.com
  DocumentRoot /srv/gitosis/repositories
  SetEnv GITWEB_CONFIG /etc/gitweb.conf
  Alias /gitweb.css /usr/share/gitweb/gitweb.css
  Alias /git-logo.png /usr/share/gitweb/git-logo.png
  Alias /git-favicon.png /usr/share/gitweb/git-favicon.png
  ScriptAlias /gitweb.cgi /usr/lib/cgi-bin/gitweb.cgi
  DirectoryIndex gitweb.cgi
  <Directory /var/www/git>
    AuthName "Authentication required"
    AuthType Basic
    require valid-user
    AuthUserFile /dev/null
    AuthBasicAuthoritative Off
    Auth_MYSQL On
    Auth_MySQL_Host mysqlhost
    Auth_MySQL_User mysqluser
    Auth_MySQL_Password mysqlpasswd
    Auth_MySQL_DB drupaldb
    Auth_MySQL_Authoritative On
    Auth_MySQL_Password_Table users
    Auth_MySQL_Encryption_Types PHP_MD5
    Auth_MySQL_Encrypted_Passwords On
    Auth_MySQL_Empty_Passwords Off
    Auth_MySQL_Username_Field name
    Auth_MySQL_Password_Field pass
  </Directory>
</VirtualHost>

Aktivieren der site:

a2ensite birgit.example.com

Die Konfiguration des Apachen neu einlesen:

/etc/init.d/apache2 reload

Leserechte für den Webserver-Prozess

Damit der Webserver auch die Repositories in Gitweb anzeigen kann,
habe ich den Benutzer gitosis der Gruppe www-data hinzugefügt.

Als root:

usermod -g www-data gitosis

Git personalisieren

Befehl: git config

git config --global user.name "Florian Latzel"
git config --global user.email "floh@netzaffe.de"

Git-Konfigurationsdateien: /etc/gitconfig, ~/.gitconfig, .git/config

Auswertungsreihenfolge:

  1. /etc/gitconfig

    Systemweite Git-Konfigurationsdatei
  2. ~/.gitconfig

    Benutzerweite Git-Konfigurationsdatei
  3. .git/config

    Projektspezifische Git-Konfigurationsdatei im jeweiligen Repository

Redimentär, nur Name und EMail nach Eingabe des obigen git config Befehls. Die --global Option bewirkt das Schreiben nach ~/.gitconfig, ohne diese Option wäre es .git/config. Nach dem abesetzen der beiden git config Befehle hat die Datei ~/.gitconfig den folegende Inhalt:

 
[user]
     name = Florian Latzel
     email = floh@netzaffe.de

$EDITOR Variable anpassen

Um z.B. Commit-Messages direkt mit dem gewüschten Editor schreiben zu können, falls man sich die m-Option beim git commit weglässt.  export EDITOR='vim'

Git-Branch im Promtersting

Folgende Funktion für die Anzeige des aktuellen Branches, eingeschlossen in weissen, runden Klammern, zur Plazierung in ~/.bashrc.  parse_git_branch() { local BRANCH=`git branch 2&gt; /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'` echo -e "\033[m${BRANCH}\033[m" }

Git-Status im Prompterstring

Die folgende Funktion stellt den Status des Repositories, im Falle von nicht commiteten Dateien bzw. Änderungen wird das ± Zeichen in rot, ansonsten in grün angezeigt. Plazierung ebenfalls in ~/.bashrc.  parse_git_status() { local STATUS=`git status 2&gt;&amp;1` if [[ "$STATUS" != *'Not a git repository'* ]]; then if [[ "$STATUS" == *'working directory clean'* ]]; then echo -e '\033[0;32m±\033[00m' else echo -e '\033[0;31m±\033[00m' fi fi }

Der Angepasste Prompterstring PS1

Weiter unten in der ~/.bashrc die Definition der Variable PS1 im if-Statement eines Debian bzw. Ubuntu Systems, welches greift, wenn force_color_prompt=yes gesetzt ist.  PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w $(parse_git_branch)$(parse_git_status)$\[\e[00m\] ' Sieht dann später in einem Git Verzeichnis ohne Farbe so aus:  florian@box:~/workspace/drush_multi/drush_multi (master)±$ Siehe auch:

Weiterführendes zu Git

Git

Git Hooks

Gitosis

Gitweb

Git-GUI's und -Clients

Git und Drupal