Переформатирование и контроль версий

23

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

SELECT id, name, address
FROM persons JOIN addresses ON persons.id = addresses.person_id;

может быть лучше написано как / лучше написано, чем

SELECT persons.id,
       persons.name,
       addresses.address
  FROM persons
  JOIN addresses ON persons.id = addresses.person_id;

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

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

  • Одинаковый стиль во всех коммитах
  • Минимальная работа слияния

?

Для пояснения, речь идет не о передовых практиках при запуске проекта, а о том, что следует делать, если крупный рефакторинг был признан Good Thing ™, но вы все еще хотите отслеживать историю? Никогда не переписывать историю - это хорошо, если это единственный способ гарантировать, что ваши версии всегда работают одинаково, но как насчет преимуществ чистого переписывания для разработчиков? Особенно, если у вас есть способы (тесты, определения синтаксиса или идентичный двоичный файл после компиляции), чтобы гарантировать, что переписанная версия работает точно так же, как и оригинал?

l0b0
источник
24
Почему вы хотите переписать историю? Это побеждает цель контроля версий. Вы хотите убедиться, что приложение, которое вы отправили 3 месяца назад, соответствует версии xxxxxx без малейших сомнений. Даже банальное переформатирование недопустимо.
Саймон Бергот
5
Мне нравится комментировать коммиты, которые я делаю с пометкой "Переформатировать. Без функциональных изменений"
Rig
3
По несвязанной теме кажется, что вы предлагали переписать историю Git, переформатировав весь код. Не дайте людям идеи, переписывание истории Git плохо для 99,9% случаев. Переформатирование не является крайним случаем .1%.
Эндрю Финнелл
4
В некоторых языках (я смотрю на ВАС, Python) переформатирование может изменить логическое функционирование кода. Вы должны были бы иметь возможность анализировать все языки, хранящиеся в вашей VCS, чтобы безопасно отслеживать и игнорировать переформатирование.
Йорис Тиммерманс
3
Реформаторы являются изменениями кода и должны быть зафиксированы как таковые.
Дэвид Коуден

Ответы:

26

Выполните переформатирование как отдельные коммиты. Это будет минимально влиять на историю, и вы сможете сразу увидеть, какие коммиты просто переформатируют, а какие фактически меняют код. Он может быть искаженным git blameи похожим, но если он указывает на фиксацию только для переформатирования, довольно просто искать предыдущее изменение перед этим.

Harald
источник
Я видел проекты сорванными в течение нескольких недель, потому что один из разработчиков думал, что это хорошая идея. Если вы собираетесь это сделать, заранее разберитесь с рисками и точно определите, как далеко вы пойдете с форматированием. Я думаю, что у mjfgates правильный ответ.
Johntron
1
Похоже, что у рассматриваемой команды есть большие проблемы, чем форматирование кода. Но да, я не рекомендую делать это, если вам не нужно. Если вы хотите переформатировать изменения, я бы сказал, что лучше делать их как отдельные коммиты, чем смешивать с функциональными изменениями.
Геральд
Да, много проблем: PI просто хочет предупредить новых разработчиков, что это не так просто, как кажется. Инструменты массового переформатирования являются рискованными (особенно если вы создаете их самостоятельно с помощью регулярных выражений - по крайней мере, используете AST), и если вы заботитесь о проверке кода и отслеживании ошибок, он может действительно испортить ваш процесс. Лично я пишу свой код так, чтобы он соответствовал стилю каждого файла, хотя я не против пересмотреть код, когда переформатируются несколько функций. Многие разработчики зацикливаются на стиле кода и пренебрегают более
важными
В программировании все не так просто, как кажется :)
harald
13

Не переписывайте историю VCS: это противоречит принципам VCS.

Не пытайтесь автоматизировать исправление форматирования: это лечит симптомы, а не реальную проблему (= разработчики не следуют стандартам кодирования).

Определите стандарт кодирования и рекомендации по форматированию в общем документе и получите согласие всех разработчиков.

Вы упоминаете Git, который великолепен, потому что он распространяется. С DVCS очень легко применять лучшие практики через рабочий процесс привратника . Привратники отклоняют предложения о слиянии (= запросы на получение в Git), которые не соответствуют общим правилам. И я имею в виду отклонить жирным шрифтом, иначе нарушитель кодера не потрудится следовать правилам и продолжит повторять те же ошибки.

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

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

