Как я могу объединить изменения из ветки, содержащей подмножество каталогов из другого?
Я попытаюсь сохранить эту краткую информацию.
У нас есть репозиторий git, который действует как зеркало SVN (управляется BitBucket). Этот репо содержит все проекты в компании с самого начала и каждый клон разработчика не является разумным запросом (25 + 33GiB полный клон и 15 + GiB неглубокий). Но даже тогда нам не нужен полный клон весь репозиторий, всего лишь подмножество каталогов внутри.
Используя git -subtree, мне удалось разделить все интересующие нас каталоги и подумали, что мы можем добавить эти каталоги в наши локальные репозитории, используя git -subtree add. Этот процесс прозрачен для репозитория svn. Это хорошо работает, и размер намного более управляемый (9 + 6GiB полный клон и 8GiB мелкий). Проблема в том, что я не знаю, как мы могли бы внести изменения в эти "частичные клоны" и объединить их обратно в главную ветвь.
Я думал, что мы сможем использовать обычные запросы на получение, чтобы их получить, но так как деревья ветвей разные, они не ведут себя так, как хотелось бы (недостающие каталоги рассматриваются как удаление). Я просто хочу объединить изменения клонированных каталогов и оставить остальных нетронутыми.
Я не думаю, что использование разреженной проверки поможет здесь, так как нам все равно придется клонировать полное репо, чтобы заставить его работать, чего именно я пытаюсь избежать.
Есть ли какая-то комбинация команд, которые я могу использовать, чтобы все это работало?
Здесь (измененные) сценарии, которые я использовал для разделения каталогов и проверки интересующих каталогов:
split_projects.sh
Я использовал git -subtree для разделения и воссоединения каталогов и использования git -replace для улучшения скорости повторного добавления (только для обработки новых коммитов). Обратите внимание, что rejoin не привязан к основному репо (я не хочу пытаться зафиксировать это, особенно с зеркалом svn).
initial_setup.sh
Это script для подготовки локального репо. Для использования пользователями Windows, многие из которых не имеют большого опыта работы с инструментами git или командной строки.
checkout_projects.sh
Фактическая проверка script.
Там другой, который извлекает обновления из разделенных подкаталогов, но я не включаю его здесь.
Ответы
Ответ 1
Если вы не хотите, чтобы некоторые изменения были объединены назад, сделайте слияние --no-commit
и отмените эти изменения в результате слияния перед фиксацией. Для нежелательных удалений просто git checkout
желаемая версия. Для нежелательных изменений ханки git checkout --patch
.
Другой вариант, который может оказаться проще, если он просто просто складывается в поддеревьях из верхнего уровня, отсутствующих в объединенной ветки, заключается в том, чтобы выполнить слияние и впоследствии изменить его, (git ls-tree @; git ls-tree @^1|grep ^04)|sort -usk4 | git mktree
будет генерировать правильное дерево достаточно легко, поэтому
fixup=`(git ls-tree @; git ls-tree @^1|grep ^04)|sort -usk4|git mktree`
commit=`git show -s --pretty=%B @|git commit-tree -p @^1 -p @^2 $fixup`
git update-ref -m 'fold in missing subdirectories' @ $commit
после слияния, и все готово.
Ответ 2
в вашем случае, я боюсь, вам придется использовать вишневые подборки для перемещения изменений в исходный репозиторий
Ответ 3
Лучшее решение, которое у меня есть, - это выполнить следующие действия в разреженной проверке мелкого клонирования корневого репозитория:
git checkout -b branch-to-PR-in
git fetch remote-with-subtree-as-root
git merge -s recursive -X theirs -X subtree=path/in/root/to/subtree/ remote-with-subtree-as-root/master --allow-unrelated-histories -X theirs
Ответ 4
Если я правильно понимаю ваши сценарии:
внутри bigrepo
, a $project
имеет свою историю на ветке subdirs/$project
, а ее содержимое в корневой директории репо
например: если вы запустите git checkout subdirs/$project
в bigrepo
, содержимое проекта находится в /
(не в каком-то дополнительном подкаталоге).
Если это так:
Я думаю, что последовательность git subdir push -P $project
должна работать:
- один из любого "локального репо" в разделенное репо
- один из разделенного репо на
bigrepo