[Quicktip] Jenkins baut bereits gelöschte git Branches

Besonders wenn man einen Jenkins Job nicht auf einen bestimmten Branch einschränkt wird man dieses Problem schnell bemerken: Jenkins baut in bestimmten Fällen auf Basis von git Branches, die eigentlich bereits gelöscht sind. Der Fehler tritt auf, weil Jenkins per default das lokale git Repository nicht mit dem Origin bezüglich gelöschter Branches synchronisiert. 

Dieses Problem kann man relativ einfach beheben. Dazu geht ihr in die Konfiguration des betroffenen Jenkins Job und im Bereich “Source-Code-Management“ wählt ihr im Dropdown “Additional Behaviours“ den Punkt “Prune stale remote-tracking branches“. Damit wird vor dem Pull bzw. Fetch genau dieser Sync durchgeführt. Sprich, es werden lokal alle Branches gelöscht, die im Origin nicht mehr vorhanden sind.

[Quicktip] Wie man go get und Atlasssian Stash bzw. Gitlab zusammen bringt

In meiner Tätigkeit als Jenkins Admin hat mir das Thema „go get“ und Stash viel Kopfzerbrechen bereitet. Letztendlich ist „go get“ eine Art Alias für git pull, jedoch wird da einige Magic angewendet. Im Normalfall – also mit github und auch plain git Repos funktioniert das ganze wunderbar, sobald man aber Software wie Gitlab oder Stash verwendet, wird es etwas problematisch. Zum einen ist das „.git“, welches sowohl Gitlab als auch Stash an jedes Repo hängen ein Problem, zum anderen aber auch SSH über alternative Ports.

Zum Problem der „.git“ Endung: hängt einfach ein weiteres „.git“ an euren „go get“ Command. Also:

go get git.mydomain.com/foo/bar.git.git

Etwas kniffliger ist die Verwendung eines alternativen Ports und ssh. Stash macht nämlich genau das – der ssh Port ist 7999 in der Default Config. Aber auch hierfür gibt es eine Lösung. Dazu müsst ihr die Datei „.gitconfig“ in eurem Home Folder editieren bzw. anlegen. Die Datei muss dann so aussehen:

[url "ssh://git@stash.yourdomain.com:7999/"]
insteadOf = https://stash.yourdomain.de/

Sobald ihr nun einen Checkout auf

https://stash.yourdomain.de/foo/bar.git 

macht, biegt Git diesen Request auf

ssh://git@stash.yourdomain.com:7999/foo/bar.git

um. Somit könnt ihr auf andere Ports gehen, komplett auf andere Domains umschreiben usw.

[Quicktip] Globalen SSH Key in Atlassian Stash hinterlegen

Wenn ihr in Stash viele Repositories habt und ein CI Tool wie Jenkins oder Teamcity nutzt, dann möchtet ihr sicher nicht bei jedem einzelnen Repo den SSH Key des Tools hinterlegen. Da ich lange nach der entsprechenden Stelle in Stash gesucht habe und in den Settings nichts dazu zu finden ist, hier eine mögliche Lösung für das Problem:

Die eine globale Stelle für das Problem gibt es nicht, ABER ihr könnt pro Projekt Zugriffsschlüssel hinterlegen. Ruft dazu einfach das Projekt auf, geht dann in die Einstellungen und dort auf Zugriffsschlüssel. Alle hier hinterlegten Keys können nur lesend oder auch lesend und schreibend für ALLE Repositories dieses Projektes freigeschalten werden. So lange ihr also nicht über allzu viele Projekte verfügt, ist die Einrichtung schnell erledigt 😉

[Quicktip] Wie ändere ich nachträglich die Email und den Namen von git Commits?

Stellt euch folgende Situation vor: ihr habt lokal ein Tool entwickelt und während der Entwicklung natürlich bereits mit einem git Repository gearbeitet. Nun wollt ihr das Repository mit einem Server synchronisieren und bemerkt, dass ihr unter falschenm Namen/Email Adresse die Commits abgesetzt habt. Um dies nun nachträglich noch zu ändern, haben die Jungs von Github ein nettes Script zusammengebastelt:

https://help.github.com/articles/changing-author-info

Kopiert den Code in eine Datei namens “replace.sh” in den jeweiligen Repository Ordner und ersetzt die Stellen “your@email.to.match” mit der Email Adresse, bei der ihr eine Ersetzung durchführen wollt. Bei “Your New Committer Name” und “Your New Committer Email” (und das gleiche für “Author”) fügt ihr die neuen Daten ein, die ihr in den jeweiligen Commit Messages sehen wollt.

