git-hist.sh (2440B)
1 #!/bin/bash 2 3 # TODO : 4 # * use cursor keys 5 # * show also current (uncommited) version 6 # * syntax highlighting 7 # * process through nano (problem : nano's output is limited to one single screen, and puts some termcaps at the begining and end of output.) 8 # * use vim : http://machine-cycle.blogspot.com/2007/10/syntax-highlighting-pager.html 9 # * use highlight --ansi --force, or pygmentize -g : http://machine-cycle.blogspot.com/2008/02/syntax-highlighting-pager-reloaded.html 10 # * use emacs 11 # * choose from one of the above by guessing from $EDITOR and what's installed on the system. 12 # * doesn't seem to include pre-rename versions of a file that was renamed. 13 # * git log --follow --name-only --oneline $file 14 # * git whatchanged --follow $file | grep '^\(:\|commit \)' 15 16 file="$1" 17 if [ -z "$file" -o "$file" == "--help" -o "$file" == "-h" ]; then 18 echo "Usage : $0 filename" 19 echo "You must be in a directory versionned with git for this to work." 20 exit 1 21 fi 22 23 statusbar() { 24 echo -e "\e[47m\e[K[$(($i+1)) / $(($max+1))] : ${rev[i]}\e[1000G\e[46D\e[1mh\e[47m : help \e[1mp\e[47m,\e[1m-\e[47m : previous \e[1mn\e[47m,\e[1m+\e[47m : next \e[1mq\e[47m : quit \e[m" 25 } 26 27 page=0 28 pager() { 29 termlines="$(tput lines)" 30 tail -n +$(($termlines*$page/2)) | head -n $(($termlines-2)) 31 } 32 33 show() { 34 clear 35 statusbar 36 git show "${rev[i]}:$fullpath" | nl | pager 37 } 38 39 help() { 40 local garbage 41 clear 42 statusbar 43 echo -e "status line : [version i / of total] : sha1" 44 echo "" 45 echo -e "\e[1mh\e[m : help" 46 echo -e "\e[1mp\e[m,\e[1m-\e[m : previous version" 47 echo -e "\e[1mn\e[m,\e[1m+\e[m : next version" 48 echo -e "\e[1mf\e[m : first version" 49 echo -e "\e[1ml\e[m : last version" 50 echo -e "\e[1md\e[m : scroll down" 51 echo -e "\e[1mu\e[m : scroll up" 52 echo -e "\e[1mt\e[m : scroll to top" 53 echo -e "\e[1mq\e[m : quit" 54 echo "" 55 echo "Press any key to hide this help." 56 read -n 1 garbage 57 } 58 59 fullpath="$(git ls-files --full-name "$file" | head -n 1)" 60 i=0 61 for ab in $(git log --oneline "$file" | cut -d ' ' -f 1 | tac); do 62 rev[i]="$ab" 63 i=$((i+1)) 64 done 65 max="$((i-1))" 66 67 i="$max" 68 show 69 while read -n 1 ab; do 70 case "$ab" in 71 "") continue ;; 72 "p"|"+") i=$((i-1)); [ "$i" -lt 0 ] && i=0 ;; 73 "n"|"-") i=$((i+1)); [ "$i" -gt "$max" ] && i="$max" ;; 74 "f") i=0 ;; 75 "l") i="$max" ;; 76 "d") page=$((page+1)) ;; 77 "u") page=$((page-1)); [ "$i" -lt 0 ] && i=0 ;; 78 "t") page=0 ;; 79 "h") help ;; 80 "q") break ;; 81 esac 82 show 83 done