#git #git-merge #access-control
#git #git-слияние #управление доступом
Вопрос:
Извлеченные данные из кода
Мой репозиторий git содержит как код, так и ресурсы. Проект Scala, но Java будет аналогичен: ресурсы содержатся в shared/src/main/resources
path, остальные являются источниками. Назовем этот репозиторий «репозиторий кода».
Я хочу, чтобы некоторые люди могли редактировать ресурсы, но не имели никакого доступа к остальной части репозитория. Для достижения этой цели я создал новый репозиторий (назовем его «data») и зафиксировал в нем два коммита:
- начальный коммит из репозитория кода (мне повезло, что этот коммит вообще не содержал никаких файлов), поэтому включить его было легко (это предотвращает несвязанную ошибку истории)
- фиксация с текущим состоянием
shared/src/main/resources
Люди, которые вносят вклад только в данные, получают доступ только к репозиторию «данных».
Объединение данных в код
Это работает довольно хорошо, я могу без каких-либо проблем объединить любые изменения, внесенные в репозиторий «данные», в мой репозиторий «код».
Слияние изменений данных из кода в данные
Единственная проблема заключается в том, что я вношу какие-либо изменения в ресурсы в моем репозитории «code». Когда я пытаюсь объединить такие изменения, git хочет объединить все коммиты, которые я ранее не включал в репозиторий «данных», эффективно добавляя в него весь код. Я могу исправить такое слияние, используя --no-ff
--no-commit
параметры и и отменяя нежелательные вставки файлов перед совершением слияния. Полученный таким образом результат хорошо выглядит в репозитории «данных», но затем слияние из «данных» в «код» становится затруднительным, поскольку этот «возврат» теперь является частью фиксации слияния, и git хочет его применить. Я могу предотвратить это таким же образом, но это снова только переносит проблему на другую сторону.
Существует ли какой-либо рабочий процесс или инструмент, который можно было бы использовать в такой ситуации? Я знаю о подмодулях, но я бы хотел держаться от них подальше, поскольку они приносят свои проблемы.
Я знаю, что это, вероятно, нецелевое использование Git, а не то, что обычно делается, и я ожидаю ответа «нет, это невозможно», но, видя огромное количество творчества, которое некоторые люди проявляют при использовании Git, я сказал себе, что спрошу здесь с надеждой, что какое-то решение может помочьбыть найденным.
Комментарии:
1. Сума, с какими проблемами вы ожидаете столкнуться при использовании вспомогательных модулей?
2. Недавно я использовал подмодули в проекте. Клонирование, ветвление и слияние, которые обычно являются тривиальными, стали довольно сложными. Обработка перемещения подмодуля в другой каталог была за пределами моих возможностей, даже удалить его было довольно сложно.
3. Есть альтернативы подмодулю git, которые вы можете попробовать blog.summitto.com/posts/submodules_subtree_subtrac и github.com/ingydotnet/git-subrepo/blob/master/Intro.pod .
4. Если вы используете github, вы можете использовать концепцию CODEOWNERS здесь. docs.github.com/en/free-pro-team@latest/github /…
5. Вы описываете пример использования учебника для подмодулей. Пожалуйста, опишите более подробно проблемы, которые у вас возникли с подмодулями, чтобы увидеть, как их можно решить.
Ответ №1:
Я вижу два основных способа сделать это без использования подмодулей, в зависимости от того, хотите ли вы сохранить историю или нет. Оба основаны на одной и той же идее: создайте новую ветку, содержащую только изменения в интересующих вас файлах, затем объедините эту ветку. Я собираюсь предположить, что оба репозитория содержат shared/src/main/resources
путь с соответствующими папками: если вы переместили один из них в «данные» в корень, это становится более сложным, потому что коммиты относятся к файлам в разных местах. Одним из простых решений является создание коммита в «data», в который перемещаются файлы shared/src/main/resources
, объединение изменений из «code», а затем удаление коммита (с использованием git rebase -i
). В качестве альтернативы в разделе «ведение истории» вы можете использовать git-filter-repo
для перезаписи местоположения папки.
Потеря истории
Это проще сделать разово, но сложнее автоматизировать и может привести к более сложным слияниям. Здесь вы делаете то же самое, что и при создании хранилища «данных»: просто сбрасываете существующее состояние папки поверх хранилища данных. Если вы только что объединили «данные» в «код», то «код» содержит нужные вам изменения: просто скопируйте resources
файл в «данные» и создайте коммит.
Сохранение истории
Создайте другое репозиторий / ветку, содержащую только изменения shared/src/main/resources
. Я рекомендую использовать git-filter-repo . Обратите внимание, что это перепишет ваш репозиторий: я не уверен, сможете ли вы заставить его переписать только ветку.
cd /path/to/new/repo
git clone code
git checkout -b resources-only
git filter-repo --path shared/src/main/resources
Затем в разделе «данные»:
git remote add code-resources-only /path/to/new/repo/code
git fetch code-resources-only
git merge --allow-unrelated-histories code-resources-only/resources-only
git remote remove code-resources-only
Одна небольшая проблема с репозиторием «данных» заключается в том, что он содержит фиксацию, отсутствующую в истории «кода»:
фиксация с текущим состоянием
shared/src/main/resources
в то время как в «коде» будет много коммитов, создающих папку ресурсов. На самом деле это не проблема после первого слияния, но может быть лучше, если ветви действительно разделяют историю.