Обновление - Фактически идеальный подход:
# Inside the older repo
$ cd old_repo
# Add the remote to newer repo with updated content
$ git remote add <remote name> <new_repo>
# Fetch the remote
$ git fetch <remote name>
# Track all branches of the remote so you have all of it's history in your older git (be aware of the remote's name in the command)
$ for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##<remote name>/} $b; done
# Delete the remote so you avoid messing up with the newer repo
$ git remote remove <remote name>
Теперь я настоятельно рекомендую вам использовать визуальный инструмент с этим репозиторием (например, Gitkraken), так как теперь там какой-то беспорядок. У вас будет две истории, не привязанные друг к другу, с, возможно, множеством повторяющихся коммитов.
Теперь выберите коммиты, которыми вы будете управлять. Давайте вызовем фиксацию с ha sh A
той, которая была в более старой истории, которая теперь будет родительской для фиксации B
новейшей истории. Теперь вы можете использовать приведенный ниже сценарий (или запустить команды вручную), чтобы присоединиться к деревьям и очистить оставшийся беспорядок (обрезать новую историю прямо в коммите B
, отбросив всех родителей, так как теперь у него есть новый родитель). (У вас должны быть установлены git -replace и git -filter-repo )
#!/bin/sh
# Argument "$1" is commit A, and argument "$2" is commit B
if [ -z "$1" ] || [ -z "$2" ]
then
echo "error";
exit 1;
fi
git replace --graft $1 $2
result="$?"
[ "$result" = "0" ] && git filter-repo --force
Более старые, неважные (они служат только для того, чтобы узнать, чего НЕ делать), ответ ниже.
Сначала я попробовал подход с git-rebase
, который не сработал по ряду причин, самая большая из них - это было немного излишним для чего-то вроде простой смены родителя совершить другой, даже если он не имеет отношения к истории. Затем я попытался git cherry-pick
повторно применить всю историю из точки E..G
в старый репозиторий, тоже не сработало по ряду причин, но главная из них заключалась в том, что другие ветки рекурсивно не копировались.
Пробный подход
$ git replace --graft <commit> <new parent to this commit>
Теперь поместите HEAD
на кончик новой истории (самая последняя фиксация в основной строке, которую вы хотите сохранить), затем: $ git filter-branch <new parent to this commit>..HEAD
Вы можете потерять ветви, которые еще не слились с веткой, в которой находится HEAD, и я пока не мог найти способ обойти это.