Вы не можете напрямую объединить это.
Существует некоторая путаница в комментариях о том, поможет ли здесь обнаружение переименования git. Исходя из того, как вы говорите, ветвь была создана (с filter-branch
), скорее всего, нет. Это потому, что новая ветка, вероятно, не имеет общего предка со старой веткой. [1]
Итак, сначала вам нужно решить проблему с получением git для распознавания соответствующих файлов из веток; и затем вам нужно решить проблему, заключающуюся в том, что он не будет знать самого последнего общего предка для двух текущих состояний этого файла, поэтому слияние не будет проходить гладко. (Каждый файл, который существует в обеих ветвях, будет конфликтовать, скорее всего, со всем файлом, а не с реально объединением чего-либо.)
Это одна из проблем, которая может возникнуть из-за наличия «разного контента в разных ветках»; это не то, как должен работать git, и он может сделать интеграцию изменений между ветками довольно утомительной.
Насколько это утомительно, зависит от того, насколько сильно файлы изменились в каждой ветви с момента запуска filter-branch
. Самая общая процедура, о которой я могу подумать:
(1) написать скрипт, который перемещает файлы обратно в их подкаталог
(2) запустите filter-branch
(с указанным выше сценарием в качестве фильтра дерева) на более новой ветви, создав еще одну ветвь со структурой, более близкой к исходной
(3) идентифицирует последний коммит в новой ветке, который соответствует коммиту в оригинальной ветке
(4) используйте git replace
для замены указанного выше коммита вместо соответствующего коммита из исходной ветви.
(5) Теперь вы сможете объединить новую ветку с первоначальной веткой. Затем вы можете отменить git replace
и, возможно, избавиться от новой ветви.
Есть подробности, чтобы понять о каждом из этих шагов; не простая процедура, поэтому обратитесь к документации по задействованным командам, если хотите ее выполнить.
[1] - Более конкретно, чтобы применить обнаружение переименования, git должен искать исправление, которое одновременно удаляет файл и создает другой файл (по другому пути) с достаточно похожим содержимым.
Если бы вы разветвились от master
, а затем в ветке сделали коммит, в котором вы переместили файлы, вы бы теперь смотрели что-то вроде
x -- x -- O -- A <--(master)
\
x -- x -- B <--(bramch)
При слиянии branch
с master
, git будет искать патч между O
и B
, который соответствует критериям обнаружения переименования (если перемещаемый файл не слишком сильно изменился).
Но filter-branch
, вероятно, создал совершенно отдельную историю
x -- x -- x -- A <--(master)
x -- x -- B <--(branch)
По умолчанию слияние завершится неудачно (без общей истории), и если вы сделаете это без сбоев (скажем, разрешить несвязанные истории), то оно будет действовать так, как если бы существовала база слияния с пустым TREE
(т.е. нет файлы). Патч от этого к A
создает foo/file
, а патч от этого к B
создает file
, но ни один патч не удаляет файл по одному пути и создает его по другому , поэтому обнаружение переименования не произойдет. Слияние создаст вторую копию файла.