Янош
источник
1
Понижено, потому что автор четко заявляет, что это в контексте проектов, которые не начинались с «... четкого, полного, проверяемого и обязательного руководства по стилю с первого дня». Он не может лечить настоящую проблему, потому что это уже произошло. Я согласен с вами, хотя :)
Johntron
2
Отклонение означает, что между людьми и роботом будет борьба. Был там. Рано или поздно роботу потребуется действительно сложный кусок кода, который будет отформатирован нечитаемым способом. Примеры: строка Java на самом деле является оператором SQL, но робот этого не знает; пробел перед закрытием пары может содержать информацию о структуре кода для человека, но не для робота; Параметры функции разбиты на несколько строк самым бессмысленным образом ...
18446744073709551615
9

Ответ на ваш настоящий вопрос: «Вы не делаете». Я не знаю ни одного текущего инструмента SCM, который мог бы отслеживать изменения в логике от кода, отформатированного одним способом, через значительное изменение форматирования и через дальнейшие изменения после того, как код отформатирован новым способом. И, вы знаете это, потерять историю на куске кода - это не хорошо.

Соответственно, я собираюсь немного противоречить вашему первому предложению. Форматирование кода не имеет значения , что много. Довольно приятно, но мы здесь не для этого. Я, как и любой другой, понимаю, что получить дамп в чей-то старый адский странный код варианта K & R с отступами в два пробела - отстой (1), но ... форматирование на самом деле не является препятствием для понимания происходящего, если только это не является чем-то исключительным патологический. И в этом случае у вас все равно возникнут проблемы с изменением кода, и вам не следует об этом беспокоиться.

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

1) - Когда-то я владел средством просмотра буфера обмена Windows. Все это было одно, 150k, модуль C. Я нашел место, где разные люди использовали, я думаю, пять разных стилей скобок в пределах тридцати строк друг от друга. Но этот раздел вещей работал. Я носил распечатку этого куска кода в течение десяти лет, но я не совал его, потому что эта история имела значение, и этот код был как минимум в трех исходных деревьях (Windows 3.x, NT, future 95), которые все жили в разных зданиях.

mjfgates
источник
В прошлом, используя hg, я обнаружил, что объединение по частям является бесценным инструментом в борьбе с хитрыми большими факторами слияния. Обычно я делаю слияние коммитов перед большим рефакторингом, затем сливаю сам большой рефакторинг и, наконец, сливаю коммиты с момента повторного фактора. Каждый из этих трех слияний самих по себе является гораздо проще , чем пытаться распутать беспорядок , что результаты делать все слияния на одном дыхании.
Марк Бут
Я абсолютно согласен! Кроме того, я видел, как многие разработчики слишком много (включая мою более молодую версию) переформатировали и стиль кода, и они в конечном итоге вносят дефекты. Здесь пропущена запятая / точка с запятой, объявления переменных перемещены в начало функций, for-циклы заменены на for-each's - все они могут содержать незначительные ошибки. Требуется обманчивое количество навыков, чтобы сделать эти изменения безопасно.
Johntron
4

Но как вы отслеживаете изменения кода при основных изменениях форматирования?

Форматирование изменений являются изменения кода; относитесь к ним так же, как к любым другим изменениям в вашем коде. Любой, кто работал над значимым проектом, вероятно, видел ошибки и другие проблемы, которые были созданы, когда кто-то решил «просто» переформатировать некоторый код.

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

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

Калеб
источник
1

Есть два жизнеспособных подхода, которые я видел для этого.

1. Переформатировать код на коммит-хук

Изначально сложно изменить код после того, как они его отправили, но если ваша процедура переформатирования (например, astyle ) не повредит коду, то это безопасная операция. Со временем вся команда поймет, что весь код в конечном итоге выглядит одинаково. Понятно, что комплексные юнит / автоматические тесты гарантируют, что ничего не сломалось.

2. Единовременное переформатирование всего кода

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

JBRWilkinson
источник
1
Не будет ли вариант 1, когда он включен, пульсации по большей части базы кода быстро приводят к тому же большому взрыву при каждом изменении файла?
Знак
@Sign: Именно моя точка зрения. Когда хук коммита меняется, ваша история может превратиться в нечто почти бесполезное. Форматирование, которое не меняет функциональность, не должно быть коммитом, оно должно быть перенесено в историю кода.
l0b0
1
Если IDE поддерживает его, то также есть 3) автоформат IDE при сохранении. Тогда просто используйте одинаковые настройки везде - это проще всего, если вы используете настройки по умолчанию с IDE.
Я сделал оба этих подхода. Первый подход очень навязчив, поскольку каждый раз, когда новый файл фиксируется впервые, будет происходить множество изменений. Второй подход лучше для команды, как быстрое срывание бинта.
Друска