Контроль версий программного рефакторинга - PullRequest
4 голосов
/ 29 мая 2010

Каков наилучший способ управления версиями крупномасштабного рефакторинга?

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

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

  1. Резервное копирование и возможность возврата к хорошей версии «на всякий случай».
  2. Взгляд на историю говорит мне, как продвигался проект и поток идей.

Я использую Mercurial на окнах, используя TortoiseHg, который позволяет выборки фрагментов для фиксации. Причина, по которой я упоминаю об этом, заключается в том, что я хотел бы получить совет о степени детализации коммита в рефакторинге. Должен ли я отделить рефакторинг от функциональности, добавленной всегда при фиксации?

Я посмотрел ответы Рефакторинг и контроль источников: как? , но он не отвечает на мой вопрос. Этот вопрос направлен на сотрудничество с командой. Эта статья посвящена созданию истории, которая будет понятна в будущем (при условии, что я не переписываю историю, как это допускают некоторые VCS).

Ответы [ 6 ]

9 голосов
/ 29 мая 2010

Я полагаю, что нет единого размера, который подходит всем ответам на ваш вопрос:)
Лично я предпочитаю сохранить более тонкую гранулярность в моих коммитах: в вашем случае я бы разделил действие на две фазы: каждая независимая:

  1. рефакторинг (и последующий коммит)
  2. новые функции (и коммит).

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

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

3 голосов
/ 29 мая 2010

Должен ли я отделить рефакторинг от функциональности, добавленной всегда при фиксации?

Я склонен часто регистрироваться;и каждая регистрация - это либо рефакторинг, либо новая функциональность.Это цикл:

  1. Рефакторинг существующего кода (без изменения его функциональности), чтобы подготовить его к принятию нового кода
  2. Добавление нового кода (который реализует дополнительную функциональность).
2 голосов
/ 29 мая 2010

Имея дело с распутыванием эффектов / ошибок / побочных эффектов ОЧЕНЬ сложного рефакторинга в сочетании с довольно обширными изменениями, я могу очень настоятельно рекомендовать всегда стараться разделить их настолько, насколько это возможно.

Если есть какие-либо проблемы, вы можете ОЧЕНЬ легко пересобрать код по тегам / меткам / версиям, относящимся к каждому этапу, и проверить, какой из двух внес проблему.

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

2 голосов
/ 29 мая 2010

Я бы рекомендовал отделить рефакторинг от добавления функциональности. Возможно, чередуя проверки. Это из моего опыта после обнаружения uncrustify и будет переформатировать исходные файлы при внесении изменений в код. Стало очень сложно вычислить реальное изменение от просто переформатирования. Теперь uncrustify получает собственные выделенные коммиты.

1 голос
/ 29 мая 2010
  • Сделай шаги ребенку . Сделайте наименьшее полезное изменение, протестируйте его, отправьте и повторите.

  • Один вид изменений за раз . Не рефакторинг и изменение поведения в в то же время.

  • Отправить часто . Небольшие изменения с четкими подробными описаниями неоценимы.

  • Убедитесь, что ваши автоматизированные тесты надежны и полезны . Если вы можете доверять своим тестам, вы можете легко и быстро выполнить вышеизложенное.

  • Убедитесь, что ваши тесты всегда проходят .

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

1 голос
/ 29 мая 2010

Каждый ответ до сих пор советовал вам отделить рефакторинг от добавления функциональности - и я добавил их +1. Вы должны сделать это, независимо от контроля источника. Мартин Фаулер написал целую книгу о том, что вы не можете выполнять рефакторинг одновременно с изменением функциональности. При любом изменении вы хотите знать, должен ли код и работать до изменения так же, как и после. И, как указывает @Amardeep, гораздо сложнее увидеть, какие функциональные изменения вы внесли, если они скрыты путем форматирования или рефакторинга изменений, и, следовательно, гораздо сложнее отследить ошибки, внесенные функциональными изменениями. Я не хочу этим отговаривать вас от рефакторинга или откладывать это. Делайте это, во что бы то ни стало, часто. Но сделайте это отдельно от функциональных изменений. Микрокоммиты - это путь.

...