четверг, 10 апреля 2008 г.

Ответственность за изменения...

После вчерашнего задумался о подписывании изменений. Многие системы контроля версий имеют данную фичу, а насколько она применима и имеет смысл? Попытаюсь изложить свои криптографически-этические соображения.

Начнем с глобальных мотивов. Если взять большой открытый проект типа linux, то там ситуация такова, что конкретные изменения вносят тысячи людей, Линус не обязан им доверять и может вообще не подозревать об их существовании (нет необходимости импортировать ключи), потому, что эти изменения попадают к нему через доверенных лиц, которые, как бы, берут на себя ответственность за эти изменения. Собственно git и не поддерживает (во всяком случае в стандартной поставке) подписывания каждого изменения, там есть только подписывание меток.

В более ограниченных проектах ситуация с доверием возможна, если бы не несколько но. При единственной ветви разработки никаких проблем нету. (CVCS?) Проблемы начинаются при ветвлениях.

Предположим что существует некая ветвь разработки a. от нее создается ветвь b, и обе ветви некоторое время развиваются независимо... a1 -> a2 -> ... an, b1 -> b2 -> ... bn. Естественно, что каждый набор изменений подписан кем-то.

Теперь ветвь b сливается с ветвью a.

Первый путь (mercurial вроде так поступал), Это когда изменения сливаются в рабочей копии и формируется версия a(n+1), которая потом коммитится в ветви a. Но в этом случае получается что ни подписанные истории изменений, не авторство их не попадает в ветвь a. И этическая сторона в этом месте такова, что нельзя ссылаться на автора изменений (annotate, log), потому что его подписи нигде нету. То есть ситуация ровно как в ядре линукс, автор слияния берет на себя ответственность за все вносимые изменения.

Я, как человек сведующий в криптографии понимаю что любое изменение подписанных данных автоматически приводит к недействительности подписи. Но теоретически, если изменения ветви b производились в файлах не изменяемых в ветви a, то историю изменений можно перенести из b, при этом новая версия (дерево файлов) всеравно подписывается автором слияния, но изменения по конкретным файлам имеют изначальное авторство. Но любой конфликт нарушает эту идиллию коренным образом, поскольку любое постороннее изменение файла исключает возможность применения вливаемых изменений, и ситуация сводится к предыдущей.

файл1: a -> b1 -> ... bn (HEAD of a)
файл2: a -> a1 -> ... an (HEAD of a)

Это справедливо только для бинарных дельт, diff'ы можно было бы накатывать и на посторонние изменения, если не учитывать тот факт что при подписывании изменений стоит обращать внимание и на содержимое исходного файла, иначе как можно дать гарантию, что изменение не деструктивное?

Как ни крути а подписанное изменение в любом случае должно опираться на конкретную версию исходного файла.

Получается, что подписывание результатов будет работать только в строго координируемых, полностью подконтрольных, где все участники известны, проектах.

В случае децентрализованных систем контроля (особенно таких где репозиторий и рабочая копия неразрывно связаны) правильнее будет строить доверительность на уровне взаимосвязи репозиториев. Подписывание отдельных изменений тоже допустимо, но по большому счету оно ничего не дает. Авторство будет сохраняться только при экспорте (всмысле при раздаче изменений от центрального узла к переферийным, ну при паутинообразной организации типа linux ядра :) ), При слиянии изменений подписи перестают работать.

К тому же при большом количестве участников необходимо распространять и ключи...

Может я опять чего-то не учитываю? Что-то еще хотел написать да забыл. завтра вспомню.

PS: Вот, спустя неделю, кое что вспомнил. Подписывать надо не наборы изменений, а состояние версии. Но это требует от системы контроля целостности состояний, то есть версия должна фиксировать содержимое всех файлов проекта (как в monotone). Что касается git, то его изменения ИМХО кумулятивны, и вообще не понимаю каким боком туда прикручивают цифровые подписи, а ведь прикручивают же, или я опять ошибаюсь?