Существуют два очевидных решения: хранить целиком последнюю версию и иметь команды редактирования для возврата к старым версиям или хранить самую старую версию и иметь команды редактирования для перехода к новым. Хотя второе решение чуть проще запрограммировать, первое предпочтительнее, поскольку из множества версий почти всегда интереснее выбрать новые.
Мы рассмотрим первое решение. В едином файле, называемом файлом истории, хранится текущая версия, за которой следует множество команд редактирования, преобразующих каждую версию в предыдущую (т.е. более старую). Любой набор команд редактирования начинается такой строкой:
@@@ пользователь дата сводка
Сводка — это одна строка, которая вводится пользователем и описывает изменения.
Для работы с версиями используются две команды: get
выделяет версию из файла истории, a put
заносит новую версию в файл истории после запроса на ввод сводки изменений. Прежде чем привести программу, покажем, как выполняются get
и put
и как сохраняется файл истории:
$ echo строка текста > junk
$ put junk
Summary: создадим новый файл
Введите описание
get: no file junk.H
Файл-история не существует
put: creating junk.H
…и put создает его
$ cat junk.H
строка текста
@@@ you Sat Oct 1 13:31:03 EDT 1983
сделаем новый файл
$ echo еще строка >>junk
$ put junk
Summary: одна строка добавлена
$ cat junk.H
строка текста
еще одна строка текста
@@@ you Sat Oct 1 13:31:28 EDT 1983 одна строка добавлена
2d
@@@ you Sat Oct 1 13:31:03 EDT 1983 сделаем новый файл
$
Команды редактирования представляют собой одну строку 2, которая исключает вторую строку файла, преобразуя новую версию в исходную:
$ rm junk
$ get junk
Самая новая версия
$ cat junk строка текста еще строка текста
$ get -l junk
$ cat junk
Версия новейшая, но одна
строка текста
$ get junk
Опять самая новая версия
$ replace еще 'другая' junk
Изменим ее
$ put junk
Summary: изменена вторая строка
$ cat junk.H
строка текста
другая строка
@@@ you Sat Oct 1 13:34:07 EDT 1983 одна строка добавлена
2d
@@@ you Sat Oct 1 13:31:03 EDT 1983 создадим новый файл
$
Для получения нужной версии файла в файле истории записаны команды редактирования. Первая группа команд преобразует самую последнюю версию в предыдущую, вторая группа преобразует предыдущую в пред-предыдущую версию и т.д. Таким образом, мы преобразуем новый файл в его старую версию, запуская каждый раз редактор ed
.
Очевидно, может возникнуть проблема, если в изменяемом файле есть строки, начинающиеся с трех символов. Кроме того, в разделе ошибок описания команды diff(1)
(см. справочное руководство по UNIX) есть предупреждение о строках, состоящих из одной точки. Мы выбрали @@@
для разделения команд редактирования, поскольку такая строка является редкостью для обычного текста.
Конечно, было бы полезно показать здесь процесс развития команд put
и get
, но из-за ограниченного объема книги мы приведем только их окончательные варианты. Команда put
проще команды get
:
# put: install file into history
PATH=/bin:/usr/bin
case $# in
1) HIST=$1.H ;;
*) echo 'Usage: put file' 1>&2; exit 1 ;;
esac
if test ! -r $1
then
echo "put: can't open $1" 1>&2
exit 1
fi
trap 'rm -f /tmp/put.[ab]$$; exit 1' 1 2 15
echo -n 'Summary: '
read Summary
if get -o /tmp/put.a$$ $1 # previous version
then # merge pieces
cp $1 /tmp/put.b$$ # current version
echo"@@@ `getname` `date` $Summary" >>/tmp/put.b$$
diff -e $1 /tmp/put.a$$ >>/tmp/put.b$$ # latest diffs
sed -n '/^@@@/,$p' <$HIST >>/tmp/put.b$$ # old diffs
overwrite $HIST cat /tmp/put.b$$ # put it back
else # make a new one
echo "put: creating $HIST"
cp $1 $HIST
echo "@@@ `getname` `date` $Summary" >>$HIST
fi
rm -f /tmp/put.[ab]$$
После считывания одной строки сводки команда put
обращается к get
для получения предыдущей версии файла из файла истории. Флаг -о
команды get
указывает на переключение выходного файла. В том случае, когда get
не может найти файл истории, она возвращает код завершения ошибки, и put
создает файл истории. Если файл истории существует, то в командах после then
создается временный файл такого формата: самая последняя версия, строка @@@
, команды редактора для преобразования этой версии в предыдущую, старые команды редактора и строки В конце временный файл копируется в файл истории с помощью команды overwrite
.
Читать дальше
Конец ознакомительного отрывка
Купить книгу