#!/bin/zsh # # Show differences between $1 and $2 with selection TMP=/tmp/git-show-i-$$ mkdir -p $TMP function cleanup() { rm -rf $TMP trap "" 0 exit } trap "cleanup" 0 2 15 git diff --no-prefix $* 2>/dev/null | \ csplit -z -b %04d -f $TMP/hunk# - "/^diff --git/" "{*}" > /dev/null if [ ! -f $TMP/hunk#0000 ] ; then read 'x?Push enter' exit 0 fi LIST=( ${(f)"$(head -qn1 $TMP/* 2>/dev/null | awk '{print "" $3;}')"} ) if [ -z "$LIST" ] ; then read 'x?Nothing to show. Push enter' exit 0 fi # translate a given selection index, if for a submodule, into the # commit ids for the submodule function submodule_delta() { # Determine which diff-hunk is selected HUNK="$(grep -lF "diff --git $1 " $TMP/* )" # If the hunk ends with "+Subproject commit ", then it's a sub project tail -n 2 $HUNK | grep "^.Subproject commit " | sed 's/.* //' } PROJECT="$(git rev-parse --show-toplevel| sed 's/.*\///')" if [ -n "$FOCUS" ] ; then # point at the focused item LAST=${$(echo "${(F)LIST}" | grep -nF "$FOCUS")%%:*} fi [ -z "$LAST" ] && LAST=1 while true ; do X="$(iselect -f -n "git-show-i" -K -t "$PROJECT: commit $1" -p $LAST \ $LIST "Done" )" [ -z "$X" ] && break LAST=${$(echo "${(F)LIST}" | grep -nF "${X#*:}")%%:*} #read "x?$LAST $X" case "${X%%:*}" in RETURN|KEY_RIGHT) [ "${X#*:}" = Done ] && exit 0 # If the selection is a sub module, then use git-show-i # recursively for the submodule versions SUBS=( $(submodule_delta "${X#*:}" ) ) if [ -z "$SUBS" ] ; then #git meld $* -- "${X#*:}" git-differ $* -- "${X#*:}" else ( cd ${X#*:} ; $0 $SUBS ) fi continue ;; esac done