Wenn ihr nun das Script per “./replace.sh” ausführt, geht git jeden einzelnen Commit durch, schaut, ob die “your@email.to.match” Email Adresse passt und ersetzt in diesen Commits die Daten mit den von euch hinterlegten Ersetzungen.

BITTE AUFPASSEN: Führt dieses Script keinesfalls in git Repositories aus, die bereits mit einem Server bzw. anderen Usern synchronisiert wurden. Dies kann fatale Auswirkungen haben!

[Quicktip] git per Samba Share zeigt alle Dateien als “geändert” an

Nehmen wir folgende Konstellation: Du hast einen Linux Server, der einen Ordner per SMB (Samba, Windows Freigabe) Share freigibt, in dem sich git Repositories befinden. Greifst du nun von einem anderen Rechner auf diese Dateien zu, so wird git alle Dateien innerhalb dieses Repositories als geändert anzeigen. Ein git diff zeigt dann z.B. folgendes:

old mode 100644
new mode 100755

Dies bedeutet nichts anderes, als dass sich die Zugriffsrechte der Dateien geändert haben. Innerhalb der Samba Share Konfiguration kann man diese Rechte (also Zugriff für Benutzer, Gruppe, Alle) regeln. In vielen Fällen wird sich diese Konfiguration von der in git eingecheckten unterscheiden. Um das Problem zu umgehen, gibt es nun folgende Möglichkeiten:

– im Samba Share Config File die Dateirechte korrekt setzen
– innerhalb des git Repositories folgenden Parameter setzen bzw. umstellen:

git config core.filemode false

Bitte beachten: Wenn dieser Parameter gesetzt wird, kann man KEINE Änderungen von Dateirechten in git committen!

Wollt ihr dies auf eurem Rechner global für alle Repositories machen, dann verwendet folgenden Befehl:

git config --global core.filemode false

Bitte hier besonders daran denken, dass nun in ALLEN git Repositories, auf die dieser Rechner zugreift, kein Committen von Änderungen an den Dateirechten möglich ist – es sei denn, der Parameter wird in einzelnen Repositories explizit überschrieben.

[Quicktip] Wenn das remote git repository keinen Push annehmen will…

Erinnerung an mich selbst: wenn mich ein remote git Repo das nächste mal mit so einer Fehlermeldung begrüßt

fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
Auto packing the repository for optimum performance.
fatal: Unable to create '/[reponame].git/packed-refs.lock': Permission denied

…dann macht es Sinn zu prüfen, ob der jeweilige User auf dem Zielserver überhaupt die entsprechenden Schreibrechte für den Repository Ordner hat…

[Quicktip] aktuellen git branch im bash prompt anzeigen

Hier mal wieder etwas nettes für die Mac bzw. Linux User unter euch. Mittels der hier beschriebenen Methode könnt ihr euch einfach – sofern ihr euch innerhalb eines mit git versionierten Ordners befindet – den aktuell ausgecheckten Branch anzeigen lassen. Die hier verwendete Methode gilt für die bash. Mit kleinen Abwandlungen sollte es aber auch auf anderen Shells laufen.

In eurem Homeverzeichnis – mittels eines einfachem “cd” gelangt ihr dort hin – müsst ihr nur die Datei “.bash_profile” bzw. unter Linux die “.bash_rc” editieren und folgende Zeile einfügen (es handelt sich um eine Zeile!):

export PS1='\[\033[01;32m\]\u\[\033[01;34m\] \w\[\033[31m\]$(git branch 2>/dev/null|cut -f2 -d\* -s) \[\033[01;34m\]$\[\033[00m\] '

Falls ein “export PS1” bereits vorhanden ist, müsst ihr es ersetzen bzw. beide zusammenführen.

Was passiert? Durch die Formatierung wird das aktuelle Verzeichnis in grün angezeigt, ein evtl. anzeigbarer Branchname in rot. Die Farbe kommt von den Zahlenwerten in den eckigen Klammern. Wenn ihr keine farblichen Veränderungen wünscht, dann lasst die entsprechenden Codes einfach weg.

Falls ihr bereits eigene Formatierungen für die PS1 vorgenommen habt, findet ihr hier den eigentlich relevanten Teil für die Ausgabe des git branches:

$(git branch 2>/dev/null|cut -f2 -d\* -s) 

