Samstag, 17. April 2010

Git happens

Ich bin kein besonders großer Fan von Git, allerdings kommt man hin und wieder einfach nicht drum herum. Da mein Standard-Workflow derzeit einfach darin besteht Commits im Nirvana verschwinden zu lassen gibt es eigentlich nur 2 Alternativen für mich:
  1. Eine Selbsthilfegruppe für Git-Geschädigte aufsuchen

  2. Ein paar Skripten schreiben die mir das Leben leichter machen

Zweiteres klang bei näherer Betrachtung einfach attraktiver.

Da ich im privaten Umfeld mehr Mercurial nutze platzt meine .gitconfig derzeit durch Aliase auseinander die meinen Workflow erhalten, 2 davon replizieren in etwa das Verhalten von incoming und outgoing, oder anders gesagt: sie zeigen mir eingehende bzw. ausstehende Commits an.

Beispiel:

// commits die noch nicht in origin/master
// eingeflossen sind
git out origin/master

// commit aus origin/master die noch nicht
// in meinem lokalen Branch liegen
git in origin/master

Die beiden Aliase sind nicht besonders spektakulär aber nützlich:

out = "log --stat HEAD --not"
in = "!f() { git log --stat $1 --not HEAD; }; f"

Ein weiteres Alias reproduziert das verhalten von hg log -G und zeigt mit die History in einem halbwegs lesbaren Graphen an (bei komplexeren Bäumen greife ich aber lieber zu einem Tool wie GitX)

graph = "log --graph --pretty=oneline --abbrev-commit --decorate --all"

Das alles hilft aber noch nicht bei meinem eigentlichen Problem: Commits schrotten.
Hierfür habe ich mir eine kleine Erweiterung geschrieben… Also nicht zum schrotten, sondern zum wiederherstellen ^^.
Mit git orphans werden mir sogenannte "dangling commits" angezeigt, das sind Commits die auf normalem Wege nicht mehr erreichbar sind. Da git ohne Garbage Collection (git gc oder git prune) nicht so ohne weiteres Commits wegwirft sondern als "dangling commits" im Nirvana vorhält, kann ich mit git reset --hard SHA1 (oder in meinem Fall mit dem Alias git rollback SHA1) meinen HEAD auf gerade verlorene Commits umbiegen und alles ist wieder beim Alten. git orphans verifiziert Commitobjekte und zeigt mir den dazugehören History Eintrag an. Das Ganze ist ein simples Shellskript das man einfach zu den anderen git Kommandos (welche bei mir in libexec/git-core liegen) unter dem Namen git-orphans abglegt.

#!/bin/sh

USAGE=''
OPTIONS_SPEC=
. git-sh-setup

if [ "$#" != "0" ]
then
usage
fi

git fsck --lost-found |
while read dangling type sha1
do
case "$type" in
commit)
if git rev-parse -q --verify "$sha1" >/dev/null
then
git log --color -n 1 "$sha1"
echo ""
fi
;;
esac
done | git_pager

Für mich sind das ein paar sehr brauchbare Anpassungen, ich hoffe der ein oder andere findet sie ebenso brauchbar :)

2 Kommentare:

Anonym hat gesagt…

Das "in" Alias ist so wohl einfacher:

in = "git log --stat ^HEAD"

Und sollten die Commits die "orphans" findet nicht auch im reflog von HEAD sein? Zumindest für 90 Tage... Nen "git reflog" oder "git log -g -p" sollte da also reichen...

raichoo hat gesagt…

git orphans ist lediglich eine Erweiterung für meinen Komfort, da ich mich auf der Arbeit nicht stundenlang mit git rumschlagen will sondern es meiner Denkweise anpassen möchte. Klar zeigen die anderen diese Information auch irgendwie an aber nicht so wie ich das gerne hätte. Es geht einfach nur darum das Git meinem Workflow nicht in den Weg kommt. Ich habe halt gerne auf einen Blick was ich gerne wissen möchte und dann auch möglichst ohne lange darüber nachdenken zu müssen wie ich das tue. Beide Befehle die du genannt hast zeigen mir das nicht so ohne weiteres an, git orphans schon.

Das in alias scheint allerdings ein guter Tipp zu sein, danke.

Darüber hinaus wäre ein nicht anonymer schon einen Tacken höflicher bzw. persönlicher. ;)

Gruß
raichoo