"Layering" репозиторий git

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

У меня есть хранилище, которое содержит всю структуру веб-сайта, а корень веб-узла находится в корне хранилища. Все было хорошо, пока это не было хранилище для одного сайта. Тем не менее, одно и то же хранилище теперь используется для нескольких сайтов - в основном, для одного и того же сайта, на разных языках, с незначительными изменениями шаблонов, с другой графикой и т. Д. Все эти вещи имеют естественную версию.

Существует ветка master, которая содержит исходный исходный код сайта, и я бы хотел, чтобы master (или какая-то другая ветвь) содержала код, универсальный для всех сайтов, так как в конечном итоге будут внесены изменения, которые слишком узкие. Конкретно включить в универсальную часть репо.

Далее, есть ветка для каждого сайта, который использует этот исходный код. Все эти ветви (скажем, site1, site2 и site3) создаются из главной ветви, и каждый сайт клонирует правильную ветку.

Ну, это казалось хорошей идеей, пока я не начал вносить изменения везде.

Если я внес изменения в ветку site1, и мне нужно было скопировать это изменение в ветку site2, я бы выбрал коммит из одной ветви в другую. Слияние не может быть и речи, так как есть другие изменения в ветке site1, которые не относятся к ветке site2. Есть ли какое-то другое, более изящное решение для такой ситуации или сбор вишни именно для этой цели?

Теперь настоящая "проблема" для меня - когда я меняю мастер, а затем я хочу скопировать все эти изменения во все ветви. Естественно, учитывая тот факт, что все ветви являются потомками master, и что я хочу, чтобы эти изменения были во всех ветвях сайта *, я переключаюсь на каждую ветку и объединяю master.

Это создает довольно неприятную историю для всех ветвей. Каждый раунд слияний значительно усложняет граф, что приводит меня к двум выводам:

  1. этот способ наложения веток может работать до тех пор, пока я наблюдаю за своим шагом и не делаю ничего глупого, не пытаясь извлечь какой-либо смысл из графа истории всех ветвей. Или же..
  2. должен быть какой-то лучший, более подходящий способ сделать это.

Чтобы проиллюстрировать мою "проблему", я приведу изображение графика, который я получил после создания этих веток, добавления нескольких коммитов для конкретной ветви, выбора нескольких из них, добавления и объединения одного коммита из master во все ветви, коммита или два к определенным ветвям, и затем еще одно объединение мастера со всеми.

своего рода не очень простой граф истории

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

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

Итак... Есть идеи, опыт, предложения, которыми вы не против поделиться?

ОБНОВЛЕНИЕ: я выбираю решение, описанное в моем комментарии к принятому ответу. Спасибо всем, кто внес свой вклад!

ОБНОВЛЕНИЕ 2: Несмотря на то, что это не тесно связано с этим вопросом, недавно я наткнулся на эту модель ветвления, которая, кажется, подходит практически для любого организованного цикла разработки с GIT в качестве основного DVCS. Это действительно хорошее чтение. Рекомендуемые.

2 ответа

Решение

Альтернативный ответ:

Вы можете переместить абстракцию с уровня ветки на уровень хранилища. Создайте одно главное репо с мастер-веткой. Клонируйте этот репозиторий для каждого сайта. После внесения изменений в основную ветку внесите эти изменения в каждое хранилище сайта. Таким образом, вам потребуется только одна основная ветка на репо.


Оригинальный ответ:

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

 o---o---o---o---o  master
         \
          o---o---o---o---o  pl_site

После того, как вы перебазировали pl_site, он будет выглядеть так:

 o---o---o---o---o  master
                  \
                   o'---o'---o'---o'---o'  pl_site

Обратите внимание, что коммиты на перебазированной версии pl_site являются новыми. Теперь pl_site содержит изменения, которые были сделаны на master.

Команды:

$ git checkout pl_site
$ git rebase master

У меня нет хорошего ответа для вас, потому что ваша проблема сложна и имеет сложные решения.

Вариант 1: Рефакторинг

Вы сказали, что разные сайты "в основном один и тот же сайт". Так что перенесите их в разные проекты и сохраните main_site в проекте сам по себе. Другие сайты будут включать main_site как подпроект.

Итак, для баннера...

en_site/
en_site/images/banner.jpg
en_site/master/
en_site/master/images/banner.jpg

Код вашего веб-сайта, сценарий конфигурации, сценарий развертывания или что-то еще обеспечит images/banner.jpg выбран master/images/banner.jpg, Может быть, при развертывании сайта master/images сначала копируется, а затем images копируется, может быть, вы делаете что-то более сложное.

Это может быть много работы. Однако, когда вы посмотрите на историю, вы получите что-то вроде этого:

en_site: A -> B -> C -> D
de_site: E -> F -> G -> H -> I
main_site: J -> K -> L -> M -> N -> O

Вариант 2: использовать Darcs

В Darcs вы можете перемещать патчи от ветки к ветке. Некоторые коммерческие VCS, вероятно, могут сделать это тоже. Так что ваши ветки будут выглядеть так:

master: patch1 patch2 patch3 patch4
en_site: patch1 patch2 patch3 patch4 en1 en2 en3
de_site: patch1 patch2 patch3 patch4 de1 de2 de3

Предположим, что вы хотите портировать патч en2 на немецкий сайт.

de_site: patch1 patch2 patch3 patch4 de1 de2 de3 en2

Вуаля. Однако это не так чисто, как кажется. Поклонники Darcs укажут, что эта модель патча соответствует нашей концептуальной модели "перемещения патча в другую ветвь", однако это заслоняет тот факт, что вам все равно придется протестировать, чтобы убедиться, что en2 патч не ломает все, когда вы надеваете его de_site,

Например, что если en2 вносит изменения в ту же часть кода, что и de1? Что тогда? Вы должны объединить вручную, независимо от того, какую VCS вы используете. Для каждого очевидного случая, подобного этому, есть другой случай, который VCS не обнаружит, и вам придется проверить его самостоятельно.

Мой опыт

Когда я впервые начал использовать gitказалось git merge было волшебство Однако никакие хитрости VCS не скрывают тот факт, что ваш сайт имеет очень сложные взаимозависимости. Вы можете либо реорганизовать свой сайт, чтобы удалить взаимозависимости, либо надеяться, что ваша история VCS не станет настолько сложной, что вы больше не сможете ее понять.

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

Другие вопросы по тегам