Freitag, Mai 23, 2014

Alltags GIT

Hier eine Zusammenstellung meiner häufigsten GIT Alltagsoperationen: In der Regel geht es mit dem Clonen eines Repositories los:
git clone <url> <local_directory>
Im Anschluss fange ich mit der Arbeit an und editiere einige Dateien. Diese werden mit add und commit in das lokale Repository übernommen.
git add .
git commit -m "Sinnvoller(!) Kommentar."
Falls Dateien gelöscht wurden, dann lohnt sich der folgende Befehl. Dieser sammelt alle geänderten und gelöschten Dateien ein und fügt sie dem Änderungsindex zu.
git add -u
Nach dem commit ist im Anschluss eventuell ein push in das Remote Repository durchzuführen:
git push
Eventuell lege ich vor Arbeitsbeginn einen lokalen Branch an. Das ist vielleicht empfehlenswert, bevor man mit der Arbeit beginnt.
git branch <branch_name>
Oder das Wechseln auf einen bestimmten Branch.
git checkout <branch_name>
Beim Branch-Wechsel bleiben unter Umständen Dateien im Verzeichnisbaum liegen, die in man dort nicht wünscht. Z.B. neu angelegte Dateien, die noch nicht unter Versionskontrolle stehen. Das folgende Kommando entfernt alle für GIT unbekannten Dateien und Verzeichnisse. Aber aufpassen: Die Dateien und Verzeichnisse sind dann gelöscht! GIT kann diese Dateien nicht wieder hervorholen.
git clean -f -d
Und falls die Arbeiten sich hinziehen, lohnt sich vielleicht ein Replizieren des Branchs in das Remote-Repository.
git push origin <branch_name>
Irgendwann, wenn das Arbeitsergebnis nach MASTER gemerged wurde, kann der lokale Branch gelöscht werden.
git branch -d <branch_name>
Im zweiten Schritt bietet sich vielleicht auch das Löschen des zugeordneten Remote-Branches an.
git push origin :v1.1.1_optimate
Einen Remote-Branch abholen:
git checkout -b <branch_name> origin/<branch_name>
Ein Tag vergeben (In diesem Fall mit einem sprechendem Kommentar):
git tag -a v1.2.0 -m 'Version 1.2.0'
Und im Anschluss wird das Tag, wenn gewünscht, auch Remote verfügbar gemacht:
git push origin --tags
Unter Windows hat sich die folgende Farbeinstellung bei mir bewährt. Die Standard-Farbe verschwimmt etwas bei einem eingestellten Zeichensatz Consolas mit Schriftgröße 12.
git config --global color.status.untracked "bold red"
UPDATE (22.05.2014 21:18 Uhr): Unter Github habe ich mir ein kleines Shell Skript zusammen gestellt. Den Command Line Prompt habe ich um den GIT Status erweitert. Weitere Highlights sind die Funktionen 'git_remove_missing_files', 'git_stats' und 'git_info'.

Dienstag, Dezember 17, 2013

git push and current branch

Bei der Ausführung von git push versucht GIT alle lokalen Branches auf das Remote-Repository zu schieben. Diese Funktion lässt sich abschalten oder besser begrenzen. Mit
git config --global push.default current
schiebt GIT nur die Änderungen des aktuellen Branches auf das Remote-Repository. Ab GIT 2.0 wird diese Einstellung der Standard sein.

Oracle VirtualBox Update Ärger

Oracles VM VirtualBox Manager wollte aktualisiert werden. Kein Problem. Download gestartet. Installer gestartet.... Der Versuch, die alten VM Installationen zu starten, schlug mit einer Fehlermeldung fehl.
VT-x is disabled in the BIOS. (VERR_VMX_MSR_VMXON_DISABLED)
Ein ähnliches Problem hatte ich vor einiger Zeit. Damals half es, die Benutzerrechte für die VMs neu zu setzen. Das hatte diesmal keine Wirkung. Im Netz bin ich auf die folgende Lösung gestossen: Zunächst muss die VBoxManage.exe im Dateipfad liegen. Ist das gegeben, kann man den folgenden Kommandozeilen Befehl ausführen:
VBoxManage list vms
Das liefert eine Liste aller registrierten VMs. Bei mir sieht das so aus:
"Oracle Developer Days" {de67fcab-5dce-4e21-bc4b-17e176dce2c3}
"ubuntu-laptop" {5c6e9005-4a1d-4163-833d-ede800a71f06}
"betoffice-server" {96319b3a-88b4-46ad-8e87-41e1d1d10ca1}
Für alle VMs habe ich dann das folgende Kommando ausgeführt:
VBoxManage modifyvm "Oracle Developer Days" --longmode off
VBoxManage modifyvm "ubuntu-laptop" --longmode off
VBoxManage modifyvm "betoffice-server" --longmode off
Und schon lassen sich die VMs wieder starten.

