Перейти к содержимому
Aback Tools Logo

Ошибка Git «is not a valid branch name»: правила, исправления и конвенции

Ошибка Git «is not a valid branch name» с разбором: полный список правил refname, частые причины с однострочными исправлениями, безопасное переименование невалидных веток, правила GitHub/GitLab/Windows и командные конвенции именования.

DH
Tutorials & How-Tos11 мин чтения2,600 слов

Ошибка Git «is not a valid branch name» точна: предложенное вами имя нарушает одно или несколько правил refname. Исправление почти всегда сводится к правке одной строки, когда известно, какой символ или шаблон её вызвал. Это руководство охватывает полный набор ограничений именования Git, самые частые причины с точными исправлениями, безопасное переименование уже существующей ветки и внедрение валидных имён во всей команде до того, как кто-то столкнётся с ошибкой.

14+Запрещённых шаблоновпо спецификации refname Git
1 командаЧтобы переименовать веткуgit branch -m old new
0Жёсткий лимит длиныно рекомендуются 50-72 символа

Что означает ошибка

Когда Git сообщает `fatal: 'some-name' is not a valid branch name`, это значит, что переданная строка имени ветки нарушает спецификацию refname Git — набор правил, определяющих, что является допустимым именем ссылки в репозитории Git. Git применяет одни и те же правила к именам веток, тегов и remote-отслеживающих имён, потому что все они хранятся как ссылки в каталоге `.git/refs/`.

Валидация происходит до записи какого-либо объекта. Git прогоняет предложенное имя через `check_refname_format()` внутри и прерывается с ошибкой, если имя не проходит. Значит, вы увидите ошибку сразу при выполнении `git checkout -b`, `git branch` или `git switch -c` — никакого частичного состояния чистить не нужно.

Где возникает ошибка

  • `git checkout -b branch-name` - создание новой ветки и переключение на неё
  • `git branch branch-name` - создание новой ветки без переключения
  • `git switch -c branch-name` - современный эквивалент checkout -b
  • `git push origin branch-name` - отправка в remote с невалидным локальным именем
  • Скрипты CI/CD - когда имя ветки строится программно из ID задачи или сообщения коммита

Note

Полное сообщение об ошибке Git цитирует точное имя, которое не прошло: `fatal: 'my feature branch' is not a valid branch name`. Цитируемое значение — буквальная строка, полученная Git, включая пробелы, спецсимволы и развёрнутые shell-значения. Это облегчает поиск именно того символа, который вызвал проблему.

Правила именования веток в Git

Спецификация refname Git (описана в man-странице `git-check-ref-format`) определяет точный набор запрещённых символов и шаблонов. Разобрав правила один раз, вы предотвратите все будущие ошибки именования — неоднозначных случаев нет, когда известен полный список.

