--- title: "Блог на Hugo в K3s: часть 4 - выбор Git workflow" date: 2026-02-16 draft: false description: "Одна папка или две для dev и production? Разбираем Git workflow для Hugo блога в K3s — переключение веток против отдельных директорий." tags: ["git", "workflow", "devops", "hugo"] categories: ["Веб-разработка", "DevOps практики"] series: ["Блог на Hugo в K3s"] series_order: 4 --- В части 3 мы развернули два окружения - production и development. Один репозиторий, две ветки (`main` и `dev`), два пайплайна. Теперь встаёт вопрос: **как организовать работу локально?** --- ## Проблема У нас есть: - Репозиторий в Gitea - Две ветки: `main` (production) и `dev` (development) - Необходимость постоянно переключаться между ними Как это делать на локальной машине? Два варианта. --- ## Вариант А: Две отдельные папки Клонируем репозиторий дважды - в разные папки: ``` ~/projects/ ├── blog/ ← ветка main (production) └── blog-dev/ ← ветка dev (development) ``` **Логика:** Хочу работать с dev - иду в `blog-dev`. Хочу что-то проверить в production - иду в `blog`. Без переключения веток. ### Кажущиеся преимущества **Параллельная работа.** Можно держать открытыми два терминала - в одном `hugo server` для dev, в другом смотреть production код. **Изоляция.** Каждая папка - своя песочница. Изменения в одной не влияют на другую. **Простота навигации.** `cd blog-dev` вместо `git checkout dev`. Меньше команд. **Привычный паттерн.** Многие админы и разработчики держат несколько клонов для разных задач. ### Реальные проблемы #### Проблема 1: Рассинхронизация локальных ветокin Работаю в `blog-dev` - пишу статьи, коммичу, пушу в `origin/dev`. Всё хорошо. Но локальная ветка `dev` в папке `blog` при этом **не обновляется**. Она отстаёт от `origin/dev`. Приходишь делать merge: ```bash cd blog git checkout main git merge dev # Already up to date. ← НО есть НЮАНС! ``` Git говорит "всё актуально", имея в виду **локальную** ветку `dev`, которая отстала на три коммита. Статьи не попадают в production. Приходится помнить делать `git pull origin dev` перед каждым merge. Забыл - публикуешь устаревшую версию. #### Проблема 2: Конфликты при merge Редактируешь `config/params.toml` в обеих папках независимо: - В `blog-dev` добавил Firebase конфиг - В `blog` изменил название сайта При merge Git честно сообщает о конфликте: ``` CONFLICT (content): Merge conflict in config/params.toml ``` И это повторяется **каждый раз** когда трогаешь конфигурацию. Потому что две папки - это две независимые истории изменений одного файла. #### Проблема 3: Работа не в той папке Несколько раз ловил себя на том что редактирую статьи прямо в `blog` - папке production. Это нарушает весь смысл раздельных окружений. #### Проблема 4: Умственная нагрузка Постоянный вопрос "в какой папке я сейчас?" Для простого блога это лишняя когнитивная нагрузка. --- ## Вариант Б: Одна папка с переключением веток Один клон репозитория, работа через `git checkout`: ``` ~/projects/ └── blog/ ← одна папка, две ветки: main и dev ``` ### Как это работает **Пишу статью:** ```bash cd ~/projects/blog # Переключаюсь на dev git checkout dev # Проверяю что dev актуален git pull origin dev # Запускаю локальный сервер hugo server -D --bind 0.0.0.0 # Создаю статью hugo new content posts/название/index.md # Коммичу и пушу git add . git commit -m "feat: новая статья" git push origin dev ``` **Публикую:** ```bash # Убеждаюсь что dev актуален git checkout dev git pull origin dev # Переключаюсь на main и мержу git checkout main git pull origin main git merge dev git push origin main ``` ### Реальные преимущества **Никакой рассинхронизации.** Все ветки в одном репозитории. `git pull` обновляет всё что нужно. **Нет конфликтов из-за независимых изменений.** Когда работаешь в одной папке, `params.toml` существует в одном экземпляре. Все изменения делаются в `dev`, в `main` попадают только через merge. Конфликт возможен только если кто-то редактирует `main` напрямую - а это нарушение workflow. **Невозможно ошибиться с веткой.** `git branch` показывает где ты сейчас. Случайно отредактировать файлы в `main` - сложнее. **Меньше места на диске.** Один клон вместо двух. Один `.git` вместо двух. --- ## Сравнение на практических примерах ### Пример 1: Обновление темы Blowfish **Две папки:** ```bash cd blog-dev git submodule update --remote themes/blowfish git add themes/blowfish git commit -m "update: Blowfish theme" git push origin dev # Проверяешь на dev.blog.ru # Если всё ок - мержишь cd ../blog git checkout dev git pull origin dev # ← ЛЕГКО ЗАБЫТЬ git checkout main git merge dev git push origin main ``` **Одна папка:** ```bash cd blog git checkout dev git pull origin dev git submodule update --remote themes/blowfish git add themes/blowfish git commit -m "update: Blowfish theme" git push origin dev # Проверяешь на dev.blog.ru # Если всё ок - мержишь git checkout main git pull origin main git merge dev git push origin main ``` Меньше команд, меньше переходов между папками, меньше шансов забыть `git pull`. ### Пример 2: Правка опечатки в production Нашёл опечатку на `blog.ru`. Нужно исправить быстро. **Две папки:** Опасность: хочется исправить прямо в `blog` (ветка `main`). Это нарушает workflow - все изменения должны идти через `dev`. Правильно: ```bash cd blog-dev git checkout dev # Исправляешь git commit -m "fix: опечатка" git push origin dev cd ../blog git checkout main git pull origin dev # ← опять легко забыть git merge dev git push origin main ``` **Одна папка:** ```bash cd blog git checkout dev git pull origin dev # Исправляешь git commit -m "fix: опечатка" git push origin dev git checkout main git merge dev git push origin main ``` Проще, меньше команд, понятнее. ### Пример 3: Долгая работа над статьёй Пишешь большую статью несколько дней. Между сеансами работы кто-то (или ты сам) запушил другие изменения в `dev`. **Две папки:** ```bash cd blog-dev # День 1: пишешь git add . git commit -m "wip: статья" # День 2: продолжаешь git pull origin dev # Подтягиваешь чужие изменения # Пишешь дальше git add . git commit -m "feat: закончил статью" git push origin dev ``` Всё так же как и с одной папкой. Разницы нет. **Одна папка:** ```bash cd blog git checkout dev # День 1: пишешь git add . git commit -m "wip: статья" # День 2: продолжаешь git pull origin dev # Подтягиваешь чужие изменения # Пишешь дальше git add . git commit -m "feat: закончил статью" git push origin dev ``` Идентично. Этот пример работает одинаково в обоих вариантах. --- ## Что выбрать? **Если ты только начинаешь - сразу делай одну папку.** Две папки кажутся удобными, но создают проблемы которые регулярно прерывают работу: - Рассинхронизация веток - Конфликты при merge - Когнитивная нагрузка Одна папка с переключением веток - стандартный Git workflow, проверенный миллионами разработчиков. Требует чуть больше дисциплины (`git checkout dev` вместо `cd blog-dev`), но избавляет от всех проблем выше. **Золотое правило:** Никогда не редактировать файлы находясь на ветке `main`. Все изменения - через `dev`. Всегда. --- ## Миграция: если начал с двух папок Если уже работаешь в двух папках - переход простой. ### Шаг 1: Убеждаемся что всё запушено ```bash # Проверяем обе папки cd ~/projects/blog-dev git status git push origin dev cd ~/projects/blog git status git push origin main ``` ### Шаг 2: Синхронизируем ветку dev в основной папке ```bash cd ~/projects/blog # Обновляем локальную ветку dev из remote git checkout dev git pull origin dev # Проверяем что всё актуально git log --oneline -5 # Возвращаемся на main git checkout main ``` ### Шаг 3: Удаляем вторую папку ```bash # Убеждаемся что в blog-dev нет несохранённых изменений cd ~/projects/blog-dev git status # Должно быть: nothing to commit, working tree clean # Удаляем папку cd ~/projects rm -rf blog-dev ``` ### Шаг 4: Проверяем что всё работает ```bash cd ~/projects/blog # Переключаемся на dev и запускаем сервер git checkout dev hugo server -D --bind 0.0.0.0 # Открываем http://localhost:1313/ # Видим dev версию сайта ``` --- ## Новый workflow: шпаргалка ### Создаю статью ```bash cd ~/projects/blog git checkout dev hugo new content posts/название/index.md # Пишу, сохраняю, проверяю в hugo server git add . git commit -m "feat: название статьи" git push origin dev # → dev.blog.ru ``` ### Публикую статью ```bash git checkout dev git pull origin dev # Убеждаюсь что dev актуален git checkout main git pull origin main # Убеждаюсь что main актуален git merge dev git push origin main # → blog.ru ``` ### Меняю конфигурацию ```bash git checkout dev # ВСЕ изменения только через dev! nano config/params.toml git add . git commit -m "feat: изменил конфиг" git push origin dev # Проверяю на dev.blog.ru # Если всё ок git checkout main git merge dev git push origin main ``` --- ## Что дальше Workflow выбран, окружения работают. Можно писать статьи. Но есть ещё одна тема которую стоит разобрать - что делать когда что-то сломалось. Как диагностировать проблемы когда сайт вдруг начал отдавать 503, или SSL перестал работать, или webhook не срабатывает. В следующей части покажу процесс диагностики на реальном примере - как я чинил `blog.ru` когда он внезапно стал недоступен из интернета. --- **Рекомендация этой части:** - Одна папка `~/projects/blog` - Переключение веток через `git checkout` - Все изменения через `dev` → merge в `main` - Никогда не редактировать находясь на `main`