Привет, Хабр, меня зовут Александр Мачулин, я основатель Gramax, open source системы для ведения документации в подходе Docs as Code с визуальным редактором. Gramax хранит контент в git-репозитории. Это означает, что у пользователей могут возникнуть конфликты при синхронизации изменений. Я считаю, что нагружать пользователей решением конфликтов – не очень хорошо и пытаюсь найти решение для этой задачи.
В Notion недавно появился офлайн режим и я решил разобраться как он решает конфликты, когда пользователи отредактировали один и тот же контент. Как я понял, они подключили или используют логику библиотеки Automerge. Её основная суть – решение конфликтов для текстовых редакторов с поддержкой форматирования. И основаная задача, объединить изменения от несколькоих пользователей.
Пример со строкой «Привет, как дела?»:
Пользователь X вносит правку: «Привет, как дела?»
Пользователь Y вносит правку: «Привет, как дела?»
В результате получаем: «Привет, как дела?»
Вернёмся к решению конфликтов в Notion.
Меня интересует как будет работать, если один человек внёс значительные правки в текст, а другой человек этот контент удалил. Смоделировал несколько кейсов:
Я в офлайне редактировал блок текста, и его параллельно кто-то удалил.
Когда я вернусь в онлайн, то контент удалится на моих глазах насовсем и даже в истории изменений я не вижу своих правок.Я в офлайне редактировал статью, и её кто-то параллельно удалил целиком.
Аналогично прошлому кейсу, статья удалится, но я смогу найти её в Корзине с сохранёнными изменениями.
Т.к. Notion – это online first платформа, то такое решение допустимо, в связи с редкостью возникновения подобных ситуаций. Gramax local first и мы такое решение использовать не можем и будем исследовать дальше.
Если у вас есть идеи как удобно решать конфликты, то давайте обсудим их в комментариях!
Комментарии (6)

nin-jin
10.02.2026 08:39В идеале - если идёт вставка в удаленный параграф, то он должен автоматически восстановиться. Но в своей системе я на это забил, ибо другой пользователь может и после моих правок удалить весь параграф, и должна быть возможность восстановить мои. Поэтому я храню версии всех пользователей.

skargik Автор
10.02.2026 08:39Выходит пользователю показываем самую последнюю версию и даем ему возможность восстановить нужную из истории?

nin-jin
10.02.2026 08:39История - это отдельная песня, реализуется у меня через бранчевание или список снепшотов. Я же говорю про мультивселенную - один и тот же документ можно видеть через призму отдельного пользователя (например MV регистр), как результат слияния (например, LWW регистр), и как результат объединения (что-то типа GO множества). Особенно актуально это когда лишаешь прав вандала и все его правки должны автоматически откатиться.

Bambyrov
10.02.2026 08:39Речь о Notion. Не знаком. Ну если на каждой странице может быть (?) свой флаг, и если каждому пользователю в его интерфейс можно вставить (?) нечто, связанное с событием ХочуОфлайн, например:
Private BOOLEAN Flag_Страница1; // локальная переменная страницы, глобальная для
//всех пользователей
BOOLEAN function Страница1_ХочуОфлайн ()
{
if (Flag_Страница1 = = True)
{ // ничего не делать
Return False; }
else
{ Flag_Страница1 = True;
// войти в офлайн на странице1;
Return True; }
};
При выходе пользователя из офлайн должно инициироваться событие сброса флага: Flag = False;
Bambyrov
В результате получаем: «Привет, как дела?». Сомневаюсь. Скорее, хотите получить. Много хотите. Обычно в любой базе данных (если речь о БД) пользователи имеют разные права доступа. Или я чего то не понял?
skargik Автор
Речь о Notion. В нём у пользователей есть одинаковые права на блок текста в статье.