На ум приходят несколько простых подходов...
Отдельное пространство имен
Переместите все разбросанные файлы в отдельный каталог пространства имен, например ./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