Подтвердить что ты не робот

Упрощенная семантика для команды "винить" - хорошая вещь?

Я работаю над новой структурой weave для хранения истории управления версиями. Это, несомненно, вызовет некоторые религиозные войны о том, является ли это правильным способом делать вещи, когда он выходит, но это не мой вопрос прямо сейчас.

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

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

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

4b9b3361

Ответ 1

На самом деле я написал одну из реализаций вины (Subversion, которую я считаю, если кто-то не заменил ее в прошлом году или два). Я помогал и другим.

По крайней мере, большинство реализаций вины не выполняют то, что вы описываете:

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

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

Например, Mercurial просто выполняет поиск по первой итеративной глубине до тех пор, пока не будут обвинены все строки. Он не пытается учесть, делают ли отношения маловероятным, что он обвинил правильную.

Git делает что-то более сложное, но все же не совсем так, как вы описываете.

Subversion делает то, что делает Mercurial, но график истории очень прост, поэтому он еще проще.

В свою очередь, на самом деле то, что вы предлагаете, - это то, что все они действительно делают:

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

Ответ 2

На личном уровне я предпочитаю ваш упрощенный вариант.

Причина: Вина не используется очень сильно.

Поэтому я не вижу смысла тратить много времени на его всестороннюю реализацию.

Это правда. Вина в значительной степени оказалась одной из тех особенностей "горшка с золотом в конце радуги". Это выглядело действительно круто от тех из нас, кто стоял на земле, мечтал о том дне, когда мы могли просто нажать на файл и посмотреть, кто написал, какие строки кода. Но теперь, когда он широко применяется, большинство из нас осознало, что на самом деле это не очень полезно. Проверьте активность в теге blame здесь, на Stack Overflow. Он безмятежно опустошен.

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

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

Таким образом, для того, чтобы винить на самом деле быть полезной экономией времени для более чем удачливых ситуаций, вину нужно эвристически пробираться мимо новой строки, пробелов и идеально блокировать изменения копирования/перемещения. Это звучит как очень высокий порядок, особенно при чистке журнала изменений для одного файла, в большинстве случаев он не даст много различий в любом случае, и вы можете просто просеять вручную довольно быстро. (Значимым исключением является, пожалуй, плохо спроектированные исходные деревья, где 90% кода заполнено одним или двумя файлами ginormous... но кто в эти дни в среде с совместным кодированием делает большую часть этого?).

Заключение: Дайте ему виноватую реализацию, потому что некоторым людям нравится "винить"! в списке функций. И затем переходите к тому, что имеет значение. Наслаждайтесь!

Ответ 3

Алгоритм слияния строк является глупее, чем разработчик. Если они не согласны, это просто указывает на то, что слияние неверно, а не указывает точку принятия решения. Таким образом, упрощенная логика должна быть более правильной.