Ошибки дизайна

А давайте про ошибки в дизайне поговорим. Тем более, что задним умом мы тут самые умные… Я в последнее время много играюсь с миграцией Subversion на Git и многие их косяки так в глаза и лезут.

Начнем с Subversion. Во времена массового перехода с CVS на Subversion, одним из главных аргументов “за” была поддержка директорий и операций копирования/перемещения в Subversion. Было видно, что разработчикам поддержка копирования очень пришлась по душе. Насколько пришлась, что и ветки в Subversion создаются через копирование, а структура репозитория по-умолчанию - это знаменитые три директории trunk, branches и tags.

Я догадываюсь как принималось это решение. Что-нибудь в духе “прикиньте, одна операция поддерживает и копирование, и ветки, и метки. Не нужно писать новый код для отдельного пространства имен веток. У нас уже есть этот код”. Но если пересчитать набитые шишки, то становится понятно, что решение было так себе… не очень… совсем хреновое решение это было, как оказалось.

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

Скажем количество шагов в пути для trunk и branches/foobar разная. Это значит, что любой скрипт должен это корректно обработать. Не существует способа найти все ветки в произвольном репозитории. Операция копирования не обязательно означает создание ветки - а значит без какого-нибудь соглашения не обойтись. Ну а мы знаем насколько хорошо люди выдумывают совместимые стандарты.

Использование копирования для создания веток автоматически означает, что Subversion создать рабочую копию из людой директории в репозитории. Отличная оптимизация, когда нужно выкачать один файл, но, опять же, это означает, что скрипты не могут делать массы полезных предположений о структуре репозитория. Практически сразу же вся эта гибкость запрещается и создается wiki страничка “чекаут делается так, а ветки называются только так, а всех кто делает не так - прибью нафиг”.

Теперь давайте про Git. Линус выбрал другую крайность. Вместо того, чтобы оставить поддержку копирования для файлов, но сделать нормальные ветки, он сделал нормальные ветки, но выкорчевал поддержку операций копирования. За одно под раздачу попали пустые директории.

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

Что же тут плохого, спросите вы? В данном случае проблема упирается в психологию людей. Да, соглашается подавляющее большинство разработчиков, - поддержка копирования и пустые директории в принципе не нужны. Но! Мы к ним так привыкли. Мы хотим линейную историю, явную поддержку копирования и пустые директории. Нам без них не уютно.

Вы будете смеяться, но это реальная проблема. Особенно, когда мигрируешь с Subversion на Git.

Но ведь оно раньше работало. Я мог сделать так и так.

Полностью согласен, но, на кой, простите, вам это нужно делать именно таким способом?

Но ведь это единственный правильный способ. Мы так всегда делали…

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

comments powered by Disqus