Объединить изменения с одного репо на другое с помощью разных древовидных структур

У меня есть два репозитория Git, foo/master и bar/master:

В foo:

code_root
->dirA
  ->dirB
    -> *some files*

В строке:

code_root
  -> *same files as above*

Теперь кто-то внес изменения в *some files*... как я могу объединить эти изменения в *same files as above*?

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

Ответ 1

Вы можете разделить изменения на уровень поддерева, а затем объединить с другой ветвью:

# from your foo project
git subtree split --prefix=dirA/dirB/ --branch=temp-branch [--onto=<onto-sub-note1>] [<commit-sub-note2>]

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

фиксация подзаголовка 2. Затем вы хотите указать идентификатор фиксации, который использовался при первом копировании подпроекта, чтобы вы только получали изменения с тех пор слиться с копией бара, который у вас уже есть (это будет поддерживать историю того, что вы пропустили). Используйте такой синтаксис, чтобы включить сам код фиксации до последнего: 0abc210^..

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

После запуска команды split вы будете в ветки foo, в котором есть только те файлы. Оттуда вы можете выполнить нормальное слияние с проектом вашего бара или начать новый проект и объединить панель в это (поскольку он, вероятно, не имеет правильной истории). Вы можете захотеть переустановить точку расхождения или что-то еще, прежде чем пытаться сделать это слияние.

Edit: Также здесь ссылка для git команд поддерева

Ответ 2

Итак, вы говорите, что файлы по существу одинаковы как в foo, так и в баре, только те, что в foo новее, чем в баре:

Если да, то вы можете просто взять diff:

diff -b /path_to/foo/dirA/dirB/ /path_to/bar/ > diff.patch

а затем примените патч к строке:

cd bar

patch -p1 < diff.patch

Обновление: в соответствии с обновленным OPs, он ищет, чтобы сохранить историю фиксации, выше не будет работать в этом случае.

Ответ 3

Просмотрите git книгу и git magic. В зависимости от точных изменений, возможно, раунд перезаписи истории (git filter-branch и друзей или приложение грубой силы git rebase --interactive, выпрямление каждой фиксации), может восстановить здравомыслие к искаженному клону, а затем разрешить чистое слияние.

Другой альтернативой является экспорт каждого фиксации в виде патча (по существу, запуск git format-patch), восстановление данных фиксации и обратное проектирование патчей для применения. Вы могли бы даже использовать возможность переписать более чистую/более простую историю при этом.

Очевидно, что жизнеспособность зависит от степени расхождения и количества "ошибочно примененных" коммитов. [/p >