Явно запрещённые символы и последовательности

  • Пробел (ASCII 0x20) - самая частая ошибка; используйте вместо него `-` или `_`.
  • Тильда `~` - используется в нотации reflog (`branch~2` означает два коммита до вершины).
  • Циркумфлекс `^` - используется в нотации ревизий (`branch^` означает родительский коммит).
  • Двоеточие `:` - используется в нотации refspec при fetch (`refs/heads/main:refs/heads/main`).
  • Знак вопроса `?` - glob-символ подстановки в шаблонах ref.
  • Звёздочка `*` - glob-символ подстановки в шаблонах ref.
  • Открывающая скобка `[` - открывает glob-набор символов.
  • Обратный слэш `\\` - разделитель путей в Windows; запрещён во избежание кроссплатформенных проблем.
  • Двойная точка `..` - используется в нотации диапазонов (`main..feature`).
  • Последовательность @{ - сокращённая нотация reflog (`branch@{1}` — запись reflog).

Позиционные и структурные правила

  • Не может начинаться с точки (`.`) - конвенция скрытых файлов; `.hidden` — недопустимое начало.
  • Не может заканчиваться точкой (`.`) - двусмысленно с расширением `.lock` и нотацией файловых расширений.
  • Не может заканчиваться на `.lock` - Git использует суффикс `.lock` для lock-файлов; любой компонент пути, заканчивающийся на `.lock`, запрещён.
  • Не может начинаться с дефиса (`-`) - конфликтует с разбором опций командной строки.
  • Не может содержать подряд идущие точки (`..`) - конфликт с нотацией диапазонов (см. выше).
  • Не может быть единственным символом `@` - сокращение для `HEAD`.
  • Не может содержать управляющие символы - ASCII-символы ниже 0x20 и DEL (0x7F) запрещены.
  • Не может быть пустым - пустая строка не является валидным именем.
valid and invalid examples
bash
# ✓ Valid branch names
git checkout -b feature/add-login
git checkout -b fix/null-pointer-123
git checkout -b release/v2.1.0
git checkout -b chore_update-deps
git checkout -b users/alice/experiment

# ✗ Invalid - contains a space
git checkout -b "my feature"
# fatal: 'my feature' is not a valid branch name

# ✗ Invalid - double dot
git checkout -b feature..login
# fatal: 'feature..login' is not a valid branch name

# ✗ Invalid - ends with .lock
git checkout -b release.lock
# fatal: 'release.lock' is not a valid branch name

# ✗ Invalid - starts with hyphen
git checkout -b -hotfix
# fatal: '-hotfix' is not a valid branch name

Tip

Выполните `git check-ref-format --branch предложенное-имя`, чтобы протестировать любое имя до создания ветки. Команда завершается кодом 0, если имя валидно, и 1 — если нет; это удобно в скриптах и pre-commit-хуках. Для проверки в браузере с поддержкой командных конвенций используйте [Валидатор конвенций имён веток](/tools/data/validators/branch-name-convention-validator).

Частые причины и исправления

Большинство появлений этой ошибки вызвано небольшим числом повторяющихся шаблонов. У каждого есть конкретная причина и конкретное однострочное исправление.

Пробелы из скопированных названий задач

Самый частый триггер — копирование названия задачи или story прямо в имя ветки. «Add user login form» превращается в `git checkout -b Add user login form`, Git видит три отдельных аргумента и отклоняет имя ветки `Add`. Исправление: замените каждый пробел дефисом. Многие команды автоматизируют это алиасом или скриптом `branch-from-ticket`, который преобразует название перед передачей в Git. Генератор slug-ов превращает любой текст в чистый slug с дефисами, пригодный для имён веток.

Спецсимволы в интерполяции переменных CI/CD

CI-пайплайны часто строят имена веток из переменных окружения — заголовков PR, сообщений коммитов или ID задач Jira. Если какое-то из этих значений содержит спецсимвол (двоеточие в ID Jira вроде `PROJECT:123` или слэш в semver-теге вроде `v1.0.0/rc.1`), интерполированное имя ветки провалится. Исправление: очищайте ввод перед использованием в качестве имени ветки. Замените неалфанумерные символы дефисами и уберите дефисы и точки в начале и конце.

Точка в конце или суффикс .lock

Имя ветки, оканчивающееся точкой (`feature.`) или на `.lock` (`release.lock`), отклоняется, потому что Git резервирует эти шаблоны для lock-файлов. Ошибка обычно появляется, когда разработчик случайно ставит точку в конце имени или когда скрипт добавляет `.lock` к сгенерированному имени. Исправление: уберите точку в конце или замените `.lock` валидным суффиксом вроде `-locked` или `-pending`.

Невалидный шаблонПримерИсправление
Пробелfeature/add loginfeature/add-login
Двойная точкаfeat..loginfeat/login
Тильдаhotfix~v2hotfix-v2
ДвоеточиеPROJECT:123PROJECT-123
Точка в концеrelease.release
Заканчивается на .lockfix.lockfix-pending
Начинается с дефиса-bugfixbugfix
@ с последующей {user@{branch}user-branch
Обратный слэшfeature\\loginfeature/login

Валидатор конвенций имён веток

Проверяйте имена веток Git по полной спецификации refname и конвенции вашей команды — локально в браузере, мгновенная обратная связь, без настройки.

Open tool

Как переименовать невалидную ветку

В редких случаях — особенно со старыми версиями Git или ветками, созданными сторонними инструментами, — невалидное имя ветки может уже попасть в репозиторий. Современный Git блокирует это при создании, но если вы унаследовали репозиторий с проблемным именем ветки, вот как это исправить.

1

Переименуйте локальную ветку

Выполните `git branch -m old-name new-name`, чтобы переименовать ветку в локальном репозитории. Флаг `-m` перемещает (переименовывает) ссылку ветки, не затрагивая историю коммитов. Если старое имя содержит символы, усложняющие кавычки в вашей оболочке, возьмите его в одинарные кавычки: `git branch -m 'old name with spaces' new-valid-name`.

2

Отправьте новое имя в remote

После локального переименования отправьте новую ветку в remote: `git push origin new-valid-name`. Это создаст новую ветку на remote. Если старая ветка уже была отправлена, коллегам следует обновить локальную отслеживающую ссылку через `git fetch --prune` после того, как вы удалите старую remote-ветку.

3

Удалите старую remote-ветку

Удалите старую remote-ветку: `git push origin --delete old-name`. В GitHub, GitLab и Bitbucket ветки можно переименовать и через веб-интерфейс в списке веток — это безопаснее, когда старое имя содержит символы, которые трудно передать через CLI без экранирования.

4

Обновите открытые pull request-ы

Если у переименованной ветки были открытые PR, большинство платформ (GitHub, GitLab) автоматически обновляют ссылку базовой ветки PR при переименовании через веб-интерфейс. Если переименовали через CLI, проверьте открытые PR и при необходимости вручную обновите ссылку head-ветки. Запуски CI против старого имени ветки тоже придётся перезапустить с новым именем.

Warning

Не переименовывайте ветку, которая является текущей веткой по умолчанию (`main` или `master`), без предварительного обновления настроек репозитория. Переименование ветки по умолчанию без обновления указателя HEAD на remote приведёт к тому, что `git clone` будет проверять не ту ветку по умолчанию во всех последующих клонах.

Правила именования по платформам

Собственные правила refname Git — база. Платформы хостинга накладывают дополнительные ограничения сверху: имя, прошедшее локальную валидацию Git, всё ещё может не пройти при push в GitHub или GitLab. Понимание платформенных правил избавляет от разочарования, когда имя работает локально, но проваливается на remote.

Дополнительные ограничения GitHub

GitHub отклоняет имена веток, оканчивающиеся на `.lock` в любом компоненте пути (не только в последнем сегменте), имена с подряд идущими точками в любой позиции и имена, содержащие нулевой байт. GitHub также ограничивает длину имени ветки 255 байтами. Веб-интерфейс GitHub дополнительно обрезает пробелы в начале и конце имён, созданных через интерфейс.

Дополнительные ограничения GitLab

GitLab добавляет ограничения для шаблонов защищённых веток: имена с подстановочными символами `*` зарезервированы под правила защищённых веток и не могут использоваться как буквальные имена веток. GitLab также резервирует имена, совпадающие с его внутренним namespacing вроде `protected` и `refs`. Имена веток длиннее 255 символов отклоняются. Валидация имён в пайплайне GitLab CI отделена от валидации refname Git — ошибки интерполяции переменных CI проявляются как сбои пайплайна, а не как ошибки Git.

Особенности файловой системы Windows

В Windows каталог `.git/refs/heads/` хранит каждую ветку как файл. Значит, действуют все ограничения имён файлов Windows: имена не могут содержать `<`, `>`, `"`, `|`, `?` или `*`; имена не могут заканчиваться пробелом или точкой; а имена нечувствительны к регистру на NTFS. Нечувствительность к регистру особенно важна в смешанных командах: `Feature/Login` и `feature/login` — одна и та же ветка в Windows, но разные в Linux и macOS.


ПравилоЯдро GitGitHubGitLabФайловая система Windows
Без пробелов✓✓✓✓
Без суффикса .lock✓✓ любой компонент✓✓
Без двойных точек✓✓✓✓
Без начального дефиса✓✓✓✓
Максимум 255 байт✗ (без лимита)✓✓Лимит пути ОС
Нечувствительность к регистру✗✗✗✓ (NTFS)
Без * как буквального имени✓✓✓ зарезервированоN/A

Командные конвенции именования веток

Валидность — это минимум, а не максимум. Имя ветки может быть валидным по правилам Git и при этом оставаться неясным, непоследовательным или непригодным в рабочем процессе команды. Устоявшиеся конвенции добавляют предсказуемость поверх технической валидности: каждый участник команды может прочитать имя ветки и сразу понять её цель, охват и жизненный цикл.

Конвенция Gitflow

Gitflow использует пять типов веток: `main` (продакшен), `develop` (интеграция), `feature/описание`, `release/версия` и `hotfix/описание`. Имена веток строятся из категории-префикса, слэша и описания с дефисами. Release-ветки включают номер версии (`release/1.4.0`). Эту конвенцию хорошо поддерживают большинство GUI-клиентов Git и CI-инструменты, распознающие префиксы как категории веток.

GitHub Flow и trunk-based конвенции

GitHub Flow использует более простую структуру: `main` плюс короткоживущие feature-ветки с описательными именами (`add-oauth-login`, `fix-pagination-bug`). Trunk-based-разработка аналогично использует `main` плюс очень короткоживущие ветки, мержащиеся за часы. Оба подхода предпочитают короткие имена в нижнем регистре с дефисами без категорийных префиксов — предполагается, что имена веток временные, а контекст несут заголовок и описание PR.

Конвенции с ссылкой на задачу

Многие команды добавляют в имя ветки ссылку на задачу: `JIRA-1234-fix-login-bug` или `feat/GH-456-add-dark-mode`. ID задачи обеспечивает трассируемость между веткой и исходным рабочим элементом. Строя такие имена программно, всегда очищайте часть с описанием задачи — в названиях задач часто встречаются двоеточия, слэши и другие символы, ломающие правила именования Git.

Имена веток, как и сообщения коммитов, — это документация. Последовательная конвенция именования превращает список веток в читаемый changelog текущей работы.

- Сообщество Conventional Commits

Профилактика невалидных имён веток

Исправление отдельных ошибок — реактивный подход. Лучше предотвращать создание невалидных имён изначально: через инструменты валидации, интеграции с редакторами и CI-проверки, отлавливающие проблемы до того, как они помешают команде.

Pre-push-хуки Git

Скрипт `.git/hooks/pre-push` выполняется перед любым `git push` и может проверить текущее имя ветки по конвенции команды. Если имя не проходит, хук завершается ненулевым кодом и прерывает push с пояснительным сообщением. Используйте фреймворк `pre-commit`, чтобы равномерно распространять хуки по команде: отдельные файлы `.git/hooks/` не коммитятся в репозиторий, а `.pre-commit-config.yaml` — коммитится.

Валидация имён в CI-пайплайне

Добавьте шаг валидации имени ветки в начало CI-пайплайна. В GitHub Actions используйте ранний шаг job-а, проверяющий имя ветки по regex-шаблону и валиящий workflow при несовпадении. Это ловит имена, технически валидные по Git, но нарушающие конвенцию команды: без типового префикса, слишком длинные или без ссылки на задачу. Валидатор конвенций имён веток применяет ту же логику локально в браузере — удобно проверять имя до создания ветки.

  • Валидируйте локально до создания: используйте Валидатор конвенций имён веток, чтобы проверять имена по правилам Git и командным конвенциям.
  • Используйте скрипт создания веток: небольшая shell-функция, принимающая ID задачи и описание и выдающая корректно отформатированное имя ветки, полностью устраняет ручные ошибки именования.
  • Добавьте pre-push-хук: проверяет имя ветки при каждом push — последняя линия обороны до того, как невалидное имя попадёт на remote.
  • Линтьте в CI: шаг GitHub Actions или GitLab CI, проверяющий имя ветки в каждом PR, не даёт слиться нарушениям конвенции.
  • Документируйте конвенцию в CONTRIBUTING.md: члены команды, знающие правила, ошибаются реже тех, кто угадывает по примерам.

Tip

Строя имена веток из внешних данных (названия задач, сообщения коммитов или ответы API), всегда очищайте данные перед использованием. Надёжный паттерн: привести строку к нижнему регистру, заменить любую последовательность неалфанумерных символов одним дефисом, убрать дефисы в начале и конце и обрезать до 72 символов. Результат всегда валиден как имя ветки Git и соответствует самым распространённым командным конвенциям.

Key takeaways

  • Git проверяет имена веток по спецификации refname и сразу отклоняет имена с пробелами, `..`, `~`, `^`, `:`, `?`, `*`, `[`, `\\`, `@{`, а также имена, начинающиеся/оканчивающиеся точкой или начинающиеся с дефиса.
  • Самая частая причина — копирование названия задачи с пробелами прямо в команду `git checkout -b`: заменяйте пробелы дефисами, прежде чем использовать название как имя ветки.
  • Проверяйте имя командой `git check-ref-format --branch name` в терминале или через Валидатор конвенций имён веток в браузере.
  • Чтобы переименовать существующую ветку: `git branch -m old-name new-name` локально, затем отправьте новое имя и удалите старую remote-ветку командой `git push origin --delete old-name`.
  • Правила платформ расширяют базу Git: GitHub и GitLab отклоняют `.lock` в любом компоненте пути, а NTFS в Windows делает имена веток нечувствительными к регистру — всегда используйте нижний регистр, чтобы избежать кроссплатформенных коллизий.
  • Предотвращайте ошибки системно: pre-push-хук Git, шаг валидации в CI-пайплайне и задокументированная конвенция именования веток в репозитории.
  • Самая безопасная кроссплатформенная конвенция: `тип/нижний-регистр-с-дефисами` (например, `feat/add-login-form`, `fix/null-pointer-auth`).

Частые вопросы

Git validates branch names against its refname specification and rejects any name containing forbidden characters or patterns. The most common triggers are spaces in the branch name, double dots (..), a tilde (~), a caret (^), a colon (:), a question mark (?), an asterisk (*), a backslash (\), or a name that starts or ends with a dot or slash. The error also fires if the name ends with .lock - a suffix Git reserves for lock files.

No. Spaces are explicitly forbidden in Git branch names. Git uses spaces as delimiters in many command outputs and cannot reliably disambiguate a branch name containing a space from two separate arguments. The standard replacement is a hyphen - `feature/user-profile` instead of `feature/user profile`. Underscores also work but hyphens are more widely adopted in open-source conventions. If your CI or CD platform has additional restrictions, check its documentation alongside Git's own refname rules.

Git allows letters (a-z, A-Z), digits (0-9), hyphens (-), underscores (_), forward slashes (/) for hierarchical namespaces (e.g. feature/login), and dots (.) within the name but not at the start or end. Most other characters are either forbidden or context-dependent. The safest convention is `lowercase-with-hyphens` or `type/lowercase-with-hyphens` (e.g. `feat/add-login-form`). Validate any unconventional branch name with the Branch Name Convention Validator before creating it.

Use `git branch -m old-name new-name` to rename a local branch. If the branch is already pushed to a remote, rename locally first, then push the new name with `git push origin new-name` and delete the old remote branch with `git push origin --delete old-name`. On GitHub, GitLab, and Bitbucket, you can also rename branches through the web UI - useful if the remote branch name itself contains characters that make CLI deletion awkward.

Older Git versions (before 2.x) had less strict local name validation and would sometimes allow creating a branch locally that was then rejected by the remote. Modern Git validates refnames at creation time, but edge cases can occur when names are constructed programmatically or passed through shell interpolation. Remote hosts like GitHub also apply additional restrictions (no consecutive dots, no names ending in .lock at any path component) that the local Git client does not enforce.

The combination @{ is forbidden in Git branch names because it is the syntax for the reflog shorthand - `branch@{n}` refers to the nth entry in a branch's reflog. Allowing @{ in a branch name would create an ambiguity between the branch itself and a reflog reference. This restriction is often encountered when developers try to use ticket IDs or timestamps that include the @ symbol followed by a brace in a branch name. Replace @ with a hyphen or remove it entirely.

Git itself is case-sensitive on Linux and macOS but case-insensitive on Windows filesystems, which means `Feature/Login` and `feature/login` are the same branch on Windows but different branches on Linux. Using lowercase throughout prevents confusing case-collision bugs when teams work across different operating systems. Most popular conventions (Gitflow, GitHub Flow, Trunk-Based Development) specify lowercase branch names, and most CI systems enforce it as a linting rule.

Git does not impose a hard character limit on branch names from the specification side, but practical limits exist. The underlying filesystem has path length constraints - on Windows, the default maximum path length is 260 characters, which includes the .git directory path and the refs/heads/ prefix. Long branch names also become impractical to type and read. Most teams enforce a soft limit of 50-72 characters as a convention. The Branch Name Convention Validator checks your name against both Git rules and configurable length limits.

ShareXLinkedIn