Слияние репозиториев Git

У меня есть два репозитория, которые я хотел бы объединить. Назовем их старым и новым стилем. Моя команда перестала использовать старый стиль 31 декабря 2016 года и начала использовать новый стиль 1 января 2017 года. Стиль каталога / проекта был скопирован из старого стиля и перемещен в новый стиль, за исключением истории. Я хотел бы объединить эти две истории вместе, чтобы увидеть, что изменилось в проекте.

Как бы я это сделал? Многие блоги предлагают взять старый стиль и сделать его дочерним каталогом нового стиля, а затем объединить их несвязанные истории. Но я считаю, что мои истории связаны. При этом могло бы показаться, что кодовые базы не похожи.

old-style: c1--c2--c3--c4--c5 <- master
January 1 2017  
new-style: c1--c2--c3--c4--c5--c6-- <- master

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

old-style: c1--c2--c3--c4--c5 <- master
             January 1 2017  \
                   new-style: c1'--c2'--c3'--c4'--c5'--c6'--c7 <- master
message at c7 indicating that old-style was added to new-style

Какой будет идеальный выход

c1--c2--c3--c4--c5--c1'--c2'--c3'--c4'--c5'--c6'--c7-- <- master
# merge
Источник
Codelisting
за 1 против
Лучший ответ

Я нашел решение, которое мне помогло. Все это нужно делать в GitBash, а не в Powershell.

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

В вашем клонировании нового стиля

git rev-list --max-parents=0 HEAD

Выход

2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

В вашем старом клонированном пробеге

git rev-parse HEAD

Выход

de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3

Клонировать репозиторий в новом стиле

git clone https://GitWebsite.repos/new-style.git
cd new-style

Добавить старый репозиторий как удаленный

git remote add history https://GitWebsite.repos/old-style.git
git fetch history

Теперь, чтобы преобразовать ветку, я собираюсь использовать git-filter-branch. Я понимаю, что это работает аналогично тому, как работает TFVC. Вы делаете снимок фиксации и двигаетесь вперед, не работая с различиями между коммитами. Git не будет пытаться решить проблему между двумя коммитами. Это напоминает мне фильм Уоллеса и Громита «Не те брюки» во время сцены погони за поездом, которую Громмит размещает перед поездом, когда он движется вперед.

git filter-branch --parent-filter 'test $GIT_COMMIT = 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 && echo "-p de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3" || cat' HEAD

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

git push -f

Теперь вы должны увидеть код в единой линейной истории.

Большое спасибо за этот ответ https://stackoverflow.com/a/44078243/2375884

за 1 против

График идеальной ситуации описывает перебазирование, которое вы можете сделать. Если у вас есть эти два репозитория как ветки, вы можете запуститьgit rebase --root --onto old-style new-style , который создаст линейную историю.

Вы также можете использовать--rebase-merges еслиnew-style - это основная ветвь разработки, которая использует типичный рабочий процесс слияния для сохранения коммитов слияния, а не их исключения. Для этого требуется достаточно свежая версия Git.

Если вы действительно хотите использовать слияние, вам нужно слить с--allow-unrelated-histories , поскольку ветки при совместном использовании кода не имеют фактического общего коммита.

Codelisting
Популярные категории
На заметку программисту