2017-01-23 15 views
10

Я постараюсь сохранить эту краткую информацию.Как я могу объединить изменения из ветви, содержащей подмножество каталогов из другого?

У нас есть git-хранилище, которое действует как зеркало SVN (управляется BitBucket). Этот репо содержит каждый проект в компании с начала времени и наличие каждого клона разработчика не является разумным запросом (25 + 33GiB полный клон и 15 + GiB неглубокий). Но даже тогда нам не нужен полный клон всего репозитория, всего лишь подмножество каталогов внутри.

Используя git-поддеревье, мне удалось разделить все интересующие нас каталоги и подумали, что мы можем добавить эти каталоги в наши локальные репозитории, используя git-subtree add. Этот процесс прозрачен для репозитория svn. Это хорошо работает, и размер намного более управляемый (9 + 6GiB полный клон и 8GiB мелкий). Проблема в том, что я не знаю, как мы могли бы вносить изменения в эти «частичные клоны» и объединить их обратно в основную ветвь.

Я думал, что мы сможем использовать обычные запросы на тягу, чтобы получить их, но так как деревья ветвей разные, это не ведет себя так, как хотелось бы (отсутствующие каталоги рассматриваются как абсорбция). Я просто хочу объединить изменения клонированных каталогов и оставить остальных нетронутыми.

Я не думаю, что использование разреженной выписки поможет здесь, так как нам все равно придется клонировать полное репо, чтобы заставить его работать, и именно этого я и стараюсь избежать.

Есть ли какая-то комбинация команд, которые я могу использовать, чтобы все это работало?


Вот эта (модифицированная) сценарии, которые я использовал, чтобы расколоть из каталогов и проверки каталогов интересов:

split_projects.sh
я использовал ГИТ-поддерево, чтобы разделить и воссоединиться каталогами и использовал мерзавец -replace, чтобы улучшить скорость повторного добавления (только для обработки новых коммитов). Обратите внимание, что rejoin - , а не, преданный основному репо (я не хочу пытаться совершить это, особенно с зеркалом svn).

initial_setup.sh
Это сценарий для подготовки местного репо. Для использования пользователями Windows, многие из которых не очень разбираются в инструментах git или командной строки.

checkout_projects.sh
Фактический скрипт выписки.

Есть еще один, который извлекает обновления из подкаталогов split, но я не включаю его здесь.

+0

Что случилось с параметрами поддерева при слиянии? – jthill

+0

Я понимаю, что использование этой стратегии объединяет ветви, где один полностью содержится внутри другого. то есть ветвь A уже является поддеревом ветви B. В моей ситуации ветвь A содержит подмножество каталогов ветви B и не будет работать. –

+0

Возможно, вам придется обратиться к списку рассылки ([email protected]), чтобы получить поддержку. Мой интуитивный инстинкт, однако, заключается в том, что может не быть решения, поскольку вы пытаетесь каким-то образом применить изменения, сделанные в поддеревьях к корневому репо, и я не могу представить, как это было бы возможно без информации о коммитах в корень репо. Если ваши разработчики используют Windows, недавно открытый проект GVFS на самом деле может быть тем, что вы ищете. – Pockets

ответ

2

в вашем случае я боюсь, что вы должны использовать вишнево-кирку, чтобы переместить изменения в оригинальный репозиторий

4

Если вы не хотите, чтобы некоторые изменения слиты обратно, делать слияние --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 

после слияния, и все готово.

+0

Я думаю, что смогу создать скрипт для этого. Вероятно, интегрирован с запросами на тягу к специальной ветке, которую я создам. –

+0

Это звучит работоспособно. – jthill

+0

Я буду двигаться в этом направлении, когда у меня будет больше времени для работы над этим (сейчас это на backburner). Это будет самое близкое, с чем я могу справиться. –

2

Лучшее решение у меня есть для вас, чтобы выполнить следующую команду в разреженной проверки неглубокого клона корневого хранилища:

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 
2

Если я понимаю ваши скрипты правильно:

внутри bigrepo, $project имеет свою историю на ветвиsubdirs/$project, и его содержание в корневой директории репозитория
например: если вы запустите git checkout subdirs/$project в bigrepo, содержание проекта лежит в / (не в каком-то дополнительном подкаталоге).

Если это так:

Я думаю, что последовательность git subdir push -P $project должна работать:

  • один из любого «местного репо» к разделенным репо
  • один из расщепленного репо к bigrepo
+0

Хотя это будет толкать к разветвленным ветвям, я в конечном итоге хочу вернуть их к мастер-ветке. Таким образом, изменения от пользователей git возвращаются к репозиторию svn. –

+0

@JeffMercado: из документов ('git help поддерево) вы можете нажать любую ветку, которая вам нравится. В противном случае вы можете построить свое дерево и совершить вручную, как это было предложено @jth. – LeGEC