Мне нужно объединить два репозитория Git в совершенно новый, третий репозиторий. Я нашел много описаний того , как сделать это с помощью поддерева слияния (например , ответ Якуба Narębski в на Как объединить два хранилища Git? ) И следуя эти инструкции , в основном работаешь, за исключением того, что , когда я совершить поддерево слияния всех файлов из старых репозиториев записываются как новые добавленные файлы. Когда я это делаю git log
, я вижу историю коммитов из старых репозиториев , но если я это сделаю, git log <file>
то для этого файла будет показан только один коммит - слияние поддеревьев. Судя по комментариям к ответу выше, я не одинок в этой проблеме, но я не нашел опубликованных решений для нее.
Есть ли способ объединить репозитории и оставить историю отдельных файлов без изменений?
источник
Ответы:
Оказывается, что ответ гораздо проще, если вы просто пытаетесь склеить два репозитория и сделать так, чтобы все выглядело так, а не управлять внешней зависимостью. Вам просто нужно добавить пульты к своим старым репозиториям, объединить их с новым мастером, переместить файлы и папки в подкаталог, зафиксировать перемещение и повторить для всех дополнительных репо. Подмодули, слияния поддеревьев и необычные ребазы предназначены для решения немного другой проблемы и не подходят для того, что я пытался сделать.
Вот пример скрипта Powershell для склеивания двух репозиториев:
Очевидно, что вместо этого вы можете объединить old_b со old_a (который становится новым объединенным репо), если вы предпочитаете это сделать - изменить скрипт так, чтобы он подходил.
Если вы также хотите перенести текущие ветви функций, используйте это:
Это единственная неочевидная часть процесса - это не слияние поддеревьев, а скорее аргумент к обычному рекурсивному слиянию, которое сообщает Git, что мы переименовали цель, и помогает Git правильно выстраивать все.
Я написал чуть более подробное объяснение здесь .
источник
git mv
не очень хорошо работает. когда вы позже используете agit log
для одного из перемещенных файлов, вы получаете только фиксацию при перемещении. Вся предыдущая история потеряна. это потому, чтоgit mv
на самом деле,git rm; git add
но в один шаг .git log --follow
, либо все инструменты GUI сделают это автоматически. Насколько я знаю, с объединением поддерева вы не можете получить историю отдельных файлов, поэтому этот метод лучше.1
(номер один) дляls
и «глаз» дляxargs
. Спасибо вам за этот совет!Вот способ, который не переписывает историю, поэтому все идентификаторы коммитов остаются действительными. Конечным результатом является то, что файлы второго репо окажутся в подкаталоге.
Добавьте второй репо как удаленный:
Убедитесь, что вы загрузили все коммиты secondrepo:
Создайте локальную ветку из ветви второго репо:
Переместите все его файлы в подкаталог:
Объедините вторую ветку с главной веткой первого репо:
Ваш репозиторий будет иметь более одного корневого коммита, но это не должно создавать проблем.
источник
git remote show secondrepo
)--allow-unrelated-histories
. Смотрите историю этого ответного поста.Прошло несколько лет, и есть хорошо обоснованные решения с положительным голосом, но я хочу поделиться своим, потому что это немного отличалось, потому что я хотел объединить 2 удаленных репозитория в новый, не удаляя историю из предыдущих репозиториев.
Создайте новый репозиторий в Github.
Загрузите вновь созданный репозиторий и добавьте старый удаленный репозиторий.
Получить все файлы из старого репозитория, чтобы создать новую ветку.
В основной ветке выполните слияние, чтобы объединить старое репо с вновь созданным.
Создайте новую папку для хранения всего нового созданного контента, который был добавлен из OldRepo, и переместите его файлы в эту новую папку.
Наконец, вы можете загрузить файлы из объединенных репозиториев и безопасно удалить OldRepo из GitHub.
Надеюсь, что это может быть полезно для всех, кто занимается слиянием удаленных репозиториев.
источник
git remote rm OldRepo
.пожалуйста, посмотрите на использование
связать две истории в начале своей жизни.
Если у вас есть пути, которые перекрываются, исправьте их
при использовании журнала убедитесь, что вы «находите копии труднее» с
Таким образом, вы найдете любые движения файлов в пути.
источник
Я превратил решение из @Flimm в
git alias
подобное (добавлено в мой~/.gitconfig
):источник
$GIT_PREFIX
?Эта функция клонирует удаленное репо в локальный каталог репо:
Как пользоваться:
Примечание. Этот сценарий может перезаписывать коммиты, но сохранит всех авторов и даты, это означает, что новые коммиты будут иметь другие хэши, и если вы попытаетесь отправить изменения на удаленный сервер, он сможет это сделать только с помощью клавиши Force, также он перезапишет коммиты на сервере. Поэтому, пожалуйста, сделайте резервные копии перед запуском.
Прибыль!
источник
git filter-branch --index-filter
до работы. Обычно я получаю сообщение об ошибке, что файл индекса .new не существует. Это звонит в какие-нибудь колокола?git-add-repo.sh
с функцией выше, в конце файла поставьте эту строкуgit-add-repo "$@"
. После этого вы можете использовать его из Zsh, какcd current/git/package
иbash path/to/git-add-repo.sh https://github.com/example/example dir/to/save
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
иногда терпит неудачу, поэтому вы должны добавитьif test
.Выполните шаги для встраивания одного репо в другое репо, имея одну историю Git, объединяя обе истории Git.
my/new/subdir
(3 случая) структурой каталогов, в которой вы хотите иметь дочернее хранилище.Если вы сейчас проверите журнал git в родительском репо, он должен объединить коммиты дочернего репо. Вы также можете увидеть тег, указывающий из источника фиксации.
Приведенная ниже статья помогла мне встроить одно хранилище в другое, создав одну историю Git, объединив обе истории Git.
http://ericlathrop.com/2014/01/combining-git-repositories/
Надеюсь это поможет. Удачного кодирования!
источник
git filter-branch --prune-empty --tree-filter ' if [ ! -e my/new/subdir ]; then mkdir -p my/new/subdir; git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files my/new/subdir; fi'
Допустим, вы хотите объединить хранилище
a
сb
(я предполагаю, что они расположены рядом друг с другом):В случае, если вы хотите поместить
a
в подкаталог, сделайте следующее перед командами выше:Для этого вам нужно
git-filter-repo
установить (filter-branch
не рекомендуется ).Пример объединения двух больших репозиториев и помещения одного из них в подкаталог: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731
Подробнее об этом здесь .
источник