Превращаем Midnight Commander в консольный браузер для GIT


Вместо предисловия...

Мне давно хотелось отсматривать код примерно как это сделано в meld, но только в консоли, и еще мне хотелось чтобы это все было увязано с системой управления версиями файлов GIT. В общем чтобы все делалось 1 кнопкой не выходя из mc.
Ydiff
Однажды у нас на канале (или это было на траке...) проявился некто Daniel Borca пошумел-пошумел и убежал, видимо не понравилась ему наша бюрократия, но зато оставил он после себя несколько сыроватых патчей, к готовившемуся релизу 4.7.0-pre1 миднайт коммандера. Один из них содержал в себе ydiff.[ch] и zdiff.[ch]... Как оказалось, то что я хотел получить, было давно уже реализовано в древнем форке mc-mp и в последней версии ru-fork. После 2-х дневного "перепиливания" я подключил функцию сравнения файлов к последней версии mc... Полдела было сделано. :)
Просмотр репозитария GIT
Панельный плагин gitfs
Второй проблемой было то что мне хотелось бы просматривать патчи из репозитария GIT непосредственно в миднайт коммандер, прямо из каталога репозитария. И я задумался над написанием VFS для миднайт коммандер с помощью которого можно было бы производить навигацию по репозитарию в нужной панели. Через несколько минут "ковыряния" родился первый сырой вариант gitfs текущий полностью рабочий, но не окончательный вариант представлен ниже:
#!/bin/sh
 
LANG=C
umask 077
 
gitfs_list()
{
    DATE=`date +"%b %d %H:%M"`
    GIT_DIR="$2/.git"
    user=`whoami`
    git ls-files | while read fname
    do
        echo "-r--r--r--   1 $user     0  0 $DATE `dirname $fname`/(git) `basename $fname`"
    done
}
 
gitfs_copyout()
{
 
    echo -e "$2" > "$4"
    echo "$3"|sed -e s/\(git\)// >> "$4"
}
 
case "$1" in
list) gitfs_list "$@" ;;
copyout) gitfs_copyout "$@" ;;
*) exit 1 ;;
esac
exit 0
 
 
 
Панельный плагин gitlogfs
Мне хотелось не только производить навигацию по репозитарию, но так-же иметь возможность получать файлы любой ревизии. Для этого был написан плагин gitlogfs
#!/bin/sh
 
LANG=C
 
changesetfs_list()
{
    DATE=`date +"%b %d %H:%M"`
    GIT_DIR=`head -n1 $2`".git"
    fname=`tail -n1 $2`
    USER=`whoami`
    git log --abbrev=7 --pretty="format:%at %h %an" "$fname" | while read chset
    do
        TIMESTAMP=`echo $chset| cut -f1 -d" "`
        DATE=`date -d @"$TIMESTAMP" +"%b %d %H:%M"`
        NAME=`echo $chset| cut -f2 -d" "`" "`basename $fname`
        echo "-rw-rw-rw-   1 $USER    0 0 $DATE  $NAME"
    done
 
}
 
changesetfs_copyout()
{
    GIT_DIR=`head -n1 $2`".git"
    fname=`tail -n1 $2`
    chset=`echo "$3"| cut -f 1 -d " "`
    filecommit=`git show --raw --pretty=tformat:%"$chset" "$fname"|grep ^:|grep ...|cut -f3 -d " "|cut -f1 -d "."`
    git show "$filecommit" > "$4"
}
 
case "$1" in
  list) changesetfs_list "$@"exit 0;;
  copyout) changesetfs_copyout "$@"exit 0;;
esac
exit 1
 
Подключение плагинов gitfs и gitlogfs к миднайт коммандер
Для того чтобы любые панельные плагины подключились к mc, достаточно положить их в домашний каталог миднайт коммандера ~/.mc/extfs.d. Для того чтобы вызывался плагин gitlogfs при нажатии на любой файл, начинающийся с префикса (git) необходимо в файле ~/.mc/bindings добавить описание данного типа файла, примерно так:
regex/^\(git\)
        Open=%cd %p#gitlogfs
Иллюстрации
Вызов gitfs производится командой cd #gitfs в каталоге репозитария GIT. Free Image Hosting at FunkyIMG.com Навигация по репозитарию происходит как по любой файловой системе. Free Image Hosting at FunkyIMG.com Вход в gitlogfs производится нажатием ентер на либом файле проекта с префиксом (git) Free Image Hosting at FunkyIMG.com Сравнение 2-х произвольных ревизий файла производятся с помощью горячей клавиши Ctrl-x, Ctrl-y Free Image Hosting at FunkyIMG.com