igitti git in a Shell

71px-Git-logo.svgDa wir sicherlich noch alle von den Sylvester-Feierlichkeiten gezeichnet sind, möchte ich euch heute ausser ein Frohen Neues zu wünschen, noch ein wenig mit git in der Kommandozeile behilflich sein.
Da ich mich in der Zwischenzeit doch relativ viel in Git-Repository bewege, lasse ich mir den aktuellen Branch und den Commit-Status in meinem Prompt anzeigen.

lbetz@Leibniz ~/puppetcode/modules/tomcat:next±$

Hier befinde ich mich im Tomcat-Repository im Branch next, ± bedeutet das noch Dateien via commit ins Repository geschrieben werden müssten.

function is_on_git() {
  git rev-parse 2> /dev/null
}
function parse_git_dirty() {
  [[ $(git status 2> /dev/null | tail -n1) != *"working directory clean"* ]] && echo "±"
}
function parse_git_branch() {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1$(parse_git_dirty)/"
}
export PS1="\[${ORANGE}\]\[${MAGENTA}\]\u@\h \[${WHITE}\]\w\$(is_on_git && [[ -n \$(git branch 2> /dev/null) ]] && echo \":\")\[${PURPLE}\]\$(parse_git_branch)\[${RESET}\]\[${ORANGE}\]\[${RESET}\]$ "

Die Farben lassen sich je nach Terminal im Vorfeld anpassen.

if tput setaf 1 &> /dev/null; then
  if [[ $(tput colors) -ge 256 ]] 2>/dev/null; then
    MAGENTA=$(tput setaf 9)
    ORANGE=$(tput setaf 172)
    GREEN=$(tput setaf 190)
    PURPLE=$(tput setaf 141)
    WHITE=$(tput setaf 0)
  else
    MAGENTA=$(tput setaf 5)
    ORANGE=$(tput setaf 4)
    GREEN=$(tput setaf 2)
    PURPLE=$(tput setaf 1)
    WHITE=$(tput setaf 7)
  fi
  BOLD=$(tput bold)
  RESET=$(tput sgr0)
else
  MAGENTA="\033[1;31m"
  ORANGE="\033[1;33m"
  GREEN="\033[1;32m"
  PURPLE="\033[1;35m"
  WHITE="\033[1;37m"
  BOLD=""
  RESET="\033[m"
fi
export MAGENTA
export ORANGE
export GREEN
export PURPLE
export WHITE
export BOLD
export RESET

Und nun wünsche ich zum Abschluss allen noch ein erfolgreiches Neues Jahr, sowie Ilka eine schönen heutigen Geburtstag.

Lennart Betz
Lennart Betz
Senior Consultant

Der diplomierte Mathematiker arbeitet bei NETWAYS im Bereich Consulting und bereichert seine Kunden mit seinem Wissen zu Icinga, Nagios und anderen Open Source Administrationstools. Im Büro erleuchtet Lennart seine Kollegen mit fundierten geschichtlichen Vorträgen die seinesgleichen suchen.

Bash Prompt mit Git Branch Anzeige

Obwohl es da draußen die eine oder andere IDE gibt, die einem beim Entwickeln unter die Arme greift, bin ich doch sehr oft in der Shell in GIT Repositories unterwegs – sowohl privat als auch in der Arbeit auf Debian Stable und Testing sowie für den Paketbau in den diversen CentOS, OpenSUSE, etc VMs. Nachdem ich zudem noch ein fauler Mensch bin, der sich beim 10ten Mal Befehl eintippen oder in der History (Strg+R) suchen dann einen Bash Alias schreibt, geht mir der “in welchem Git Branch bin ich eigentlich grade” Befehl

$ git branch

ziemlich auf den Keks. Vor allem inmitten eines Rebase/Merge, wo ich dann auch noch ein ‘git status’ bemühen muss. Das sind Dinge, die ich sofort auf der Shell sehen möchte. Und dann auch noch farblich so hervorgehoben, dass mans kontrastreich erkennen kann.
Über die Jahre hinweg bastelt man dann dahin mit diversen sed Orgien auf git branch Befehle, bis man dann endlich die ultimative Lösung findet: Das Debian Paket ‘bash-completion’ bietet diese Funktionalität bereits an, und liefert in der Variable $(__git_ps1) den benötigten Output, welcher Branch bzw. welcher Status.

