---
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`
