Разделение прогресса кодирования на значимые коммиты без лишних затрат

23

Работая над исправлением или функцией, я иногда сталкиваюсь с другими крошечными проблемами, которые можно исправить на лету. Когда я выполняю их немедленно, а затем фиксирую готовую функцию / исправление, фиксация включает в себя несколько вещей. Например "add feature X and code clean up"или "fix bug X and improved logging". Было бы лучше разделить это на два коммита. Если два изменения произошли в одном и том же файле, я не могу просто добавить один файл, зафиксировать, добавить другой, а затем зафиксировать снова. Итак, я вижу следующие три варианта:

  1. Умышленно игнорируйте несвязанные вещи, работая над чем-то.

  2. Скопируйте файл с двумя изменениями, отмените его, включите одно изменение, подтвердите, включите другое изменение, подтвердите снова.

  3. Не меняйте мелкие несвязанные вещи, но добавляйте их в список задач и делайте это позже.

Мне не очень нравятся все три варианта из-за следующих причин:

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

  2. Это увеличивает ручную работу и подвержено ошибкам.

  3. Это хорошо для не очень крошечных задач, но добавление крошечного элемента в список задач и его повторное посещение часто занимает гораздо больше времени, чем просто немедленное исправление.

Как вы справляетесь с такими ситуациями?

Тобиас Герман
источник
7
Разве git не позволяет вам проверять отдельные строки, а не целые файлы?
Килиан Фот
Я git add -pмного использую, что позволяет в интерактивном режиме выбирать части файлов, которые я хочу зафиксировать. Если очистить достаточно отдельно, это легко сделать. Если разделение является более сложным, я фиксирую состояние во временной ветви, а затем вручную добавляю изменения в мою фактическую ветку, пока во временной ветви не будет различий. Это требует гораздо больше работы, но позволяет мне проверить, что каждый коммит работает сам по себе.
Амон
1
@gnat: явно не дурак. ОП не спрашивает о правильном размере коммита - он хочет делать небольшие коммиты. Он просто ищет более эффективный способ сделать это.
Док Браун
2
@gnat: верхний ответ ничего не говорит (!) о том, как обрабатывать различные изменения в одном файле и как разбивать их на отдельные коммиты.
Док Браун

Ответы:

11

Я думаю, что вы должны быть очень прагматичными при программировании. Даже если возможно сформулировать идеальную схему, рабочий процесс или реализацию, иногда вам просто нужно выполнить работу. Вот что я делаю:

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

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

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

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

Axl
источник
7

В моем редакторе есть плагин, который делает постановку отдельных частей файла чрезвычайно простой. Я полагаю, что другие редакторы программистов могут иметь подобные плагины, хотя вы всегда можете сделать это вручную git add --patch | -p. Затем я использую git stash, чтобы сохранить другие изменения, чтобы протестировать мой небольшой коммит изолированно. Затем, после того как я сделаю коммит, я просто делаю git stash popи продолжаю с того места, где остановился. Это именно то, для чего были разработаны эти функции.

Карл Билефельдт
источник
2

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

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

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

gbjbaanb
источник
1
ФП не предлагал объединить два изменения в один коммит, скорее наоборот.
Док Браун
1
@DocBrown он предлагает смешать 2 изменения в одну ветку, хотя это может быть грязно, чтобы потом распаковать, хотя, очевидно, не так грязно, как 2 изменения в одном коммите.
gbjbaanb
Хорошо, я понимаю, что ты имеешь в виду в последнем абзаце.
Док Браун
2

Вариант, который я использую довольно часто, - это добавлять TODOкомментарии, а затем делать много частых «частичных» фиксаций, используя git add --patchдля выбора соответствующих частей файла. Затем используйте git rebase --interactiveдля изменения порядка и объединения частичных фиксаций в финальную функцию и фиксации фиксаций, прежде чем их нажимать.

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

В git rebaseэтом контексте нет ничего плохого, поскольку вы переписываете только локальные коммиты.

Том
источник
1

Другим вариантом может быть «git stash» ваши текущие изменения. Рабочий процесс будет выглядеть так:

  1. Начните вносить изменения, связанные с функцией A
  2. Откройте для себя ошибку B и решите исправить ее немедленно
  3. Выполните из командной строки в репо git stash (после чего ваш код вернется в состояние, в котором он находился до того, как вы начали работать над функцией A )
  4. На данный момент ваши незафиксированные изменения для функции A хранятся в «тайнике»
  5. Внесите изменения в код, необходимые для исправления ошибки B, и внесите коммит обратно в репозиторий.
  6. Из командной строки запустите git stash pop
  7. Ваши незафиксированные изменения для функции A теперь извлекаются из тайника и восстанавливаются в вашем текущем коде вместе с (уже зафиксированным) исправлением ошибки B
Zach
источник
Не могли бы вы подробнее рассказать о том, как будет работать этот рабочий процесс? Каково состояние хранилища в каждой точке? Не могли бы вы рассказать кому-нибудь о том, как использовать git stash?
0

Отдельно подготовьте (и зафиксируйте) изменения, связанные с исправлением ошибки. В Git Extensions это чрезвычайно легко сделать. Из командной строки, я думаю, вам нужно сделать git add -p.

Эндрю Колсон
источник