# apt-get install bash-completion

Auf CentOS und Konsorten gibts das Paket (noch) nicht, man kann sich aber mit folgendem Trick behelfen (muss für alle Benutzer durchgeführt werden):

# curl https://raw.github.com/git/git/master/contrib/completion/git-prompt.sh > ~/.bash_git
# vim ~/.bashrc
source ~/.bash_git
# . ~/.bashrc

Nachdem das ja zu einfach wäre, muss man sich dann auch noch mit den Eigenheiten der Bash auseinandersetzen, was Terminalformatierung betrifft. Ich gehe mal nicht davon aus, dass das dem geneigten Leser Freude bereitet, und hängs mal mit an.
Ich verfolge dabei bestimmte Grundprinzipien, die jeder für sich selbst anpassen kann.

  • Eine Zeile für alles, inkl aktuellem Pfad (für Copypaste). Meine native Auflösung ist mind. 1680×1050, bevorzugt 1920×1080 mit entsprechender gnome-terminal Breite.
  • user@hostname sowie hostname als Root Benutzer.
  • Der root Benutzer wird rot dargestellt, der Benutzer hingegen grün (so visualisiere ich u.a. , warum das blöde rm nicht geht 😉 )
  • Das abschliessende Zeichen ist # (root) sowie $ (normaler Benutzer)
  • In Git Repositories wird $(__git_ps1) als (branchname) (dunkelgrün) angezeigt

Folgendes in die .bashrc eintragen und danach sourcen:

# =========================================================
# COLOR PROMPTS WITH GIT BRANCH
# =========================================================
function myPrompt() {
        local GREEN_BOLD="\[\033[01;32m\]"
        local RED_BOLD="\[\033[01;31m\]"
        local BLUE_BOLD="\[\033[01;34m\]"
        local GREEND="\[\033[02;32m\]"
        local REDD="\[\033[02;32m\]"
        local DEFAULT="\[\033[00m\]"
        # \h ... hostname
        # \w ... workdir
        # \$? ... RC
        # \u ... user
        # \$(__git_ps1) ... git branch/action if available
        local USER_BOLD=$GREEN_BOLD
        local USERD=$GREEND
        local USERAT="\u@\h"
        local USERHASH="\$"
        if [ `/usr/bin/whoami` = 'root' ]
        then
                USER_BOLD=$RED_BOLD
                USERD=$REDD
                USERAT="\h"
                USERHASH="#"
        fi
        PS1="$USER_BOLD$USERAT$DEFAULT $BLUE_BOLD\w$DEFAULT"
        PS1=$PS1"$DEFAULT$GREEND\$(__git_ps1)$BLUE_BOLD $USERHASH $DEFAULT"
        # window title
        case "$TERM" in
                xterm*|rxvt*)
                        PS1="\[\e]0;\h: \w (\u)\a\]$PS1"
                        ;;
        esac
}
# set git colored prompt based on uid
myPrompt

Für den Icinga 2 Entwickler sieht das dann so aus
git_bash_promt_user
während man als Root Benutzer das praktischerweise bei unterschiedlichen Konfigurationstests ebenso sieht.
git_bash_promt_root

Michael Friedrich
Michael Friedrich
Senior Developer

Michael ist seit vielen Jahren Icinga-Entwickler und hat sich Ende 2012 in das Abenteuer NETWAYS gewagt. Ein Umzug von Wien nach Nürnberg mit der Vorliebe, österreichische Köstlichkeiten zu importieren - so mancher Kollege verzweifelt an den süchtig machenden Dragee-Keksi und der Linzer Torte. Oder schlicht am österreichischen Dialekt der gerne mit Thomas im Büro intensiviert wird ("Jo eh."). Wenn sich Michael mal nicht in der Community helfend meldet, arbeitet er am nächsten LEGO-Projekt oder geniesst...