Как совершить текущий рефакторинг?

23

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

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

Что вы думаете? Есть ли решение, которое я пропускаю?
Могу ли я позже сказать, что git агрегирует коммиты или что-то еще? Я мог бы жить с некомпилируемым коммитом, пока они остаются в cleanupветке.

редактировать

К вопросу о толкании / фиксации: я знаю, что это огромная разница, но позже, когда я сливаю свои вещи, будут сломанные ревизии master. Так что, если вы просматриваете историю (или git bisect...), тогда «локальные» ревизии будут доступны всему миру. Так что только локальная фиксация, а не подталкивание - не лучшее решение, потому что это вызовет у вас проблемы позже (когда тема закрыта и забыта на некоторое время).

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

битовая
источник
1
Вы можете собрать несколько локальных коммитов в одном глобальном коммите.
@ Thorbjørn - это рекомендация Джима ниже, или другой механизм в Git?
Брайан
Я верю в это - я не могу вспомнить точную команду.
5
Вы не рефакторинг, вы делаете что-то большее. После каждого рефакторинга в кодовой базе ваш код должен компилироваться и иметь точно такое же наблюдаемое поведение. Возможно, вы захотите изменить название вопроса, чтобы отразить это, так как моей немедленной реакцией было «Зафиксируйте то, что у вас есть, все должно работать».
Дэвид Торнли
1
@bitmask Как насчет переписать?
Дэйв Хиллиер

Ответы:

21

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

git checkout master
git merge --squash cleanup
git commit -m "Merge cleanup branch"

Команда git rebase -iтакже может вводить коммиты, но требует больше работы.

Джим Хуан
источник
14

Переписать это не рефакторинг

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

Мартин Фаулер определяет рефакторинг как :

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

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

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

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

Git действительно может помочь этому методу. Вы можете сохранить свою местную (сломанную) ветку. По мере того, как вы фиксируете (и выдвигаете) подцели, вы можете rebaseпереходить к своей основной цели поверх коммитов, которые вы только что сделали, до тех пор, пока они не прекратятся.

Дэйв Хиллиер
источник
5

Проверьте страницу руководства для git rebase, особенно git rebase -iвариант. Это позволяет вам переупорядочивать, удалять или объединять любое количество коммитов в вашей истории, что звучит как то, что вы ищете. Я использую его все время именно в той ситуации, которую вы описываете: создание множества небольших коммитов, которые не подходят для общественного потребления, а затем объединение их в один коммит «рефакторинг» перед отправкой в ​​общий репозиторий.


источник
3

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

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

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

редактировать

В этом случае вы можете использовать git cherry-pickили поиграть сgit rebase

Cristian
источник
Важное замечание, но я учел это. Пожалуйста, смотрите мое редактирование. Спасибо.
битовая
Смотрите мое редактирование выше.
Кристиан
Я бы -1, если бы мог; коммиты станут доступны! Локальные коммиты незавершенного производства хороши, но никогда их не подталкивают; это усложняет понимание кода, прерывает git bisect и усложняет историю. Перебазируйте или сквош вместо этого.
RJFalconer