---
title: "Fork без боли: Как синхронизировать свои патчи с upstream и автоматически релизить"
description: "Patch-based синхронизация fork с upstream на примере ccpocket-oauth-auth. GitHub Actions, git format-patch, auto-release за 11 промптов с Claude Code."
url: "https://ifonin.ru/blog/fork-bez-boli-patch-sync/"
date: 2026-03-20
tags: ["vibe-coding","git","github-actions","claude-code","devops"]
---

# Fork без боли: Как синхронизировать свои патчи с upstream и автоматически релизить

Я заплатил за Claude Max, но оригинальный проект ccpocket убрал OAuth-авторизацию - и я не хочу платить за токены дополнительно. За 11 промптов я создал форк с собственной OAuth-авторизацией, который автоматически подтягивает релизы upstream и делает отдельный релиз для меня.

---

## Форк как обуза

ccpocket - это по сути мобильный Claude Code. Открываешь на телефоне, работаешь с агентом как в чате. Я активно контрибьютил в проект, а потом владелец решил убрать OAuth-авторизацию. Правила Anthropic разрешают OAuth для доступа к API с подпиской Max - но владелец решил, что безопаснее без неё.

Варианты у меня были простые: платить за токены поверх уже оплаченного Max, или делать форк. Форки пугают именно тем, что начинаются легко, а потом превращаются в постоянный maintenance. Upstream выпускает новую версию - ты либо тратишь час на ручное обновление, либо просто откладываешь. Потом откладываешь ещё раз. Форк начинает отставать на несколько версий и превращается в мёртвый груз.

Так казалось.

---

## Patch-based подход вместо merge

Классический форк - это ветка от upstream, в которой ты делаешь изменения. При каждом обновлении - либо merge с кучей мёрж-коммитов, либо rebase с риском конфликтов. История разрастается, трудно понять что вообще твоё, а что пришло из upstream.

Я выбрал другой путь: patch-based подход. Мои изменения живут отдельно в виде патчей. Патч - текстовый файл, описывающий разницу. Когда выходит новый upstream релиз, автоматика берёт чистый upstream и накладывает мои патчи поверх. Применились без конфликтов - сразу выходит новый релиз форка.

Это не изобретение. `git format-patch` существует с первых версий Git. Linux kernel до сих пор живёт на патчах по email. StGit - инструмент для управления стеками патчей - активно развивается, последняя версия вышла в начале этого года. Просто для личных проектов этот подход используют реже, чем стоило бы.

Для форка с несколькими патчами это идеальный вариант. Чистая история, легко понять что изменено, легко переносить изменения между версиями.

---

## 11 промптов с Claude Code

Весь форк ccpocket-oauth-auth я сделал с AI-агентом. 11 промптов - это не мало и не много для начальной настройки. Установочная фаза требует времени, потом maintenance становится гораздо дешевле.

**Структура репозитория.** Первые несколько промптов ушли на то, чтобы разобраться как хранить патчи. Выбрал папку `patches/` с нумерованными файлами и файлом `series` который задаёт порядок применения - это Quilt-стиль, понятный любому кто работал с Debian-пакетами. Патчей у меня немного: это возвращение OAuth-авторизации, не больше.

**GitHub Actions для синхронизации.** Центральная часть. Workflow срабатывает по расписанию и проверяет upstream на новые релизы. Если появился новый релиз - берёт чистый код, применяет мои патчи через `git am`, прогоняет тесты. Прошло - создаётся PR для ревью. Конфликтует - тоже PR, но с описанием проблемы, чтобы я мог разобраться руками.

```yaml
- name: Apply patches
  run: |
    git am patches/*.patch || {
      echo "Conflicts detected"
      git am --abort
      exit 1
    }
```

**Версионирование.** Мой форк получает версию вида `v1.2.3-oauth.1`. Первая часть - версия upstream, суффикс `oauth` и порядковый номер - моя итерация. Changelog генерируется автоматически из коммитов.

**Тестирование и документация.** Последние промпты - убедиться что OAuth работает после применения патчей, и написать README для тех кто захочет использовать форк.

---

## Три компонента паттерна

Если выдернуть из этого кейса переносимый паттерн, получаются три компонента.

**Patch Management.** Папка `patches/` с нумерованными файлами, файл `series` с порядком применения. Каждый патч - одна логическая задача. Патчи версионируются вместе с кодом, так что в истории репозитория видно как они менялись.

**Automated Sync.** GitHub Actions по расписанию проверяет upstream. `git fetch upstream`, сравнение тегов, если есть новый релиз - применить патчи и прогнать тесты. PR-mode здесь важнее чем автоматический push в main: лучше лишний раз посмотреть что произошло, особенно если upstream выпустил что-то неожиданное.

**Auto-Release.** Если патчи применились и тесты прошли - создаётся релиз с версией `{upstream-version}-oauth.{n}`. Пользователи форка получают обновления автоматически.

Всё это работает без моего участия. Я мог бы узнать о новом релизе ccpocket через неделю - и мой форк уже бы его подхватил.

---

## Когда это перестаёт работать

Я держу три-пять патчей. Это комфортная зона - конфликты случаются редко и разрешаются быстро.

При шести-двадцати патчах стоит добавить StGit. `stg rebase upstream/main` автоматически пробует наложить весь стек на новый base, разрешая конфликты через 3-way merge. Там где `git am` просто падает, StGit пытается разобраться сам - это принципиальная разница при большом стеке.

При пятидесяти и больше патчах - это уже не форк, это фактически отдельный проект. Fedora использует специализированный Packit workflow для автоматизации релизов и управления downstream патчами при подготовке дистрибутива, но это enterprise-уровень с выделенными людьми. Для личного проекта лучше либо активнее контрибьютить в upstream, либо признать что ведёшь самостоятельный проект.

Магия форка-как-расширения работает именно потому что он маленький.

---

## AI-агент в процессе форк-синхронизации

Claude Code помог в трёх конкретных местах.

Первое - само создание workflow. Я мог бы написать GitHub Actions YAML руками, это не сложно. Но с агентом я описал что хочу ("синхронизировать upstream, применять патчи, создавать релиз") и получил рабочий черновик за один промпт. Потом несколько итераций на уточнение деталей.

Второе - конфликты при применении патчей. Когда `git am` упал, агент читал контекст конфликта и предлагал как его разрешить. Не всегда правильно, но как точка отсчёта - полезно.

Третье - документирование патчей. Каждый патч должен иметь понятное описание: зачем он существует, почему не ушёл в upstream, на что обратить внимание при конфликте. Агент хорошо справляется с такими комментариями если ему показать сам патч.

11 промптов на старте - это нормально. Потом maintenance требует промпта примерно раз в месяц, когда что-то конфликтует. Всё остальное автоматическое.

---

## Результат

ccpocket-oauth-auth существует, OAuth-авторизация работает, синхронизация с upstream автоматическая. Я использую Claude Code с телефона, не плачу за токены поверх уже оплаченного Max.

Если upstream выпустит сто релизов - мой форк получит сто релизов. Моё участие требуется только когда patch конфликтует с новым кодом. За всё время с момента запуска это случилось один раз.

`git format-patch` и `git am` - инструменты из стандартного Git. GitHub Actions - стандартная автоматизация. Сложность была не в технологии, а в том чтобы сесть и сделать.
