Игонорирование файлов при слиянии веток и извлечение истории конфигуции проекта из репозитория

Есть проект с репозиторием в котором в коммите есть конфиги. Сделал ветку 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 шт):

Автор решения: Jarry Roxwell

Прислушался к совету @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

Извлечение истории

Для файлов конфигурации вполне подойдет плоский репозиторий (в моем случае). Создал его, перешел, извлек историю.

  1. :myproject$ git clone --bare ./.git ./conf.git (можно закинуть его в игнор, а можно разместить вне проекта)
  2. :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 - в самом конце не забыть удалить.

  1. :myproject$ git filter-repo --path conf --invert-paths
  2. :myproject$ git log
  3. :myproject$ git push --force origin master

Готово. ТОЛЬКО ПОСЛЕ того как все OK :myproject$ rm git.tar

Работа с кофигами

Да намного муторнее, но все в сохранности (конфиги не самая частая вещь которую меняю, 1й раз при развертывании проекта, 2й раз при развертывании dev-версии)
Создал репозиторий, подключил удаленный.

  1. :home$ git init /home/myproject.conf && cd myproject.conf
  2. :myproject.conf$ git remote add origin /home/myproject/conf.git

Готово. Забрал нужную ветку :myproject.conf$ git pull origin master, что-то изменил и спушил обратно.

Как получить файлы в рабочем проекте? варинта два, первый - копировать (а зачем тогда возня с удаленным репозиторием? что бы вести учет изменений), второй - подключить репозиторий с конфигами к основному.

Вариант 2 (на проде так делать не надо, только в деве):

  1. :myproject$ git remote add conf-repo /home/myproject/conf.git
  2. :myproject$ git fetch conf-repo
  3. :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
→ Ссылка