перебазирование git после большого рефакторинга

#git #git-rebase

#git #git-перебазирование

Вопрос:

У меня есть 2 ветки, master и featureA. В ветке featureA я написал кучу нового кода в CoolFile.m . Функция не завершена, поэтому этот код еще не готов к объединению в master. CoolFile был действительно плохо написан в прошлом, поэтому в ветке разработки я внес в него кучу изменений (в основном, изменив порядок методов, добавив комментарии и удалив пробелы).

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

Ответ №1:

Вы могли бы объединить изменения из ветки master в свою ветку featureA,

 A--B--F--G--H master
   
    -C--D--E featureA
  

Давайте предположим, что вы создали featureA из коммита B на master, и что C, D и E — это коммиты, сделанные на featureA, а F и G — это коммиты, которые изменили порядок методов и т.д. Что вы хотите сделать сейчас, так это объединить F и G в ветку featureA.

 $ git checkout featureA
$ git merge G (G is the sha1)
  

Или вы могли бы добавить коммиты F и G в featureA. Помните, что вы все равно будете получать конфликты и что это всего лишь альтернативы вашему варианту перебазирования.

В будущем я бы рекомендовал вам выполнять рефакторинг либо непосредственно в featureA, либо из другой ветки, отходящей от featureA:

 A--B--F--G--H master
   
    -C--D--E featureA
         
          -I--J--K refactorFeatureA
  

Тогда объединить в ветке рефакторинга в featureA проще простого, поскольку слияние было бы тривиальным.

Комментарии:

1. Я понимаю, о чем вы говорите, обычно я бы провел рефакторинг в своей ветке featureA, но у меня была другая ветка функций от master, которая использовала этот же файл. Функция A — это большая функция, и я, вероятно, создам еще несколько ветвей на master, прежде чем featureA будет завершена. Вот почему я провел свой рефакторинг в master.

Ответ №2:

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

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

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

Комментарии:

1. Если у вас есть куча таких маленьких коммитов, не будет ли у вас целой кучи неочевидных комментариев в вашей истории? Например, «переместить methodA, переместить methodB, переместить MethodC и т.д. …»

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