KVM, video virtio, Debian 8 guest, host with Intel HD 4000 – install a 4.9 kernel on the guest for optimal 2D graphics performance !

Some time ago I wrote a post about the use of new virtio video driver for a KVM guest with a Debian 8 operative system. See:
KVM, video QXL und video virtio – Video-Auflösung des Gnome-Desktops eines Debian 8-Gastystems einstellen
The KVM host at that time was a PC with a native Nvidia graphics card. In my post I was very positive about the 2D-performance results of the spice/virtio combination for the KVM guest graphics.

Two days ago I had to perform the installation of a Debian 8 KVM guest - this time, however, the host was a laptop with an Optimus system: The internal graphics card of the i7-3632QM CPU was/is an Intel HD Graphics 4000. (The laptop has an additional Nvidia GT645 M, which can be used via Bumblebee.) Under normal conditions the Intel HD graphics (with the i915 kernel module) has sufficient power to support 2D and 3D accelerated GUIs. In my case the laptop ran on Opensuse Leap 42.2, qemu-kvm was of version 2.9, libvirt of version 3.3 (installed from the "virtualization"-repository: http://download.opensuse.org/repositories/Virtualization/openSUSE_Leap_42.2/). But this time I got a bit disappointed.

Disappointing 2D-graphics performance of the Debian8 KVM guest with kernel 3.6, with spice/QXL and spice/virtio

I experienced two problematic points with the Debian 8 guest and its original 3.6 kernel:

  • The performance with the Spice/QXL-graphics of the KVM guest was not at all convincing - especially not with GTK-applications (neither on a KDE or Gnome 3 GUI of the guest) at and above guest graphics resolutions 1400x900. I saw tearing of windows during fast movements across the spice terminal screen. Especially disappointing was the performance of Firefox ESR: Sluggish reactions of all kinds of window contents and slow reactions to scrolling of complicated web site contents - especially of running videos. But the QXL driver at least gave me the choice of many, many guest resolutions up to the maximum resolution of the host.
  • The performance was only slightly better with the new "virtio" driver. But the choice of guest resolutions was very limited with a maximum of 1280x768px.

Update to the latest kernel on the Debian 8 guest

I then read on some Internet websites that the virtio graphics driver on qemu/kvm requires a kernel later than version 4.x on the guest system, too. So why not try? The installation of newer kernels on Debian 8 is possible by adding the "backports" repository to apt's configuration. We have to a add a line

deb http://mirror.one.com/debian/ jessie-backports main contrib non-free

to /etc/apt/sources.list on the Debian system. The we execute

apt-get update

and

apt-get install -t jessie-backports linux-image-amd64

to get the latest kernel installed. In my case this is a SMP kernel of version 4.9.18. Up to now this kernel lead to no conflicts or problems with any of the installed software on the Debian 8 guest.

Results of the updated guest with kernel 4.9

The graphical performance of the Debian guest with spice/virtio combination, however, changed dramatically to the better! Actually, the overall 2D-performance is now really convincing - even on the relatively weak Intel HD 4000. The tear free moving of window frames of all kinds of Qt- or Gtk3-applications across the spice terminal is just one point. The other is that the performance impression of e.g. Firefox ESR on the virtualized guest is almost not distinguishable from Firefox on the host's KDE interface. Below you see 2 FF windows on the Gnome GUI of the Debian 8 KVM guest plus a QGit window. One FF window plays a video.

And in addition I now get all resolutions I could wish for:

I love KVM! Even on laptops!

Eternal Blue – und die vermeintliche Sicherheit nach MS Windows Updates

Wannacry und EternalBlue sind gerade in aller Munde. Zu Recht; der bereits eingetretene (wirtschaftliche) Schaden ist immens. Auf der Linux-Seite braucht man sich hier übrigens nicht auf ein hohes Ross zu setzen: Heart Bleed, Shell-Shock, massive Probleme mit SSH und TLS und KEX-Algorithmen seien nur als Beispiele dafür genannt, welche Schwachstellen auch Linux-Systeme lange Zeit unerkannt aufwiesen. Niemand weiß, wie lange die vor ihrer Behebung von wem ausgenutzt wurden ... Ich finde, in einem solchen Fall ist klammheimliche Schadenfreude völlig unangebracht. Zumal auch viele Admins in einer heterogenen Welt leben müssen - und mit Samba Brücken zu Windows-Servern oder PCs hergestellt haben. [Es stellt sich nebenbei die Frage, ob eigentlich Samba schwachstellenfrei ist ....]

Was ist eigentlich mit Angriffen ohne Ransomware?

Diskussionswürdig erscheint mir ferner ein Punkt, der mir im Moment in der hektischen Berichterstattung etwas unterzugehen scheint; viele der in deutschen Tageszeitungen erschienen Artikel zu Wannacry hoben vor allem auf Angriffsvektoren ab, die bösartige E-Mail-Anhänge voraussetzen. Die SMB-Schwachpunkte betroffener Windows-Systeme wurden von vielen "fachkundigen" Journalisten lediglich als Hebel für die schnelle Verbreitung der Malware begriffen. Die Aufregung in den Zeitungsartikeln konzentrierte sich deshalb vor allem auf das Thema "Erpressung" und natürlich den Funktionsausfall der betroffenen Systeme.

Dabei hatten Experten und u.a. auch die Fa. Cisco frühzeitig und völlig zu Recht auf folgenden Punkt aufmerksam gemacht:

Eternal Blue ist ein Exploit, den Angreifer gezielt und direkt gegen Systeme, die die SMB-Schwächen aufweisen und verwundbar sind, in einem LAN oder auch aus dem Internet heraus einsetzen können. Voraussetzung ist nur, dass auf den Zielsystemen bestimmte SMB-Ports zugänglich sind. Und natürlich kann im Rahmen des Angriffs auch eine ganz andere und weniger offensichtliche Payload (Schadware) als eine Ransomware zum Einsatz kommen.

Eigene Experimente mit Kali

Ich bewahre nicht ganz zufällig ältere Sicherungsimages von Win7/8/10-Images für VMware auf. Eine solche Kopie konnte ich gestern benutzen, um ein paar Experimente mit EternalBlue und dem Angriffs-Framework "Fuzzbunch" von einem Kali-System aus durchzuführen. Natürlich abgeschirmt von der Umwelt. Ergebnis war die praktische Bestätigung dreier plausibler Vermutungen:

  • Der Einsatz der im April publizierten Angriffswerkzeuge Fuzzbunch (Python-basiert; läuft auf Linux-Systemen unter Wine) und Eternal Blue ist bei ein wenig Erfahrung relativ einfach. Ein aktueller Umlauf von Modifikationen und neuen Angriffsvarianten ist deshalb als wahrscheinlich anzusehen.
  • Ein Angriff gegenüber Windows-Systemen, die die für Eternal Blue notwendigen Schachstellen im SMB-Protokoll aufweisen und von außen über SMB-Ports zugänglich sind, kann direkt und ohne Umwege (über Fake-Webseiten oder bösartige E-Mail-Anhänge) über das Internet geführt werden. Scan-Verfahren zur Identifizierung angreifbarer Systeme lassen sich von bösen Zeitgenossen jederzeit anfertigen. (Nachtrag 27.05.: Für Netzwerk-Admins steht nun z.B. ein NSE-Script für NMAP bereit).
  • Welche Payload (Schadware, Backdoor etc.) ein Angreifer nach Kompromittierung in das Windows-System einschleust, ist relativ beliebig. In Frage kommen u.a. Meterpreter Reverse Shells.

Nachtrag 27.05.2017:
Da ich inzwischen per Mail zwei Anfragen bekommen habe, ob ich die durchgeführten Experimente nicht im Detail beschreiben möchte, Folgendes: Nein, ich möchte nicht ins Detail gehen. Grund: Die deutsche Gesetzgebung (Hacker-Paragraph). Außerdem sind im Internet bereits genügend präzise Beiträge und Filme zum konkreten Einsatz von EternalBlue erschienen.

Reicht ein Update?

Das Problem hat aufgrund der beträchtlichen Zeitspanne, die seit der Veröffentlichung der Eternal-Tools vergangenen ist, eine weitaus größere Dimension, als so mancher Windows-Nutzer und Konsument von einschlägigen Zeitungsartikeln zur aktuellen Ransomeware-Welle meinen möchte. Bereits im April wurde der Einsatz des Exploits im Detail diskutiert; Hacker hatten also frühzeitig die Möglichkeit, sich tiefer einzuarbeiten.

Dass es viele direkt aus dem Internet angreifbare Windows-Systeme gab und gibt, muss nach den Ereignissen der letzten Tage nicht mehr großartig bewiesen werden. Ich selbst kenne einige kleinere Firmen, die Windows einsetzen und die über das Internet Filesharing per SMB nutzen. Worüber nun alle Verantwortlichen, die bislang anfällige Windows-Systeme betreuen, intensiv nachdenken sollten, ist also das Folgende:

EternalBlue ermöglicht einem Angreifer vor allem den Zugang zu einem kompromittierbaren Windows-System. Der Angriff muss aber keineswegs mit der Implementierung von Ransomware verbunden sein - auch wenn sich die Presse hierauf kapriziert.

Gerade geschickte (und wirklich böse) Angreifer, die perfidere Ziele als eine begrenzte Gelderpressung im Sinne haben, werden nach einem erfolgreichen EternalBlue-Angriff auf den gehackten Systemen problematischer Tools als eine offen nach außen sichtbare Ransomware implantieren. Gerade die wirklich ernst zu nehmenden Angreifer werden sich auf dem kompromittierten System still verhalten, Spuren verwischen, im Hintergrund ihre Privilegien erhöhen, Daten abziehen und sich - wiederum mit Hilfe von Eternal Blue auf andere Systeme im (Firmen-) LAN ausbreiten. Alles ohne, dass man das nach außen hin im Alltagsbetrieb merken müsste. Das war ja gerade das, was die NSA vermutlich mit Eternal Blue und dem Exploit Kit "Fuzzbunch" bezweckte.

Es genügt deshalb keinesfalls, jetzt auf den Systemen, die die SMB-Schwachstellen aufweisen, mal schnell die bislang versäumten Updates einzuspielen und wegen nicht zu Tage getretener Ransomware zu meinen, dass die Welt dann wieder in bester Ordnung sei. Ist sie mitnichten .... denn die wirklich gefährlichen Angreifer haben sich ggf. bereits unerkannt eingenistet.

Diejenigen Windows-Nutzer und Admins, bei denen die Ransomware den Angriff offensichtlich machte, sind in gewisser Weise besser dran als diejenigen, die auch Systeme mit den SMB-Schwachstellen hatten, exponiert waren und mittels Eternal Blue von intelligenten Hackern oder Organisationen angegriffen wurden - die aber davon bislang gar nichts merkten, merken oder merken werden. Man könnte ja auf Virenscanner hoffen - aber das Thema einer Maskierung von Schad-SW gegenüber Scannern ist ja nun wirklich kein Neues; das ist und bleibt ein ewiges Katz und Maus-Spiel ....

Im Bereich der Wirtschaft steht deshalb mal wieder die Bewertung der Auswirkungen unerkannter Wirtschaftsspionage im Vergleich zu den Kosten einer umfassenden Bereinigung potentiell betroffener Systeme an. Als verantwortlicher Admin würde ich jedenfalls kritische Windows-Systeme, die die SMB-Schwachstellen aufwiesen, nach den Vorgängen der letzten Tage neu aufsetzen oder aber zumindest ihren ausgehenden Datenverkehrs feinmaschig überwachen - auch und gerade dann, wenn keine Ransomware erscheint.

Denjenigen Administratoren, die die Gefahr besser ausloten wollen, lege ich zudem einige kürzlich erschienene Veröffentlichungen im Internet zum konkreten Einsatz von EternalBlue, Fuzzbunch etc. ans Herz. Damit sind bereits ein paar Schlagworte für die Suche genannt; weitere Stichworte wären Kali, Wine, msfconsole und Empire.

Nachtrag 26.05.2017:
Meine lieben Linux-Kollegen, die sich bislang ggf. sicher wähnten und Samba im Einsatz haben, seien auf folgende Artikel zu SambaCry hingewiesen:
http://thehackernews.com/2017/05/samba-rce-exploit.html
https://www.heise.de/security/meldung/Jetzt-patchen-Gefaehrliche-Luecke-in-Samba-3725672.html
https://www.heise.de/security/meldung/SambaCry-Gefaehrliche-Sicherheitsluecke-in-Samba-finden-und-patchen-3726053.html

Interessant zu lesen sind auch die zugehörigen Diskussionen im zugehörigen Heise-Forum - u.a. wegen eines in diesem Falle überflüssigen Lagerkampfes zwischen Linux- und Windows-Anhängern.

Erste Schritte mit Git für lokale und zentrale Repositories unter Eclipse – III

Wir machen weiter mit unserer Einführung von Git - genauer EGit - unter Eclipse. Im ersten Post dieser Serie
Erste Schritte mit Git für lokale und zentrale Repositories unter Eclipse – I
hatten ich ein einfaches Szenario vorgegeben und zugehörige Aufgaben für die Arbeit mit Git unter Eclipse definiert. Im zweiten Post
Erste Schritte mit Git für lokale und zentrale Repositories unter Eclipse – II
hatte ich gezeigt, wie man unter Eclipse ein vorhandenes Projekt mit einem Git-Repository versieht.

Ich fasse nochmal die dort geleisteten Schritte unter EGit für Eclipse zusammen:

  • Vorhandenes Projekt unter Eclipse vorbereiten und von SVN-Resten befreien.
  • Target-Verzeichnis für das Git-Repository anlegen.
  • Git-Repository im Target-Verzeichnis initialisieren und EGit den Transfer aller Projekt-Dateien in den "Working Tree" im Target-Verzeichnis vornehmen lassen. Dazu ein dortiges Verzeichnis angeben.
  • Alle Projekt-Verzeichnisse/-Dateien für eine Indizierung/Behandlung in der Git-Versionsverwaltung vormerken. Dabei eclipse- und projektspezifische Dateien/Verzeichnisse gezielt außen vor lassen.
  • Alle Projekt-Verzeichnisse/-Dateien erstmalig "committen". Im Staging View den Commit mit Informationen zum Autor und Committer sowie mit hinreichenden Kommentaren versehen.

Das führte zu folgendem Bild im Eclipse-View "Git-Repositories":

Die Anzeige dieses Views erhält man übrigens über den Menüpunkt "Window=> Show View => Other => GIT => Git Repositories". Es lohnt sich übrigens gleich auch noch prophylaktisch den View "Git Staging" zu laden.

Wir wenden uns nun der Aufgabe 4 unseres Aufgabenkataloges zu:

  • Aufgabe 4: Durchführung von Änderungen im Verzeichnisbaum des Projekts und Testen nachfolgender "Commits". Blick auf die Git-Versionshistorie auf dem PC. Identifizierung des HEAD-Commmits bzw. -Knotens.

Wer das EGit-Interface nach diesem Artikel genauer studieren will, nutze bitte das Handbuch unter: http://wiki.eclipse.org/EGit/User_Guide

Testverzeichnis und Testdatei

Um die Inhalte des Working Tree nicht zu zerstören, lege ich ein Testverzeichnis "gittest" mit zwei Dateien an : "test.php5" und "basic.css". Deren Inhalt ist sehr simpel; s.u. Nach der Anlage sieht das im PHP-Explorer so aus:

Man beachte die kleinen symbolischen Fragezeichen; sie deuten an, dass der Git-Status noch undefiniert ist.

Zu diesem Zeitpunkt sind die neuen Dateien noch nicht ohne ein "Refresh" (F5) im Working Tree des Views "Git-Repositories" zu sehen:

obwohl sie dort natürlich vorhanden sind. Also F5 drücken.

Um das neue Verzeichnis samt Dateien der Versionsverwaltung zu unterwerfen, müssen wir das neue Verzeichnis in PHP-Explorer auswählen und zunächst in den Index des Repositories aufnehmen. Hierzu benutzen wir, wie im letzten Artikel beschrieben, den Button mit dem grünen "+"-Zeichen in der Git-Bedienleiste unter Eclipse:

Im "Git Staging View" erhalten wir dann automatisch die Möglichkeit, einen Kommentar einzugeben:

Danach drücken wir rechts unten auf den "Commit"-Button. Anschließend sind die Fragezeichen-Symbole verschwunden:

Der Master-Branch hat sich entsprechend verändert:

Man beachte die Anzeige des verkürzten Hashes für den Commit, der zur HEAD-Version des aktuellen Branches (im Moment der Master-Branch) führte!

Nun können wir uns mal die sog. "Historie" für "test.php5" ansehen. Dazu rufen wir im Kontext-Menü dieser Datei den Menüpunkt "Team=>Show in History" auf. Im sich öffnenden Historie-View erhalten wir dann:

Es wird der Originaltext der committeten Datei angezeigt. Im Zusammenhang mit dieser Datei gibt es bislang nur einen Knoten, der dem letzten Knoten des Masterbranches entspricht (Man vergleiche die Hashnummern!). Siehe auch, dass im unteren Bereich des Views der aktuelle Stand der Datei "test.php5" mit "/dev/null" verglichen wird!

Dateiänderungen, Commits und Anzeige der Dateiinhalte für verschiedene Knoten

Wir ändern nun den Inhalt der PHP-Datei; wir setzen einen Variablen-Wert um (aus var $a=100; wird var $a=200;) und speichern dann die Datei:

Eclipse zeigt uns (ähnlich wie bei SVN auch) an, dass die Datei zwar geändert wurde, aber die Änderung noch nicht "committed" worden ist. Man erkennt das z.B. am ">"-Symbol an der Datei im Datei- bzw. PHP-Explorer. Um die Änderung im Repository zu erfassen, müssen wir den "Commit"-Button in der Git-Bedienleiste (gelber Zylinder mit rotem Pfeil nach rechts) betätigen. Wie erwartet öffnet sich wieder der "Staging View", in dem wir die Änderung kommentieren können. Danach drücken wir wieder den Button "Commit". Ergebnis im Repository-View:

Interessanter ist nun ein Blick in den View "History"; dort wird die Historie auch in Form eines Graphen angezeigt; die Knoten sind dabei streng gemäß der zeitlichen Historie angeordnet:

Ggf. nochmal F5 drücken, falls im unteren Bereich die Differenzen nicht angezeigt werden sollten. Wir erkennen nun zwei Knoten (mit unterschiedlichen Hashes), die die Historie dieser Datei betreffen. Netterweise wird uns auch die Änderung zur Vorgängerversion angezeigt. Das ist komfortabel!

Ein Doppelklick auf einen Knoten oder aber auf einen der mit einem Knoten verbundenen Dateinamen rechts unten im History-View öffnet übrigens die durch die Versionsänderung betroffene Datei im jeweiligen Zustand des Knotens im Editorbereich - dort wird hinter dem Namen dann auch der Hash des Commits angezeigt. Sind mehrere Dateien betroffen, wird die erste ausgewählte geöffnet.

Klickt man allerdings in der Icon-Leiste, die sich im History View rechts oben befindet, das Icon für den "Compare Mode" (links neben dem Branch-Icon), so öffnet sich die Datei im "Compare-Modus"; die Inhalte der Version des früheren Knotens werden mit der aktuell vorhandenen Version des momentan gewählten Branches verglichen.

Ein Markieren zweier Knoten des Graphen und ein "rechter Mausklick" öffnet ein Kontextmenü; auch hierüber erhalten wir die Option (Menüpunkt "Compare with each other"), ein Vergleichsfenster für diese Versionen im Editorbereich von Eclipse zu öffnen:

Das ist in unserem Fall trivial, da bislang ja nur zwei Knoten existieren. Die genannten Möglichkeiten des History-Views entfalten ihren vollen Nutzen natürlich aber vor allem bei längeren und komplexeren Historien.

Eine längere Änderungshistorie

EGit liefert noch sehr viel Möglichkeiten und Views mehr als oben beschrieben. Der Leser kann ja nun selbst mal eine Kette von Änderungen an verschiedenen Testdateien vornehmen und jede dieser Änderung committen. Natürlich ist das nicht die normale Situation in einem ernsthaften Entwicklungsprozess; wir spielen im Moment ja aber nur, um uns an EGit zu gewöhnen.

Die nachfolgende Darstellung zeigt dann das Ergebnis nach 5 bzw. 4 weiteren Änderungen an unseren beiden Testdateien "test.php" und "basic.css" im View "History". Den History View erreicht man übrigens auch durch einen "rechte-Maus"-Klick auf den Branch im View "Git Repositories"; dort ist "Show In => History" zu wählen:

Wir bekommen nun eine etwas umfangreichere Darstellung der erstellten Knoten in unserem Master-Branch. Ein "Rechte-Maus-Klick" auf einen Knoten führt übrigens zu einem Kontextmenü, über dessen Punkt "Open in Commit Viewer" man auch eine Ansicht der zugehörigen Commit-Einträge (Kommentare etc.) öffnen kann.

Unser lineare Graph ist im Moment allerdings immer noch etwas langweilig, da wir bislang kein Branching vorgenommen haben.

Testweises Branching

Branching gehört zwar nicht zum Umfang dieser Serie von Posts zu Git. Damit die Graphen jedoch nicht ganz so langweilig aussehen, müssen wir aber unseren Master-Branch durch weitere Entwicklungszweige ergänzen. Dort sind neue Knoten zu erzeugen und auch ein Zusammenführen von Entwicklungszweigen (Mergen) ist natürlich interessant. Ich gehe hier allerdings nur kurz auf diese Thematik ein. Das gewählte Beispiel ist entspricht dabei nur einer wenig sinnvollen, praxisfernen Spielerei; wer einen schnellen und realitätsnahen Überblick darüber gewinnen will, wie man Branching für verschiedene Situationen eines Entwicklungsprozesses effektiv nutzt, möge sich z.B. das Buch "Git" von Rene Preißel und Bjørn Stachmann (dpunkt.verlag) zu Gemüte führen.

Einen neuen Branch legt man im View "Git Repositories" z.B. über das Kontextmenü des Zweiges "Branches => Local" an.

Danach gibt man in einem Popup-Formular den Namen des neuen Branches an; die Option "Checkout" zum Wechseln in den Branch ist bereits vorbelegt:

Man erkennt danach im View "Git Repositories", dass der neue erzeugte Branch "Consolidation" auch der aktuelle (Arbeits-) Branch geworden ist (kleiner schwarzer Haken). Alle kommenden Änderungen finden auf den vorhandenen Dateiständen dieses Branches statt, bis man ggf. den Branch des Repositorys wieder gezielt wechselt.

Man erkennt an der Abbildung, dass ich auf diese Weise bereits insgesamt 4 Branches zu meinem Repository angelegt habe - neben dem "master" die Brances "bugfix", "consolidation" und "php-extensions". Nun kann man in diesen Branches testweise die gleiche Datei (test.php5) in unterschiedlicher, aber konflikterzeugender Weise editieren und dann im jeweiligen Branch durch Commit einen neuen Knoten erzeugen. Die jeweiligen Dateiversionen in den jeweiligen Branches sollen danach einander widersprechende Inhalte besitzen.

Ich ändere beispielsweise im Branch "bugfix" den Wert von $a auf "$a=10" ab. Dazu muss ich zuerst in den Branch "bugfix" wechseln. Dies geht wieder im Kontextmenü von "Local":

Ist die Datei "test.php5" schon im Editor-Bereich geöffnet, ändert sich der Editor-Inhalt automatisch auf den des aktuellen Branches. Nach dem Branch-Wechsel führen wir die Änderung "$a=10;" durch und committen die neue Version. Dann machen wir eine entsprechende unabhängige Änderung "$a=20" in der gleichen Datei des Branches "php-extensions" und committen auch dort. Abschließend nehmen wir eine Änderung "$a=30" im Branch "master" vor. Schließlich wechseln wir in den Branch "consolidation". Dort setzen wir "$a=40" und committen.

Wir "mergen" nun in einem weiteren Schritt den Branch "bugfix" in den Branch "consolidation". Wir lösen den Merge-Vorgang über das Kontextmenü des Branches "consolidation" aus:

In unserem speziellen Fall muss das zu einem Konflikt führen. Grund ist, dass in den zu mergenden Dateien unterschiedliche Vorgaben in demselben betroffenen Zeilenbereich stehen und die logische Historie nicht eindeutig ist. Git kann nicht wissen oder erschließen, welche Änderung in welchem Branch die gewünschte sein soll. Beide Änderungen sind ja nach dem Zeitpunkt der Verzweigung in gleichen Codebereichen erfolgt. (In manchen Git-Tools kann man übrigens einstellen, ob man rein der zeitlichen Abfolge vertrauen soll. Ich nutze ein solche Option aber aus guten Gründen nie).

Der Konflikt wird auch an anderer Stelle deutlich markiert; im geöffneten Editor einer betroffenen Datei u.a. durch gezielt vorgenommene Einschübe:

Man beachte die Markierung der verschiedenen Varianten im Editor durch ">>>" und "<<<" Zeilen. Im PHP Explorer View "Git Staging" ist der Konflikt dagegen durch eine deutliche rote Markierung am jeweiligen Dateieintrag hervorgehoben.

Rechts sieht man übrigens das sog. "merge tool", dass man etwa über das Kontext Menü der Datei im unteren Bereich "Unstaged Changes" öffnen kann. Es geht aber immer auch über Unterfunktionen des Punktes "Team" im Kontext-Menü der Datei im PHP-Explorer.

Wir lösen den Konflikt im Editor auf; d.h. wir entscheiden uns dabei für eine der angedeuteten Varianten, z.B. die Variante vom Branch "bugfix" (a=10). Die nicht gewünschten Zeilen und die Markierungszeilen aus dem Merge-Prozess löschen wir.

Wir speichern die geänderte Datei dann ab; diese ist dadurch aber noch nicht in den Index des Branches aufgenommen. Aus Sicht des Views "Git Staging" ist der Konflikt somit noch nicht behoben; eine Aktualisierung F5 hilft nichts und auch ein "Commit" ist nicht möglich. Hier muss man vielmehr eine explizite Entscheidung zur Aufnahme der eben als künftiges Soll gespeicherten Version in den Index wählen; dies geschieht im Kontextmenü des Git-Staging-Views durch Auswahl des Punktes "Add to index":

Danach ist ein Commit unserer neuen Dateiversion möglich:

Hinweis:
Alternativ zu einer direkten Arbeit im Editor ist auch das Arbeiten über das "Merge Tool", das im wesentlichen einer Diff-Azeige mit Zusatzfunktionen entspricht, möglich. Das mag jeder mal selber ausprobieren.

Wir committen und mergen danach in ähnlicher Weise den Branch "php-extension" in den Branch "consolidation". Dabei entscheiden wir uns für den Wert von "$a=20" aus "php-extensions".

Zwischenzeitlich können wir immer mal den Zustand des jeweils aktiven Branches im View "History" begutachten (zur Sicherheit dort F5 drücken):

Bei mir sieht das so kompliziert aus, weil ich in den anderen Branches bereits früher Änderungen durchgeführt hatte. Der "consolidation"-Branch wurde ja aus dem Master-Branch im Zustand "a54a2b7" erzeugt; seine "Vergangenheit" davor ist mit der des Master-Branches identisch.

Durch Klicken des rechten Branch-Symbols oben rechts in der Icon-Leiste dieses Views erhält man übrigens eine graphische Ansicht aller vorhandenen Branches. Es gibt in dieser Icon-Leiste noch weitere interessante Möglichkeiten, deren Studieren sich lohnt. Interessant ist ferner das Markieren zweier Versionen aus dieser Ansicht, die man dann per Kontext-Menü direkt in einer "Compare"-Ansicht öffnen und vergleichen kann.

Schließlich mergen wir noch den "consolidation"-Branch in den Master-Branch und übernehmen dabei den Wert des "consolidation"-Branches. Wir erhalten am Ende eine recht komplex wirkende Branch-Historie; im oberen Bereich sind die hier angesprochenen Änderungen mit den Hash-Nummern "fc53e0e, d3995ff, a262600, b999a78, df23e87, fb258ff, f48c829" zu sehen:

Hinweis zu sog. "Fast Forward Branches":

In unserem Beispiel zu Branching haben wir gezielt Konflikte provoziert, die bei den verschiedenen Merges manuell beseitigt werden mussten. In vielen Fällen erfolgen aber Code-Änderungen z.B. durch Hinzufügen von Code-Fragmenten oder durch Code-Änderungen, die nicht in Konflikt mit der letzten gemeinsamen Version von zwei Branches stehen, wenn im Zielbranch an dem betroffenen Codesegment seit der Verzweigung nichts geändert wurde. Entsprechende Änderungen haben eine eindeutige logische Historie und können in Form sog. einfacher "Fast Forward Merges" [FFM] abgewickelt werden: EGit übernimmt die Änderungen dann einfach automatisch in die Target-Datei; ein manuelles Eingreifen ist nicht nötig. Ein "FFM" wird in einem Zwischendialog nach dem Mergeversuch angekündigt; das Merge-Popup (s.o.) erlaubt spezielle Einstellungen für FFMs.
Da Git aber nicht die Semantik der Änderungen überprüfen kann, muss man auf der Basis vorhergehender Codevergleiche natürlich auch im Fall von FFMs sicher sein, dass man mit der direkten Übernahme der Änderungen keinen Unsinn anrichtet. Das Denken nimmt einem Git nicht ab.

Andere Tools

Später werden wir zur Überwachung und ggf. Manipulation zentraler (!) Repositories auf den jeweiligen Servern (grafische) Tools installieren müssen, die unabhängig von Eclipse und EGit funktionieren. In Frage kommen aus dem Opensource Umfeld etwa:

GitGui (wird mit dem Git-Paket ausgeliefert; wirkt wegen Tcl/Tk etwas hausbacken, Graphen; umfangreicher Satz von Werkzeugen zur Repository-Pflege), Git Cola (Graphen; nützliche Funktionen zur Manipulation des Repositories), QGit (Graphen und einige einfache Manipulationsbefehle), GitG (web-ähnliche Oberfläche) sowie Giggle (Graph und Klon-Funktion). Die zugehörigen Pakete lassen sich für die jeweilige Linux-Distribution relativ einfach finden und installieren; ich gehe hier nicht darauf ein.

Alle genannten Tools erlauben eine Anzeige der vorhandenen Branches, ihrer Knoten und zumindest von Versions-Differenzen eines ausgewählten Knotens zur Vorgängerversion. Der Umfang an Funktionalitäten zur Pflege/Manipulation des Repositories ist unterschiedlich; hervorzuheben sind hier "Git GUI" und "Cola Git". Für eine einfache Graphenanzeige genügen GitG, QGit und Giggle.
Ich zeige abschließend den oberen Teil der Graphen in GitGui (gitk-Ansicht), QGit, Giggle, Cola-Git (DAG). Das ist alles recht ähnlich; die DAG-Ansicht finde ich eher verwirrend - hier wird die Logik zu stark komprimiert. Cola-Git bietet alternativ aber auch die gitk-Ansichten von GitGui.

GitGUI

QGit

Giggle

Cola-Git (DAG-Ansicht)

In GitG, GitGui, Cola Git (gitk) kann man zwischen einer rein chronologischen und einer topologisch-logischen Graphendarstellung wählen. Eine rein chronologische Darstellung hilft in einen komplizierten Situationen die Historie zu rekonstruieren.

Fazit

Das EGit-Plugin für Eclipse bietet einige hübsche Features an, um die Historie von Änderungen zu verfolgen. Wir haben in diesem Artikel allerdings nur an der Oberfläche gekratzt. Der Leser ist aufgerufen, weitere Möglichkeiten zu erkunden. Zumindest für ein lokales Repository werden dabei kaum Wünsche offen gelassen. Auch die Graphendarstellung für einzelne Branches im History-View braucht sich nicht zu verstecken. Die Knoten sind chronologisch geordnet - und neben jedem Knoten wird in einer separaten Spalte der zugehörige verkürzte Hash angezeigt. Das bietet komischerweise keines der anderen Tools an.

Die Funktionalitäten von EGit kann man übrigens auch in einer von Eclipse unabhängigen Form genießen. Hierzu lädt man sich die entsprechende Anwendung "GitEye" der Fa. CollabNet (s. https://www.collab.net/downloads/giteye) für Linux herunter. Das Archiv einfach expandieren und GitEye starten.

Im Vorgriff auf ein Monitoring und eine direkte Verfolgung von Änderungen eines zentralen Git-Repositories auf einem entfernten Host haben wir einen kurzen Blick auf andere Tools geworfen, die sich ebenfalls leicht installieren lassen und wie EGit eine grafische Aufbereitung bieten. Auch hier gilt es, sich mit den Möglichkeiten und Grenzen der Tools vertraut zu machen.

Im nächsten Artikel dieser Serie
Erste Schritte mit Git für lokale und zentrale Repositories unter Eclipse – IV
verfolgen wir allerdings die im ersten Artikel gesetzten Ziele weiter. U.a. werden wir ein zentrales Repository auf einem Host im LAN anlegen und auch dieses Repository mit Push-Befehlen auf einen aktuellen Stand bringen. Parallel werden wir uns die durchgeführten Änderungen auf dem zentralen Tool über QGit ansehen. Das entspricht den Aufgaben 5 -7 des ersten Artikels.