Слить ветку в папку другой ветки - PullRequest
1 голос
/ 03 июля 2019

У меня есть ветка A с папкой с именем foo.Другая ветка с именем B содержит только содержимое папки foo.Можно ли объединить ветвь B в папку foo ветки A?

Ветвь A содержит, например,

foo/
    hello_world.c
goo/
    AliceAndTom.c

Ветвь B содержит только содержимое папки foo/

./
    hello_world.c
    hello_world.h

Результат, который я хочу получить в ветви A после слияния ветви B:

foo/
    hello_world.c
    hello_world.h
goo/
    AliceAndTom.c

Редактировать : ветка B была создана с помощью команды git git filter-branch --subdirectory-filter dir/to/filter -- subdir_branch

1 Ответ

1 голос
/ 03 июля 2019

Вы не можете напрямую объединить это.

Существует некоторая путаница в комментариях о том, поможет ли здесь обнаружение переименования 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, но ни один патч не удаляет файл по одному пути и создает его по другому , поэтому обнаружение переименования не произойдет. Слияние создаст вторую копию файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...