Подтвердить что ты не робот

Можно ли "злоупотреблять" функциональностью переименования Mercurial отслеживать движение блоков кода?

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

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

Один из моих сотрудников обнаружил, что он может "злоупотреблять" переименованием, выполняя что-то вроде этого:

hg rename --after original_file new_file_1
hg rename --after original_file new_file_2
hg rename --after original_file new_file_3
hg add original_file

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

Есть ли что-то не так с этим "множественным переименованием"?

4b9b3361

Ответ 1

Вы должны убедиться, что знаете, что hg copy действительно означает, прежде чем делать это.

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

График может показать это лучше:

old --- edit old --- edit in old copied to new --- edit old --- merge
   \                /                             /
    copy old new --/------- edit new ------------/

Начнем с набора изменений, где у вас есть файл old. Затем вы редактируете old на одной ветке и копируете old в new в другую. В первом объединении редактирование на old копируется в new. Во втором слиянии нет специального лечения для new, так как new встречается у общего предка (набор изменений copy old new).

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

old --- copy old new

в качестве отправной точки, тогда все в порядке. Но если у кого-то есть ветки из набора изменений old и фактически отредактированы old в этой ветке, тогда они получат конфликты слияния, когда они попытаются объединиться с набором изменений copy old new.

Точнее, они получают конфликты слияния, если они отредактировали любую часть файла old, который не был скопирован в файл new. Конфликты слияния предупреждают вас о том, что в old было внесено изменение, которое необходимо скопировать в new. Однако, когда вы действительно делали

hg copy old new1
hg copy old new2
hg copy old new3

тогда вы получите бесполезные конфликты слияния в двух из трех новых файлов.

Если вы только что удалили файл old и добавили три новых файла, тогда вы все равно получите конфликт слияния: вам будет предложено

remove changed old which local deleted
use (c)hanged version or leave (d)eleted?

Если вы предпочитаете видеть это приглашение или видите, что запуск слияния зависит от вас, но теперь вы знаете последствия hg copy (или hg rename --after, это действительно то же самое).

Ответ 2

Легче использовать hg copy для этого:

hg copy original_file new_file_1
hg copy original_file new_file_2
hg copy original_file new_file_3

Теперь у всех 3 есть оригинальная история. Но, да, в любом случае это нормально и обычно делается.