Что мне делать, если я уже слишком долго ждал между коммитами?

100

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

Что лучше?

  1. Сделайте один очень большой коммит, перечислив все что я изменил
  2. Попробуйте разбить его на более мелкие коммиты, которые, скорее всего, не будут компилироваться, поскольку файлы имеют несколько исправлений, изменений, дополнительных имен методов и т. Д.
  3. Попробуйте выполнить частичное восстановление файлов только для соответствующих коммитов, затем верните новые изменения обратно.

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

Кстати: я использую SVN и Subclipse. Я создал новую ветку, прежде чем делать какие-либо из этих изменений.

Дополнительная информация : я задал отдельный вопрос, связанный с тем, как я попал в эту ситуацию: как подготовиться к переписыванию клея приложения

durron597
источник
2
Какую программу контроля версий вы используете? У многих есть модули, которые позволяют разбивать ваши правки на «фрагменты», то есть группы измененных строк, которые позволят вам группировать ваши правки так, как вам нравится, и распределять моды одного файла по нескольким наборам изменений. Например, у Mercurial есть расширение "полки". Конечно, вы все равно должны проверить, компилируется ли каждый пакет изменений, если это имеет значение для вашего процесса. Стоит ли это того, решать вам и вашему магазину.
Алекс
6
По крайней мере, отметьте это на ветке, чтобы не потерять свои изменения.
Рори Хантер
2
Вы можете продолжать задавать себе вопрос и ждать еще дольше, или на самом деле совершать и разбираться с любым беспорядком, который создает ... И тогда ... не делайте этого снова!
Хайлем
40
# 1, молись о прощении, а затем иди и больше не греши :)
Петерис
5
Более важный вопрос, который вы должны задать себе: «Как мне изменить свои вредные привычки, чтобы это не повторилось». Не должно быть никаких причин совершать это не реже одного раза в день, лучше чаще.
Док Браун

Ответы:

52

Чтобы ответить, вы должны спросить себя, как вы собираетесь использовать результаты этих коммитов в будущем. Наиболее распространенные причины:

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

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

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

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

Карл Билефельдт
источник
Отличный ответ! Хотя я не испытываю меньшего сожаления по поводу того, что не выполняю небольшие коммиты, я чувствую себя намного лучше в отношении того, что я должен сделать, чтобы вернуться к хорошему поведению настолько продуктивно, насколько это возможно.
durron597
1
Еще одна вещь, касающаяся 3 и 5, заключается в том, что любую работу, которую вы выполняете сейчас, чтобы позволить им произойти, вы можете подождать, пока она вам действительно понадобится, и затем выполнить ту же работу. Возможно, в будущем это будет несколько сложнее, потому что ваша память о том, что вы сделали, исчезла. Но опять же, вы, вероятно, никогда не будете нуждаться в этом.
Стив Джессоп
По моему опыту, трудно и хрупко полагаться на комментарии управления версиями, чтобы рассказать историю, почему код существует (т.е. причины 1 и 2). Если вы используете SVN с веткой, история коммитов теряется при слиянии (в любом случае вам будет лучше с такими более современными вещами, как git). Так что это ИМХО лучше всего подавать с комментариями.
Ханс-Петер Стёрр,
1
@hstoerr - если вы используете Subversion 1.5 или более позднюю версию, вы можете сохранить историю с опцией --reintegrate после слияния.
Дастин Кендалл
1
git add -p - ваш лучший друг здесь. Я влюбился в эту функцию. Таким образом, я могу фиксировать свои модификации кода в отдельных коммитах и ​​сохранять соответствующие изменения кода изолированными.
Spidey
39

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

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