Nachdem ihr die bash_profile bzw. bash_rc editiert habt, speichert alles ab, schließt das Konsolenfenster und öffnet es dann erneut. Und schon sind die Änderungen sichtbar.

via asemanfar.com

Versionsverwaltung mit git

Wie so oft in diesem Blog sprechen wir natürlich über ein technisches Thema – und zwar geht es um Versionsverwaltung. Vornehmlich im Bereich Softwareentwicklung angesiedelt kann man damit seinen Quellcode verwalten. Warum braucht man dazu ein eigenes Programm? Man hat die Dateien ja da und kann ab und zu ein Backup machen, oder?

Ganz so einfach ist es doch nicht, denn man kommt mit dieser Vorgehensweise sehr schnell an seine Grenzen. Ein paar Beispiele: mit einer einfachen Dateiverwaltung wird es teilweise unmöglich, im Team zu arbeiten, weil es zwangsläufig dazu kommt, dass mehr als eine Person an der gleichen Datei arbeiten muss. Software ist NIE fertig, es wird immer wieder Änderungen oder Bugfixes geben. Was macht man, wenn man zu einer älteren Version zurück will oder nur mal die Unterschiede zwischen zwei Versionen vergleichen will? Verbreite ich meinen Quellcode sinnvoll, damit mein Opensource-Projekt aktive Mitstreiter bekommt und diese ihr Änderungen auch wieder zu mir zurückfließen lassen können? Diese Liste kann man beliebig erweitern, und es wird immer wieder herauskommen, dass eine Versionsverwaltung doch immer der elegantere Weg sein wird.

Das haben Entwickler ziemlich zeitig bemerkt und entsprechende Programme entworfen, die einen bei diesem Problem unterstützen. Heraus kamen Systeme wie cvs oder Subversion. Die sind schon ganz gut, haben aber immer ein großes Problem: sie brauchen einen Server. Und das veringert die Geschwindigkeit sehr deutlich. Hinzu kommt, dass Arbeit von Unterwegs erheblich erschwert wird, weil man nur bei einer Verbindung zum Server Zugriff auf die Historie einer Datei hat.

Was mich persönlich am meisten gestört hat, war der Umstand, dass die bestehenden Systeme nur sehr schlecht mergen – also zusammenführen mehrerer Änderungen in der gleichen Datei – können. Auch sehr unschön war das Branching – also das Anlegen eigener Entwicklungszweige.

Git ist hier äußerst robust und bekommt nur Probleme, wenn man wirklich die gleiche Zeile verändert. Entwickelt wurde das System von keinem anderen als Linux Torvalds, dem Erfinder von Linux. Ihm war die Verwaltung des Linux Quellcodes schon lange ein Dorn im Auge und am Markt gab es kein Tool, was seinen Ansprüchen genügte. Also entwickelte er ein entsprechendes System selbst – heraus kam git.

Die großen Vorteile: Die Repositories liegen lokal auf jedem Rechner, merge-Prozesse sind sehr schnell und auch sehr genau und das Anlegen von Branches sowie der Wechseln zwischen ihnen stellt kein Problem mehr dar. Es zeigt sich einfach, dass man viel autarker arbeiten kann, da man alle benötigten Daten auf seinem PC hat und erst dann mit dem Server kommunizieren muss, wenn man Commits übertragen oder Updates ziehen möchte. Sehr schön gelöst ist auch die Aufbewahrung der Meta-Daten. Liegt bei Subversion oder cvs in jedem Ordner ein Unterordner mit den Daten, so ist es bei git pro Repository nur ein einziger Ordner, und der liegt im Hauptverzeichnis des Projekts. Möchte man also Dateien versenden, so kann man diese direkt nehmen und muss nicht erst anfangen, jeden Ordner einzeln zu reinigen. Wer schon einmal ein Subversion Projekt von Meta-Daten befreit hat, weiß, wovon ich spreche 😉

Um meine Einleitung zu diesem Artikel noch zu relativieren: Man kann mit git und auch anderen Versionskontrollsystemen jede Art von Datei verwalten. Es gibt z.B. viele Grafiker, die ihre Projekte mit git verwalten, weil sie dann einfach in der Historie vor und zurück springen können. Selbst Backup-Lösungen kann man damit aufbauen. Am effizientesten funktionieren die Systeme aber noch immer mit reinen Textdateien.

Zum Thema Versionskontrollsysteme sei euch übrigens auch folgender Podcast sehr ans Herz gelegt:
CRE 130 – Verteilte Versionskontrollsysteme

Links
git