Игонорирование файлов при слиянии веток и извлечение истории конфигуции проекта из репозитория
Есть проект с репозиторием в котором в коммите есть конфиги. Сделал ветку dev
изменил конфиги, добавил папку-песочницу (.sandbox
), которая в master
не нужна.
Собственно вопрос, можно ли выполнить слияние где файлы конфигов и моя папка .sandbox
не участвовали бы?
Как делаю сейчас: git merge --no-commit --no-ff
руками выкидываю .sandbox
и конфиги, дальше комичу. И так каждый раз... Посмотрел в сторону .gitattribute с path/file merge=ours
, но в случае с конфигами они в master
не меняются, нет конфликта слияния, драйвер не срабатывает. .gitignore на папку .sandbox
тоже не вариант, в ветке dev
хотелось бы следить, что там меняю. Так же пробовал использовать git update-index --skip-worktree $file
, при слиянии то да помогает, но и изменений в ветке dev
тоже не вижу.
Ответы (1 шт):
Прислушался к совету @user7860670
Храните конфиги в отдельном репозитории.
Извлек конфиги из основного репозитория. Сделал ветку для dev-версии
Репозитории
Проект находиться по пути /home/myproject, конфиги - /home/myproject/conf
Что нужно сделать. Извлечь историю изменения конфигов. Очистить историю основного репозитория от конфигов.
Использовал filter-repo.
- Скачал git-filter-repo с гита (:home$
wget https://raw.githubusercontent.com/newren/git-filter-repo/main/git-filter-repo
) - устанавил (можно в систему, но я сделал alis'ом)
# .git/config
[alias]
filter-repo = !python3 /home/git-filter-repo
Извлечение истории
Для файлов конфигурации вполне подойдет плоский репозиторий (в моем случае). Создал его, перешел, извлек историю.
- :myproject$
git clone --bare ./.git ./conf.git
(можно закинуть его в игнор, а можно разместить вне проекта) - :conf.git$
git filter-repo --path conf/ --path-rename conf/:
(можно и отдельными файлами--path conf/1.conf --path-rename conf/1.conf:1.conf --path conf/2.conf --path-rename conf/2.conf:2.conf
)
Готово. Проверочка :conf.git$ git log
Очистка истории
Удалил все следы конфигов из основного репозитория (добавив в .gitignore), проверил, спушил в удаленный.
НА ВСЯКИЙ СЛУЧАЙ :myproject$ tar -cf git.tar .git
- в самом конце не забыть удалить.
- :myproject$
git filter-repo --path conf --invert-paths
- :myproject$
git log
- :myproject$
git push --force origin master
Готово. ТОЛЬКО ПОСЛЕ того как все OK :myproject$ rm git.tar
Работа с кофигами
Да намного муторнее, но все в сохранности (конфиги не самая частая вещь которую меняю, 1й раз при развертывании проекта, 2й раз при развертывании dev-версии)
Создал репозиторий, подключил удаленный.
- :home$
git init /home/myproject.conf && cd myproject.conf
- :myproject.conf$
git remote add origin /home/myproject/conf.git
Готово. Забрал нужную ветку :myproject.conf$ git pull origin master
, что-то изменил и спушил обратно.
Как получить файлы в рабочем проекте? варинта два, первый - копировать (а зачем тогда возня с удаленным репозиторием? что бы вести учет изменений), второй - подключить репозиторий с конфигами к основному.
Вариант 2 (на проде так делать не надо, только в деве):
- :myproject$
git remote add conf-repo /home/myproject/conf.git
- :myproject$
git fetch conf-repo
- :myproject$
git checkout -b temp-branch conf-repo/master
Ветка для dev-версии
Для моего проекта оказалось комфортным
Отдельная ветка нужна, для внесения изменений в файлы только на дев версии и что бы в последствии с ними удобно было работать при слиянии.
- master - все что на прод
- dev-preset - тут изменения которые не должны попасть в master
- workflow - ветка разработки от нее уже можно при надобности ветвится и с нее слияние в master
Если что то-то меняеться/добавляется у dev-preset сливаю в workflow
Новая фича готова время заливать в мастер:
git checkout master
git merge workflow --no-ff --no-commit
Конечно в git сатусе будут изменения и из dev-preset, git diff --name-only dev-preset master | xargs git status
- покажет изменния только в этой ветке, которые вернуть к состоянию в master
Надежнее все посмотреть и проверить, но можно упростить dev-out.sh
git diff --name-status dev-preset master | while read status file; do
# знаю про resore, но доставшийся мне проект старенький
git reset -- "$file"
if [ "$status" = "M" ]; then
git checkout -- "$file"
elif [ "$status" = "A" ]; then
git clean -f "$file"
elif [ "$status" = "D" ]; then
git clean -f "$file"
fi
done
или добавить в alias'ы
[alias]
dev-out = "!sh -c 'git diff --name-status dev-preset master | while read status file; do git reset -- \"$file\"; [ \"$status\" = \"M\" ] && git checkout -- \"$file\"; [ \"$status\" = \"A\" ] && git clean -f \"$file\"; [ \"$status\" = \"D\" ] && git clean -f \"$file\"; done'"
dev-view = !git diff --name-only dev-preset master | xargs git status