FrustratedWithFormsDesigner
источник
Вариант третий возможен, но это будет чрезвычайно трудоемким. Я думаю, что я просто собираюсь сделать вариант 1
durron597
3
Каковы недостатки использования кода, который не будет компилироваться или встраиваться в функциональную ветвь (или подобное), которые настолько ужасны, что заставляют кого-то избегать делать «что бы они ни делали»? Я полагаю, что другие действительно могут избежать любых ужасных коммитов, и это единственная реальная причина, по которой я бы вообще избегал их (при условии, конечно, что коммиты не выпускаются ).
Кенни Эвитт
3
«Не проверять в коде , который не будет компилировать» относится только к общему кода базы / филиала. Я утверждаю, что в проекте с одним человеком или в ветке разработки с одним человеком более важно просто вносить свои изменения в VC, чтобы не потерять вещи.
Стивен С.
3
@StephenC, например, потому что он ломает такие инструменты, как git-bisect. Если код компилируется / запускается все время, и вам нужно найти регрессию, если он компилируется все время, вы можете просто выполнить бинарный поиск (не говоря уже о том, что если во фрагменте кода есть регрессия, у вас остается большое изменение для чтения вместо сужения это вниз).
Мацей Пехотка
@MaciejPiechotka - Ну, разумеется, если вам нужно использовать определенные инструменты в ваших частных ветках, и они требуют, чтобы код был компилируемым, тогда сделайте это. Но это не характерно для проекта / филиала с одним человеком.
Стивен С
19

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

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

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

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

На основании предоставленной вами информации я бы выбрал вариант 1. Может быть, вам следует настроить напоминания, предлагающие вам внести изменения?

Прототипирование и переписывание

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

При создании прототипа нового кода выполняйте коммит всякий раз, когда хотите сохранить изменения, почти наверняка в ветке, но, возможно, в отдельном проекте. Или, может быть, даже просто работать вне системы контроля версий. Вместо этого вы можете сосредоточиться на сборе доказательств о целесообразности различных гипотез или конструкций, которые вы рассматриваете. Я часто пишу небольшие прототипы, используя различные инструменты, например LINQPad вместо Visual Studio для кода C #.

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

Кенни Эвитт
источник
1
Хороший ответ; Кенни, у вас есть хорошая статья или другая база знаний, чтобы связать более конкретные детали о прототипировании? Моя версия прототипа - «Эскиз в блокноте или на доске»
durron597
@ durron597, я не могу думать ни о каких ссылках (даже искать) на моей голове. Я играл с достаточным количеством интерпретируемых (и динамически компилируемых) языков программирования, что даже не думал, что идея «прототипирования» может быть новой! И я переписал так много программ на C, C ++ и Java (снова и снова), что я не думал, что это тоже может быть необычным или, по крайней мере, новым для некоторых.
Кенни Эвитт
12

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

Поэтому я бы выбрал вариант 1. Если это невозможно, то вариант 2.

Вариант 3 требует больших усилий, и это просто не стоит.

BЈовић
источник
1
или пометить некомпилируемые версии как «НЕ СОБИРАЕТСЯ»
ratchet freak
2
@ratchetfreak: Полагаю, что «тег» в SVN не сильно поможет, поскольку теги не работают как «комментарии» к стволу.
Док Браун
@DocBrown Я хотел добавить его в сообщение коммита
трещотка урод
5
@ratchetfreak Я бы сделал это как "ЧАСТЬ X / N: проверка в ABC - НЕ СОБИРАЕТСЯ"
BЈовић
Вариант 3 не требует особых усилий. Другой ответ объясняет, как сделать это быстро и легко, используя git add --patchи git stash. Ситуация кажется сложной только из-за устаревших средств контроля и знаний.
Рон Макнейл
7

Попробуйте разбить его на более мелкие коммиты, которые, скорее всего, не будут компилироваться, поскольку файлы имеют несколько исправлений, изменений, дополнительных имен методов и т. Д.

Когда я оказался в подобной ситуации, я использовал следующую технику:

  1. Добавьте только код, который относится к определенной функции: git add --patch
  2. Копить все остальные изменения: git stash save --keep-index
  3. Запустите тесты / попробуйте скомпилировать
  4. Внесите изменения, если все в порядке, если не перейти к 1

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