Mittwoch, August 21, 2013

GIT und EGIT

Das EGit von Eclipse und die Kommandozeilenversion von GIT streiten sich momentan um die Zuständigkeit. Einer von beiden schaltet den File-Modus einiger ausgewählten Dateien um. Das hat zur Folge, daß entweder Eclipse oder die Kommandozeilenversion eine Änderung sieht, obwohl inhaltlich keine vorliegt. Dieses Dilemma kann man mit dem folgenden Befehl lösen. Das eigentliche Probleme scheint mir dabei aber noch nicht gelöst. Mit diesem Kommando ignoriert GIT alle File-Mode Änderung:
git config core.filemode false

Samstag, Mai 11, 2013

jQuery, Ajax und Cross Origin

Die Ajax Funktion von jQuery ist bekanntlich sehr praktisch. Letztens bin ich mit dieser Funktion auf einige Probleme gestossen. Hier das Grundgerüst für die Problemstellung: Ein Javascript Ajax Aufruf der eine JSON Response vom Server erwartet. Laut jQuery Dokumentation kann die Ajax Funktion eigenständig erkennen, dass die Response im JSON Format vorliegt und konvertiert die Response in ein entsprechendes Javascript Objekt. Ein eigener Aufruf von $.parseJSON(...) kann also bei der Verarbeitung der Transport Nachricht entfallen. Im IE 9 und unter Chrome hatte ich mit diesem Verhalten keine Probleme. Unter Firefox hat dieser Automatismus aber nicht funktioniert. In der Dokumentation zu jQuery findet sich der folgende Hinweis:
At present, due to a bug in Firefox where .getAllResponseHeaders() returns the empty string although .getResponseHeader('Content-Type') returns a non-empty string, automatically decoding JSON CORS responses in Firefox with jQuery is not supported.
Zu finden unter jQuery.ajax()
Das Problem hatte ich mir natürlich selbst eingebrockt. Die Javascript Resource, die den Ajax Aufruf absetzen möchte, residiert unter der URL
http://tippdiekistebier.localhost/aktuell/auto_1tipp.html
Der Ajax Aufruf ist ein POST an die URL
http://tippdiekistebier.localhost:8080/betoffice-jweb/tipp/submit
Damit handelt es sich um ein sogenanntes "Cross-Origin Resource Sharing". Die Server URL ist die vermeintlich Gleiche. Ausschlaggebend ist hier aber die zusätzliche Port Nummer für den POST Befehl. Damit der Browser die Response verarbeitet, muss der Server im Response Header die Eigenschaft
response.setHeader("Access-Control-Allow-Origin", "*");
setzen. Falls diese Eigenschaft nicht gesetzt ist, kann der Browser die Response verweigern, was die mir bekannten Browser auch alle so umsetzen. Zusätzlich dazu setze ich den Content-Type.
response.setHeader("Content-Type", "application/json; charset=UTF-8");
Die jQuery Ajax Funktion kann die Response dem JSON Format zuordnen und automatisch ein Javascript Objekt erzeugen. Das funktioniert mit einer aktuellen Chrome Version, wie auch mit dem Internet Explorer 9. Unter Firefox findet die automatische Konvertierung nicht statt. Einen Hinweis zu diesem Problem findet sich in der Doku von jQuery (siehe oben). Ich muss also unterscheiden, ob ich die JSON Konvertierung selbst durchführe oder diese bereits von jQuery durchgeführt wurde. Im Beispielcode frage ich das Transport Objekt nach einer erwarteten Eigenschaft ab. Ist diese nicht definiert, führe ich die Funktion $.parseJSON(...) aus. Danach kann die eigentliche Verarbeitung der Response erfolgen.
$.ajax({
    type : 'POST',
    url : 'http://tippdiekistebier.localhost:8080/betoffice-jweb/tipp/submit',
    data : my_data,
    cache : false,
    success : function(transport) {
        if (transport === undefined) {
            _messageSender.successButNoResponse();
        } else {
            try {
                var jsonResponse = transport;
                if (transport.notOk === undefined
                        || transport.ok === undefined) {
                    jsonResponse = $.parseJSON(transport);
                }

                if (jsonResponse.notOk) {
                    ....
                } else if (jsonResponse.ok) {
                    ....
                }
                
            } catch (exception) {
                _messageSender.unexpectedError(exception);
            }
        },
    error :  function(xhr, ajaxOptions, thrownError) {
        _messageSender.unexpectedError(thrownError);

        if (console && console.log) {
            console.log("Ajax Request Status: " + xhr.status);
            console.dir(thrownError);
        }
});
Kennt man das Problem, ist die Lösung relativ naheliegend. Mich hat das jedoch einige Stunden Javascript Debugging gekostet.