Фрилансер сдал проект и потерял доступ к коду: свой Git на сервере
Полгода вы пишете код для чужого продукта: за это время накопились десятки осмысленных коммитов, продуманная архитектура, история проб и ошибок, которая сама по себе — часть вашей квалификации. Проект сдан, деньги получены, на следующий день вас убирают из организации на GitHub или из группы в GitLab — и вместе с этим исчезает история вашей же работы. Нечем подтвердить в портфолио, что конкретно вы делали, не к чему вернуться, если через полгода понадобится вспомнить, как вы тогда обошли ту проблему с миграцией. Решение старое и скучное: не полагаться на репозиторий заказчика как на единственное место, где живёт код, а держать параллельно свой git-сервер, куда стекает та же история и который принадлежит только вам.
Содержание
Механика потери: как это происходит на практике
Типичная схема фриланс-разработки выглядит так: заказчик создаёт приватный репозиторий в своей организации на GitHub, GitLab или Bitbucket, добавляет вас как collaborator или member, вы клонируете, коммитите, пушите в его remote. Формально каждый коммит подписан вашим именем и email, но сам репозиторий, вся его инфраструктура (issues, wiki, CI, история PR) — собственность заказчика. Как только контракт закрыт, доступ отзывается: вас убирают из организации, архивируют репозиторий, иногда просто меняют права так, что старые ссылки перестают открываться. С этого момента у вас нет доступа ни к git log, ни к обсуждениям в PR, ни к самому факту, что определённый коммит — ваш.
Хуже, если репозиторий был на self-hosted GitLab или Gitea самого заказчика, в его внутренней сети за VPN. Закрыли VPN-доступ — и репозиторий исчез для вас полностью, даже посмотреть на него больше нельзя, не то что склонировать.
Отдельная категория боли — агентства и субподряд. Вы пишете код внутри чужого репозитория как исполнитель для агентства, которое, в свою очередь, работает на конечного заказчика. Вас могут отключить от репозитория сразу после последнего спринта, ещё до финальной приёмки, просто потому что бюджет на вашу роль закрыт.
Почему «просто клонировать» срабатывает не всегда
Первая интуитивная мысль — клонировать репозиторий себе перед сдачей проекта. Это правильно, но на практике спотыкается о три вещи.
Во-первых, тайминг. Доступ иногда закрывают в тот же день, когда закрывается акт, — без предупреждения и без «последнего дня», когда можно спокойно всё скачать. Если вы физически не успели сделать git clone до отзыва прав, никакого повторного шанса не будет.
Во-вторых, переписанная история. Многие команды используют squash-merge при слиянии PR в основную ветку: в результирующей истории ваша ветка со всеми промежуточными коммитами схлопывается в один коммит от имени того, кто нажал «merge». Если вы полагались на то, что просто заберёте main в конце проекта, то получите урезанную версию своей же работы — без чернового пути, без объяснений, почему решение получилось именно таким.
В-третьих, ограниченный доступ. Иногда фрилансеру дают доступ только через веб-интерфейс для code review, без прав на git clone — например, приглашение только на конкретный PR или форк без полных прав на историю. В таком случае «просто клонировать» было физически невозможно с самого начала.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверИдея: держать зеркало с первого дня, а не спохватываться перед сдачей
Правильный момент завести собственный git-сервер — не за день до сдачи проекта, а в момент, когда вы делаете первый коммит. Идея простая: репозиторий заказчика остаётся основным местом работы (там вы согласовываете PR, проходите ревью, запускаете CI заказчика), но параллельно та же история копируется на git-сервер, который физически стоит на вашем VPS и принадлежит только вам.
Здесь стоит сразу оговорить честный нюанс: держать копию кода заказчика после сдачи проекта — вопрос не технический, а юридический. Если в договоре или NDA явно прописан запрет хранить исходники после закрытия контракта, зеркалирование чужого кода на свой сервер — нарушение условий, и никакая техническая возможность этого не отменяет. Разумная практика — до старта проекта договориться в переписке или в самом договоре, что вы вправе держать приватную копию репозитория для собственного архива и портфолио (без права публикации кода третьим лицам). Большинство заказчиков соглашаются на такую формулировку, если попросить прямо, — это стандартная практика в разработке, а не что-то из ряда вон. Если заказчик прямо против — тогда решение из этой статьи применимо только к вашим собственным проектам и к репозиториям, где вы — единственный или основной автор кода, а не к чужой закрытой кодовой базе.
Разворачиваем git-сервер на своём VPS
Для одного разработчика или небольшой команды из двух-трёх фрилансеров тяжёлый GitLab CE обычно избыточен — он неплохо себя чувствует, но на слабом VPS будет ощутимо есть RAM даже в простое. Практичнее взять Gitea или Forgejo (форк Gitea с открытым управлением) — оба поднимаются за несколько минут, работают на минимальном железе и дают всё нужное: приватные репозитории, SSH и HTTPS push, веб-интерфейс с diff и историей, issues, встроенный CI (Gitea Actions / Forgejo Actions) для тех, кому нужен и он.
Быстрый вариант — Docker Compose:
version: "3.8"
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
restart: unless-stopped
volumes:
- ./gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
После docker compose up -d веб-интерфейс поднимется на порту 3000, а SSH для push/pull — на 222 (обычный 22 порт лучше оставить системе). Дальше — типовая настройка: домен или поддомен, TLS через реверс-прокси (Caddy или nginx с Let's Encrypt), создание своего пользователя и SSH-ключа. Подробный пошаговый разбор установки — в отдельной статье про Gitea на VPS, там же — нюансы с правами на volume и первым запуском. Если сомневаетесь между Gitea и её форком, разница и повод выбрать один вместо другого разобраны в статье Gitea против GitLab — она же полезна, если позже решите, что для команды из нескольких человек нужен полноценный GitLab CE.
Ресурсов такому серверу нужно немного: для Gitea или Forgejo с несколькими десятками репозиториев вполне хватает 1-2 vCPU и 2 ГБ RAM, диск — по объёму реальных репозиториев плюс запас под историю (обычно это единицы гигабайт для типичного веб-проекта, но если в репозитории лежат бинарники или дизайн-файлы, стоит закладывать больше).
Настраиваем зеркалирование: два remote вместо одного
Дальше — рабочий процесс на уровне git, без смены привычек. Самый простой вариант — добавить свой сервер вторым push-адресом к тому же origin, чтобы один git push уходил сразу в оба места:
git remote add origin git@github.com:client-org/project.git
git remote set-url --add --push origin git@github.com:client-org/project.git
git remote set-url --add --push origin git@my-server.dev:22/you/project.git
После этого git push origin main отправит коммиты и в репозиторий заказчика, и на ваш git-сервер за один вызов. Минус подхода — если один из адресов недоступен (например, вы временно потеряли VPN до заказчика или ваш VPS ушёл на обслуживание), команда завершится с ошибкой на обоих направлениях, хотя второй remote был бы доступен. Для ежедневной работы это не критично: просто повторяете push, когда доступность восстановится.
Более отказоустойчивый вариант — не трогать основной remote вообще, а зеркалировать с сервера. На своём VPS заводите пустой (bare) репозиторий и настраиваете периодический fetch из репозитория заказчика по read-only ключу или токену:
git clone --mirror git@github.com:client-org/project.git /srv/mirrors/project.git
cd /srv/mirrors/project.git
git remote set-url --push origin git@my-server.dev:you/project.git
Дальше по cron раз в день (или чаще, если хотите почти реалтайм):
*/30 * * * * cd /srv/mirrors/project.git && git fetch -q origin && git push -q --mirror mine
Такой вариант ничего не меняет в вашей повседневной работе — вы просто пушите как обычно в репозиторий заказчика, а сервер сам подтягивает и зеркалирует историю к себе. Здесь же удобно завести и второй уровень защиты — обычный бэкап настроенного GitLab CE или Gitea/Forgejo целиком (дамп базы плюс каталог с репозиториями), чтобы зеркало само не оказалось единственной копией.
Если проекту в принципе нужен автодеплой из вашего же git-сервера (например, для собственного стенда или демо), логика настройки хуков и вебхуков разобрана в статье про автодеплой из Git на VPS — тот же сервер спокойно совмещает роль архива истории и роль источника для деплоя.
Что делать, если доступ уже потерян
Если статья читается уже постфактум — доступ закрыт, а зеркала нет, — не всё потеряно, но действовать нужно быстро, пока не затёрлись остатки.
Проверьте каждый локальный клон на всех своих машинах: рабочий ноутбук, старый ноутбук, домашний десктоп, CI-агент, если вы сами его поднимали. Важно отличать полный клон от частичного: если где-то стоит git clone --depth 1 (мелкий shallow-клон под CI), там не будет полной истории, только последний срез. Ищите каталог, где вы когда-то делали именно git clone <url> без ограничения глубины — там в .git может лежать вся история, даже если рабочая копия файлов давно удалена.
Проверьте git reflog и папку .git/refs даже в клонах, которые давно не обновлялись, — там нередко остаются ссылки на ветки и коммиты, которые уже удалены на сервере заказчика, но всё ещё физически лежат у вас на диске.
Если ничего не нашлось — напишите заказчику напрямую с простой просьбой: доступ только на чтение (read-only) или экспорт репозитория для личного архива. Многие заказчики не возражают, если отношения закончились нормально, а формулировка честная — «хочу сохранить историю своей части работы для портфолио, без права публикации кода». Это стоит просить сразу после закрытия акта, пока контакт ещё тёплый, а не через полгода.
На будущее — самый надёжный способ не оказаться в этой ситуации снова — не полагаться на память в конце проекта, а завести зеркалирование в первый рабочий день следующего контракта, как описано выше.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Законно ли держать копию кода заказчика после сдачи проекта?
Зависит от договора и NDA. Если явного запрета нет — обычно допустимо иметь приватную копию для архива и портфолио, но безопаснее прописать это прямо в договоре или согласовать перепиской до старта работы, а не выяснять постфактум.
Что выбрать для личного архива — Gitea или Forgejo?
Для одного разработчика разница минимальна: оба легковесны и почти идентичны по функциям, Forgejo — открытый форк Gitea с другой моделью управления проектом. Если сомневаетесь, берите тот, что описан в вашей текущей инструкции, — миграция между ними позже не требует переписывания истории репозиториев.
Нужен ли на личном git-сервере CI, если это просто архив?
Не обязательно. Если сервер нужен только для сохранения истории, можно вообще не поднимать CI-раннер — это не даст запускать пайплайны, но не мешает push/pull и просмотру истории. CI имеет смысл добавить, только если сервер параллельно используется под деплой демо-стендов.
Как показать код из приватного репозитория заказчика в портфолио, не нарушая условия?
Даже при наличии полной истории у себя публиковать чужой закрытый код обычно нельзя. В портфолио безопаснее описывать задачу, стек и вашу роль текстом, показывать скриншоты интерфейса (если заказчик не против) и приводить обезличенные фрагменты кода только с явного разрешения — а полную git-историю держать при себе как личный референс, а не публичный экспонат.
Сколько репозиториев реально накапливается за годы фриланса и не станет ли сервер тесным?
Для типичных веб- и бэкенд-проектов история в git занимает немного места по сравнению с бинарными файлами — десятки завершённых проектов обычно укладываются в единицы-десятки гигабайт. Диск на VPS всегда можно расширить позже, отдельный сервер под это заводить с запасом на будущее не обязательно.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →