Это проблема, с которой я столкнулся в паре разных проектов, над которыми я работаю.
Поскольку проекты все еще находятся в незаметной разработке, а сама проблема представляет для них потенциально более широкий и независимый характер, я собираюсь анонимизировать их - но, FWIW, я работаю в основном с Ruby / Rails и MySQL.
Сценарий
Я хочу иметь систему для редактирования документов, которая похожа на вики, но имеет следующие функции:
- полное поведение типа VCS
- несколько асинхронных пользователей
- fork & merge
- вину и разницу
- управление версиями, фиксация и откат
- автономное редактирование рабочих копий / локальных репозиториев
- эффективное и надежное хранилище
- может быть в MySQL или в независимом репо, но не хранить полный плоский текст для каждого документа
- возможность ветвления на уровне файлов, слияния и т.д.
- максимальная прозрачность для пользователей (они очень не хакеры)
Мне не нужны децентрализованные репозитории, поскольку все мои приложения используют авторитетные серверы, но я не против иметь их.
В отличие от хорошей вики, документы, с которыми я имею дело, часто избыточны (с произвольными незначительными изменениями) и имеют довольно сложную историю редактирования и слияния.
Существующие решения
Первое требование очень хорошо выполнено, например, по GitWiki:
К сожалению, Git (и все другие известные мне VCS) работают только с вилками уровня репозитория; он не допускает разветвлений на уровне файлов.
В любом случае, что такое вилка уровня файла / документа?
Предположим, что я написал кучу рекомендательных писем для многих людей, и они постоянно доступны. (Немного надуманного примера, но потерпите меня.)
Реально, у меня есть три уровня изменений:
- базовый шаблон рекомендательного письма, который применяется ко всем из них
- более конкретное письмо для конкретного человека
- полностью конкретное письмо для конкретного человека на конкретную работу
Теперь предположим, что я хочу изменить свою контактную информацию или у меня есть новая информация о конкретном человеке. Концептуально это должно быть так просто:
- изменить основную букву
- (авто) объединить это во все буквы, которые наследуют от него
1081 * включение *
Это также можно рассматривать как использование управления версиями для более гибкой / надежной системы включения. Разница в том, что, в отличие от этого простого примера, части другого документа могут быть скопированы с произвольными правками .
Другой упрощенный пример может помочь объяснить эту проблему включения.
Предположим, что наши "документы" - это сообщения на форуме. Одна общая черта - цитировать посты других людей полностью.
Сама цитата избыточна, и в моем использовании мне полезно знать, кто кого цитировал / что и т. Д.
Итак, в простом случае мы можем сделать следующее: когда кто-то цитирует другого, в его редакторе появляется что-то вроде: [quote msg=1234 v=1]What's the best recipe for mince pie?[/quote] My mom always used to...
В большинстве случаев пользователь просто оставляет это в покое и добавляет свои ответы ниже. Затем мы можем сделать простое включение, удалить лишний текст и заменить его указателем на цитируемое сообщение - благодаря возможности отображения пользовательского интерфейса для указания того, что цитируемый текст был отредактирован с момента его цитирования, и легко см. любую версию.
На один шаг сложнее, пользователь отредактирует его как отрывок, например, [quote msg=1234 v=1]mince pie?[/quote] Parsnip!
. Опять же, мы можем сделать только указатель, на этот раз добавив смещение и длину для включения, и пользовательский интерфейс для расширения выдержки. Однако наше включение прекращается, если пользователь делает что-то вроде: [quote msg=1234 v=1]What's the best recipe for stupid pie?[/quote] Fixed! lol
. Мы можем справиться с этим, включив весь «фиксированный» текст (в менее глупых случаях, например, это может быть полезным обобщением или перефразировкой) вместе с нашим указателем. Пользовательский интерфейс может переключиться на «нескорректированную» версию, автоматически выделить разницу,
К сожалению, простое хранение нового текста - вместо того, чтобы обрабатывать его как реальную ревизию - означает, что мы отказываемся от всей функции контроля ревизии, и в больших документах (например, программе, главе книги и т. Д.) Этого недостаточно.
Больше сложности
Более сложный сценарий может включать, например:
- «ветви разработки» некоторого конкретного документа (и, следовательно, его зависимых), редактируемые и версионируемые параллельно с «производственной веткой»
- сложные истории разветвления / слияния (например, дочерний документ редактируется, разворачивается по длине, а затем частично повторно объединяется с его родителем и братьями и сестрами в той степени, в которой он имеет к ним отношение)
- неиерархические отношения документов (например, вы разветвляете мой шаблон рекомендательного письма и делаете свои собственные настройки; затем я объединяю некоторые из ваших настроек с моими; тем временем кто-то еще раз разбудил мои ...)
- и т.д.
Я в основном имею дело с реальными текстовыми документами, но я думаю, что это можно считать применимым в равной степени к коду.
Вопросы:
- Что-нибудь уже делает это или подобное?
- Что было бы хорошим способом спроектировать такую систему?
- Какие компоненты будут хорошими кандидатами для использования? (например, git и sinatra используются в gitwiki)
- Есть что-то, что я пропускаю?