Милош
источник
Мне это нравится, но, к сожалению, одна из многих вещей в моем списке задач (есть много, когда вы единственный технический специалист в компании) - это переключиться с SVN на git, и я просто еще не дошел до этого ,
durron597
1
Так как я не достаточно для использования --patch, я использую Undo на различных панелях редактора, чтобы перейти к более ранним рабочим состояниям и зафиксировать их. Затем я переделываю для следующего коммита. Из-за соблазна делать небольшие дополнения к коду, находясь в состоянии отмены, я всегда делаю резервную копию, прежде чем начать этот процесс!
Joeytwiddle
С помощью git вы также можете добавить в интерактивном режиме (добавить -i) перед коммитом и ветвь после, чтобы самостоятельно проверить ваши коммиты.
riezebosch
3

Как насчет варианта 4: сделать резервную копию текущего состояния репо во временном месте, вернуть репо в исходное состояние, составить список всех изменений, которые вы сделали (вы все еще можете посмотреть временную резервную копию), затем вручную переопределить (и скомпилировать и проверить!) их как отдельные коммиты.

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

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

Superbest
источник
Это всего лишь способ сделать вариант № 3. Вероятно, лучший способ, правда, но все же довольно много времени.
durron597
Было 149 строк добавления / удаления / отправки сообщений, когда я выполнял один большой коммит. Это как минимум полдня, чтобы сделать это.
durron597
@ durron597 Я не согласен, я думаю, что это отличается от # 3. Что касается 149 строк, сколько вы цените чистую историю коммитов? Стоит ли тратить на это полдня? В любом случае, не то, чтобы другие методы не требовали выяснения, какая строка должна быть в каком коммите, поэтому вам придется пройти через 149 строк в любом случае. Разница во времени будет небольшой.
Superbest
Хех. Я достаточно опытен, чтобы знать, как использовать управление версиями, но не настолько опытен, чтобы когда-либо это спасать мой зад :) Так что практические причины для действий все еще немного академичны, если вы понимаете, о чем я.
durron597
Вам не нужно делать резервную копию всего репо . Вы можете сделать «резервную копию» коммита, а затем откатить ГОЛОВУ с помощью git reset HEAD~. Ваш коммит будет по-прежнему в git reflogсиле, если вы решите, что он вам понадобится позже. Вы можете даже отключить ветку (а затем переключиться обратно на рабочую ветку) перед выполнением сброса, чтобы дать вашей «резервной» фиксации имя. Удалите ветку позже, если она вам не нужна. Изменить: Извините, не понял, ОП находится на SVN!
Joeytwiddle
3

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

Вы вероятно откатите "части" того, что вы сделали? Если нет, то обязательно перейдите к варианту 1.

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

Программист, входящий в проект позже, вряд ли захочет вернуться к версии, которая не компилируется. Так что, ИМХО, вариант 2 - безумие.

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

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

Не я
источник
1
Откат - не единственная причина использовать небольшие коммиты. Это даже не особенно веская причина. Основная причина заключается в том, чтобы видеть, когда и почему было внесено изменение, и облегчать устранение неполадок, когда вы сталкиваетесь с проблемой неизвестного происхождения. Другой программист, входящий в проект позже, почти наверняка будет по крайней мере время от времени сталкиваться с строками кода, которые заставляют его переходить в «WTF» и возвращаться к коммиту, где он был впервые написан или последний изменен. Если этот коммит - один гигантский коммит, изменяющий 500 вещей, невозможно получить какую-либо полезную информацию из истории.
Aaronaught
Кстати, именно поэтому команды, использующие Git, обычно ненавидят коммиты слияния и вместо этого запрашивают / требуют перебазирования; Объединение коммитов перерыв bisectи другие методы, обычно используемые для изоляции проблем, потому что так много изменений объединены в один огромный коммит.
Aaronaught
1
На личном уровне я согласен с тем, что вы не должны делать большие коммиты, если вы радикально не измените кодовую базу ... в этот момент вы все равно должны были его разветвить. Тем не менее, мы говорим об одном программисте, который работал по существу без связи и теперь пытается вернуться к правильной работе. В этом случае я считаю, что один большой коммит предпочтительнее.
NotMe
1
@Aaronaught Я бы добавил, что через 3 месяца вы сами можете стать «другим программистом».
Мацей Пехотка
1
Я должен также не согласиться с ветвлением как жизнеспособной стратегией для архитектурных изменений или других «разрушительных» изменений. Это просто приводит к кошмару конфликтов слияний и ошибок после слияния. В долгосрочной перспективе гораздо сложнее найти способ разбить основное изменение на более мелкие, обратно-совместимые изменения или, в худшем случае, использовать то, что Фаулер, Хамбл и остальные называют Ветвью. По абстракции (которая на самом деле совсем не ветвь). Обе эти стратегии предполагают небольшие и целенаправленные коммиты.
Aaronaught
2

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

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

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

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

