Вместо предисловия...
Мне давно хотелось отсматривать код примерно как это сделано в 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:%h "$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.
Навигация по репозитарию происходит как по любой файловой системе.
Вход в gitlogfs производится нажатием ентер на либом файле проекта с префиксом (git)
Сравнение 2-х произвольных ревизий файла производятся с помощью горячей клавиши Ctrl-x, Ctrl-y