рабочий процесс git для проекта с открытой и проприетарной (частной) частью

Плагин Wordpress с бесплатной и PRO версией. Версия PRO содержит дополнительные файлы, разбросанные по кодовой базе.

Какова оптимальная стратегия для отслеживания обеих версий в git с соблюдением следующих ограничений:

  1. бесплатная версия с открытым исходным кодом на GitHub, принимающая участие;
  2. PRO-версия синхронизирована с приватным репозиторием;
  3. локальная разработка происходит в версии PRO (например, для работы рефакторинга);
  4. обе истории связаны (история PRO ⊇ бесплатна)
  5. low-maintenance:
    1. we are git noobs,
    2. нет ручного учета того, какой файл куда подходит.

Существует множество плагинов для Wordpress, которые точно следуют этой дихотомии бесплатного и PRO. Как они версионируются?


person K3---rnc    schedule 06.07.2018    source источник


Ответы (1)


На ум приходят несколько простых подходов...

Отдельное пространство имен

Переместите все разбросанные файлы в отдельный каталог пространства имен, например ./pro, в который вы клонируете отдельный репозиторий PRO, содержащий только файлы PRO. Недостаток: проверки двух репозиториев должны быть синхронизированы (т. е. если вы переключаетесь на старую фиксацию в одном репозитории, вам также всегда нужно переключаться на совместимую фиксацию в другом). репо).

Два репозитория

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

cd ~/project-libre
git remote add origin GITHUB_PUBLIC_REPO

cd ~/project-pro
git remote add origin PRIVATE_REPO
git remote add libre GITHUB_PUBLIC_REPO  # to fetch and merge changes from

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

cd ~/project-pro
git checkout master
git pull libre master --allow-unrelated-histories
git push origin master

Всякий раз, когда есть изменения в версии PRO, которые вы хотите синхронизировать с опубликованной бесплатной версией, вы можете использовать git-format-patch, чтобы экспортировать изменения в виде файлов исправлений, а затем, с другой стороны, импортировать этот набор исправлений, исключая любые файлы, которые не должны публиковаться в бесплатной версии. Вот так:

cd ~/project-pro
git checkout master
git format-patch HEAD~3..HEAD  # Export e.g. last three commits as patches

Теперь переключитесь на бесплатную версию и примените исправления (с git-am), исключив из каждого коммита все файлы PRO (пути), которые находятся в списке игнорирования для бесплатной версии. Я поместил их в файл .gitignore здесь, в корне бесплатного проекта, а командная строка предполагает POSIX. доступна оболочка (повторяет параметр --exclude для каждого файла/пути в .gitignore).

cd ~/project-libre
git checkout master
git am $(printf -- '--exclude=%s ' $(cat .gitignore)) ~/project-pro/*.patch    

Две ветки

Имейте две ветки, каждая из которых синхронизируется с другим пультом.

git remote add origin  GITHUB_PUBLIC_REPO
git remote add private PRIVATE_REPO

Создайте два файла, один бесплатный и один PRO:

touch free1 pro1

В основной ветке создайте .gitignore, содержащий все файлы PRO.

git checkout master
echo 'pro*' > .gitignore

git add .gitignore
git commit -m 'Add .gitignore ignoring PRO files'

Синхронизируйте публичную ветку с публичным репозиторием:

git push -u origin master

Теперь создайте ветку master в приватную ветку PRO и очистите .gitignore, так как файлы PRO там не игнорируются.

git checkout --branch master-private
echo > .gitignore

git commit .gitignore -m 'Clear .gitignore -- track all files here'

Синхронизируйте приватную ветку с приватным репозиторием:

git push -u private master-private

Теперь зафиксируйте файлы free1 и pro1 в соответствующих ветках:

git checkout master
git add free1
git commit -m 'Add free1'

git checkout master-private
git add pro1
git commit -m 'Add pro1'

И слить master в master-private, чтобы он содержал полный набор.

git checkout master-private
git merge master

Вам нужно разрешить один конфликт .gitignore (или вы можете указать переключатель слияния -X ours).


Позже вы делаете некоторые разработки в основной-частной ветке (§ 3), ретушируя и создавая различные файлы, которые подходят к любой из двух веток:

git checkout master-private
touch free2 pro2
echo xxx > free1
echo xxx > pro1

Вы не хотите перечислять все не-PRO файлы для фиксации (§ 5.2); для этого у вас есть .gitignore. Вы используете его, переключившись на master и там зафиксировав все, что подходит, затем переключившись обратно на master-private, зафиксировав то, что осталось. Сначала вам нужно сохранить изменения, так как они будут перезаписаны при переключении ветвей.

git stash
git checkout master
git stash apply

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

git reset HEAD .

Теперь зафиксируйте все свободные файлы:

git add free2  # Manually add the new files (easy and not violating § 5.2)
git commit -a -m 'Update to free1 and free2'

Вернитесь в приватную ветку, объединитесь с обновленной основной веткой и зафиксируйте оставшиеся файлы снова из тайника.

git checkout master-private
git merge master
git stash pop  # The stash now applies cleanly and is removed
git add pro2  # Manual but necessary adding of new files (not violating § 5.2) 
git commit -a -m 'Update pro1 and pro2'

Вот и все.


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

git checkout master
git pull
git checkout master-private
git merge master
git push

git очень прост.

person K3---rnc    schedule 06.07.2018