gnasher729
источник
Логически это то же самое, что и ответ на основе Git выше ( git add --patchи git stash), и хороший пример сценария, с которым современные DVCS могут легко справиться, а старые системы - нет.
Рон Макнейл
1

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

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

Рой
источник
1
это, кажется, не добавляет ничего существенного по сравнению с тем, что уже было опубликовано в предыдущих 12 ответах
gnat
-1

Проблема не в длительных задержках между коммитами, а в том, что вы слишком долго держите код в некомпилируемом состоянии. Прежде всего, как вы определяете «длинный»? Для некоторых людей 5 минут для переходного состояния - это слишком много, но некоторые могут несколько дней полировать свой код, даже не пытаясь запустить компилятор.

На самом деле это не имеет значения - важно то, что вы потеряли контроль над своим кодом, ваш код стал неуправляемым. Это нормально, это просто означает, что у вас есть технологический долг, и пришло время подумать о рефакторинге. Так ты расстроен? Ваш код не компилируется, у вас даже нет модульных тестов? Как вы можете думать о рефакторинге в этом случае? Не волнуйтесь. Закончите свое «ковбойское кодирование» и начните его чистить. В идеале попробуйте написать несколько тестов. У тебя нет времени на это? Хорошо, начнем с небольших улучшений.

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

После этого вы увидите, что следующее изменение не займет у вас «слишком много времени» (что бы это ни значило).

AlexT
источник
2
Он не сказал, что долгое время держал код некомпилируемым. Код в репо не изменялся долгое время - старый, но все еще компилируемый. Код в его рабочей копии часто обновлялся, но не фиксировался. Ничто в этом вопросе не предполагает, что его код может потребовать рефакторинга - «ковбойское кодирование» здесь относится к его рабочему процессу SCM, а не к фактическому качеству кода
Идан Арье
@IdanArye Исходный вопрос ...Try to break it into smaller commits that likely won't compile...Если что-то мешает вам зафиксировать ваш код, то это уже хорошо, что кодом трудно управлять. «Фиксация» - это только один из способов сохранить вашу работу. Можно подумать о более крайнем случае - «если что-то мешает мне сохранить исходный файл». Так что же это может быть? Я думаю, это боязнь ваших собственных изменений. Почему это может быть? ... Я думаю, вы поняли
AlexT
2
Мне кажется, больше похоже на то, что мешало ему совершить, это просто лень.
Идан Арье
@IdanArye Вы правы по всем пунктам. Этот плюс не делает достаточно TDD, что является отдельной проблемой.
durron597
@AlexT рассмотрим сценарий, в котором вы исправляете две ошибки, и одна из них требует недавно разработанного метода. Если вы выполняли коммит правильно, вы исправляете одну ошибку, фиксируете, а затем исправляете другую ошибку. Если это не так, то при фиксации вы должны либо включить оба изменения в один и тот же коммит, либо зафиксировать первое исправление ошибки вместе с изменениями для второго, за исключением того, что у зафиксированной версии нет вызова нового метода и, следовательно, не компилируется
durron597