Восстановление истории в hg, когда движение не выполнено должным образом

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

Я пробовал hg log --follow, и это не помогает, поскольку hg не знает о переименовании. Есть ли способ вручную связать файлы со старыми удаленными версиями после факта или существует ли какое-то средство, например способ git, который может вызывать перемещения и переименовывать на основе hueristics? Было бы неплохо, если бы был какой-то способ явно сказать: "этот файл является продолжением этого старого удалённого файла". Хотя это все равно займет некоторое время, чтобы исправить все правильно.

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

Ответ 1

Вам нужно правильно переделать ход, явно указав Mercurial, какие файлы были перемещены, а затем объединить сломанные изменения. Таким образом вы восстановите путь истории к исходным файлам.

Шаги, предполагая, что <x> является пересмотром перемещения, а <y> - текущая версия главы.

  • Обновить до изменения перед перемещением: hg update <x-1>
  • Верните ход, но теперь правильно используя hg rename или hg rename --after
  • Фиксировать
  • Объединить с исходной версией перемещения (hg merge <x>), это не должно иметь конфликтов, но если отбросить все изменения.
  • Фиксировать
  • Объединить с оставшимися наборами изменений после перемещения (если есть) (hg merge <y>)
  • Фиксировать

Вот основной процесс, показанный в командной строке:

$ mkdir move-merge-test
$ cd move-merge-test
$ hg init
$ echo "x" > a
$ hg add a
$ hg commit -m "initial revision"

Неправильно перемещаться:

$ mv a b
$ hg remove a
$ hg add b
$ hg status --copies
A b
R a
$ hg commit -m "incorrect move"
$ hg log --follow b
changeset:   1:b22f3e94133b
tag:         tip
user:        Laurens Holst <...>
date:        Wed Oct 19 14:41:37 2011 +0200
summary:     incorrect move

Исправить ход:

$ hg update 0
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg rename a b
$ hg status --copies
A b
  a
R a
$ hg commit -m "correct move"
created new head
$ hg log --follow b
changeset:   2:5deabbcb5480
tag:         tip
parent:      0:b82f89f0c7d9
user:        Laurens Holst <...>
date:        Wed Oct 19 14:46:35 2011 +0200
summary:     correct move

changeset:   0:b82f89f0c7d9
user:        Laurens Holst <...>
date:        Wed Oct 19 14:36:35 2011 +0200
summary:     initial revision

Объедините его со сломанным движением:

$ hg merge 1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m "merge with broken move"
$ hg log --follow b
changeset:   3:ce65fc7b35e4
tag:         tip
parent:      2:5deabbcb5480
parent:      1:b22f3e94133b
user:        Laurens Holst <...>
date:        Wed Oct 19 14:47:13 2011 +0200
summary:     merge broken branch

changeset:   2:5deabbcb5480
parent:      0:b82f89f0c7d9
user:        Laurens Holst <...>
date:        Wed Oct 19 14:46:35 2011 +0200
summary:     correct move

changeset:   1:b22f3e94133b
user:        Laurens Holst <...>
date:        Wed Oct 19 14:41:37 2011 +0200
summary:     incorrect move

changeset:   0:b82f89f0c7d9
user:        Laurens Holst <...>
date:        Wed Oct 19 14:36:35 2011 +0200
summary:     initial revision

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

Ответ 2

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

Ответ 3

Есть опция --after для hg rename, которая позволяет вам указать Mercurial о переименовании после факта, но это необходимо сделать, прежде чем вы переименуете.

Вы можете попробовать сделать hg convert в репозитории и указать параметр --filemap, который позволит вам переименовывать файлы и каталоги.

https://www.mercurial-scm.org/wiki/ConvertExtension#A--filemap