El error de Git "is not a valid branch name" es preciso: el nombre que indicaste viola una o más de las reglas de refname de Git. La corrección casi siempre es un cambio de una línea una vez que sabes qué carácter o patrón lo provocó. Esta guía cubre el conjunto completo de restricciones de nombres de Git, las causas más comunes con correcciones exactas, cómo renombrar una rama que ya existe y cómo hacer cumplir la nomenclatura válida en todo tu equipo antes de que alguien se tope con el error.
Qué significa el error
Cuando Git informa `fatal: 'some-name' is not a valid branch name`, significa que la cadena que pasaste como nombre de rama viola la especificación de refname de Git: el conjunto de reglas que gobiernan qué constituye un nombre de referencia válido en un repositorio Git. Git usa las mismas reglas para nombres de ramas, etiquetas y nombres de seguimiento remoto, porque todos se almacenan como referencias en el directorio `.git/refs/`.
La validación ocurre antes de que se escriba cualquier objeto. Git pasa tu nombre propuesto por `check_refname_format()` internamente y aborta con el error si el nombre falla. Esto significa que ves el error de inmediato al ejecutar `git checkout -b`, `git branch` o `git switch -c`: no hay estado parcial que limpiar.
Dónde aparece el error
- `git checkout -b branch-name` - crear una nueva rama y cambiar a ella
- `git branch branch-name` - crear una nueva rama sin cambiar
- `git switch -c branch-name` - el equivalente moderno de checkout -b
- `git push origin branch-name` - hacer push a un remoto con un nombre local inválido
- Scripts de CI/CD - cuando un nombre de rama se construye programáticamente desde un ID de ticket o mensaje de commit
Note
Reglas de nomenclatura de ramas en Git
La especificación de refname de Git (definida en la página man de `git-check-ref-format`) describe un conjunto preciso de caracteres y patrones prohibidos. Aprender las reglas una vez previene todos los errores de nombres futuros: no hay casos ambiguos una vez conoces la lista completa.
Caracteres y secuencias explícitamente prohibidos
- Espacio (ASCII 0x20) - el error más común; usa `-` o `_` en su lugar.
- Tilde `~` - usada en la notación de reflog (`branch~2` significa dos commits antes de la punta).
- Circunflejo `^` - usado en la notación de revisión (`branch^` significa el commit padre).
- Dos puntos `:` - usados en la notación de refspec de fetch (`refs/heads/main:refs/heads/main`).
- Signo de interrogación `?` - comodín glob en patrones de refs.
- Asterisco `*` - comodín glob en patrones de refs.
- Corchete de apertura `[` - apertura de conjunto de caracteres glob.
- Barra invertida `\\` - separador de rutas en Windows; prohibida para evitar problemas multiplataforma.
- Doble punto `..` - usado en la notación de rangos (`main..feature`).
- Secuencia @{ - notación abreviada de reflog (`branch@{1}` es una entrada de reflog).
Reglas posicionales y estructurales
- No puede empezar por punto (`.`) - convención de archivos ocultos; `.hidden` no es un inicio válido.
- No puede terminar en punto (`.`) - ambiguo con la extensión `.lock` y la notación de extensiones de archivo.
- No puede terminar en `.lock` - Git usa el sufijo `.lock` para archivos de bloqueo; cualquier componente de ruta que termine en `.lock` está prohibido.
- No puede empezar por guion (`-`) - entra en conflicto con el análisis de opciones de línea de comandos.
- No puede contener puntos consecutivos (`..`) - conflicto con la notación de rangos (ver arriba).
- No puede ser el carácter único `@` - abreviatura de `HEAD`.
- No puede contener caracteres de control - los caracteres ASCII por debajo de 0x20 y DEL (0x7F) están prohibidos.
- No puede estar vacío - una cadena vacía no es un nombre válido.
# ✓ 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 nameTip
Causas comunes y correcciones
La mayoría de las veces este error proviene de un pequeño número de patrones que se repiten. Cada uno tiene una causa específica y una corrección específica de una línea.
Espacios por títulos de ticket copiados y pegados
El desencadenante más común es copiar un título de ticket o historia directamente en el nombre de la rama. "Add user login form" se convierte en `git checkout -b Add user login form`, que Git interpreta como tres argumentos separados y rechaza el nombre de rama `Add`. Corrección: reemplaza cada espacio por un guion. Muchos equipos lo automatizan con un alias o script `branch-from-ticket` que transforma el título antes de pasarlo a Git. El Generador de Slugs convierte cualquier texto en un slug limpio separado por guiones apto para nombres de rama.
Caracteres especiales en la interpolación de variables de CI/CD
Los pipelines de CI a menudo construyen nombres de ramas desde variables de entorno - títulos de PR, mensajes de commit o IDs de tickets de Jira. Si alguno de esos valores contiene un carácter especial (dos puntos en un ID de Jira como `PROJECT:123`, o una barra en una etiqueta semver como `v1.0.0/rc.1`), el nombre de rama interpolado fallará. Corrección: sanea la entrada antes de usarla como nombre de rama. Reemplaza los caracteres no alfanuméricos por guiones y recorta los guiones y puntos al inicio y al final.
Punto final o sufijo .lock
Un nombre de rama que termina en punto (`feature.`) o termina en `.lock` (`release.lock`) falla porque Git reserva estos patrones para archivos de bloqueo. Este error suele aparecer cuando un desarrollador escribe un nombre que acaba en punto por accidente, o cuando un script añade `.lock` como parte de un nombre generado. Corrección: elimina el punto final, o reemplaza `.lock` por un sufijo válido como `-locked` o `-pending`.
| Patrón inválido | Ejemplo | Corrección |
|---|---|---|
| Espacio | feature/add login | feature/add-login |
| Doble punto | feat..login | feat/login |
| Tilde | hotfix~v2 | hotfix-v2 |
| Dos puntos | PROJECT:123 | PROJECT-123 |
| Punto final | release. | release |
| Termina en .lock | fix.lock | fix-pending |
| Empieza por guion | -bugfix | bugfix |
| @ seguido de { | user@{branch} | user-branch |
| Barra invertida | feature\\login | feature/login |
Validador de Convención de Nombres de Rama
Valida nombres de ramas Git contra la especificación completa de refname y la convención de tu equipo - local en el navegador, feedback instantáneo, sin configuración.
Cómo renombrar una rama inválida
En casos raros - en particular con versiones antiguas de Git o ramas creadas mediante herramientas de terceros - puedes acabar con un nombre de rama inválido ya confirmado en tu repositorio. El Git moderno lo previene en el momento de creación, pero si heredas un repositorio con un nombre de rama problemático, así se corrige.
Renombra la rama local
Ejecuta `git branch -m old-name new-name` para renombrar la rama en tu repositorio local. La opción `-m` mueve (renombrando) la referencia de la rama sin tocar el historial de commits. Si el nombre antiguo contiene caracteres que complican las comillas en tu shell, usa comillas simples: `git branch -m 'old name with spaces' new-valid-name`.
Haz push del nuevo nombre al remoto
Tras renombrar localmente, haz push de la nueva rama al remoto: `git push origin new-valid-name`. Esto crea la nueva rama en el remoto. Si la rama antigua ya se había subido, tus compañeros deben actualizar su referencia de seguimiento local con `git fetch --prune` después de que elimines la rama remota antigua.
Elimina la rama remota antigua
Elimina la rama remota antigua: `git push origin --delete old-name`. En GitHub, GitLab y Bitbucket también puedes renombrar ramas desde la interfaz web en la lista de ramas: es la opción más segura cuando el nombre antiguo contiene caracteres difíciles de pasar por la CLI sin escapar.
Actualiza los pull requests abiertos
Si la rama renombrada tenía pull requests abiertos, la mayoría de plataformas (GitHub, GitLab) actualizan automáticamente la referencia de la rama base del PR al renombrar desde la interfaz web. Si renombraste por CLI, revisa tus PR abiertos y actualiza manualmente la referencia de la rama head si es necesario. Las ejecuciones de CI contra el nombre antiguo de la rama también tendrán que relanzarse contra el nombre nuevo.
Warning
Reglas de nombres específicas por plataforma
Las reglas de refname del propio Git son la base. Las plataformas de hospedaje remoto aplican restricciones adicionales por encima: un nombre que supera la validación local de Git puede seguir fallando al hacer push a GitHub o GitLab. Entender las reglas específicas de cada plataforma evita la frustración de un nombre que funciona localmente pero falla en remoto.
Restricciones adicionales de GitHub
GitHub rechaza nombres de ramas que terminen en `.lock` en cualquier componente de ruta (no solo el segmento final), nombres que contengan puntos consecutivos en cualquier posición y nombres que contengan un byte nulo. GitHub también impone una longitud máxima de nombre de rama de 255 bytes. Además, la interfaz web de GitHub recorta los espacios en blanco al inicio y al final de los nombres creados desde la interfaz.
Restricciones adicionales de GitLab
GitLab añade restricciones para los patrones de ramas protegidas: los nombres que contengan comodines `*` están reservados para las reglas de ramas protegidas y no pueden usarse como nombres literales de rama. GitLab también reserva nombres que coincidan con su namespacing interno como `protected` y `refs`. Se rechazan los nombres de rama de más de 255 caracteres. La validación de nombres en el pipeline de GitLab CI es independiente de la validación de refname de Git: los errores de interpolación de variables de CI aparecen como fallos de pipeline, no como errores de Git.
Consideraciones del sistema de archivos de Windows
En Windows, el directorio `.git/refs/heads/` guarda cada rama como un archivo. Esto significa que aplican todas las restricciones de nombres de archivo de Windows: los nombres no pueden contener `<`, `>`, `"`, `|`, `?` ni `*`; no pueden terminar en espacio o punto; y los nombres son insensibles a mayúsculas en NTFS. El tema de la insensibilidad a mayúsculas es especialmente importante en equipos mixtos: `Feature/Login` y `feature/login` son la misma rama en Windows pero ramas distintas en Linux y macOS.
| Regla | Núcleo Git | GitHub | GitLab | Sistema de archivos Windows |
|---|---|---|---|---|
| Sin espacios | ✓ | ✓ | ✓ | ✓ |
| Sin sufijo .lock | ✓ | ✓ cualquier componente | ✓ | ✓ |
| Sin puntos dobles | ✓ | ✓ | ✓ | ✓ |
| Sin guion inicial | ✓ | ✓ | ✓ | ✓ |
| Máximo 255 bytes | ✗ (sin límite) | ✓ | ✓ | Límite de ruta del SO |
| Insensible a mayúsculas | ✗ | ✗ | ✗ | ✓ (NTFS) |
| Sin * como nombre literal | ✓ | ✓ | ✓ reservado | N/A |
Convenciones de nombres de ramas por equipo
Válido es el suelo, no el techo. Un nombre de rama puede ser válido según las reglas de Git y aun así resultar confuso, inconsistente o inutilizable en el flujo de trabajo de tu equipo. Las convenciones establecidas añaden previsibilidad sobre la validez técnica: cada miembro del equipo puede leer un nombre de rama y entender de inmediato su propósito, alcance y ciclo de vida.
Convención Gitflow
Gitflow usa cinco tipos de ramas: `main` (producción), `develop` (integración), `feature/descripción`, `release/versión` y `hotfix/descripción`. Los nombres usan la categoría como prefijo seguido de una barra y una descripción separada por guiones. Las ramas de release incluyen el número de versión (`release/1.4.0`). Esta convención está bien soportada por la mayoría de clientes GUI de Git y herramientas de CI, que reconocen los prefijos como categorías de rama.
GitHub Flow y convenciones basadas en trunk
GitHub Flow usa una estructura más simple: `main` más ramas de feature de vida corta con nombres descriptivos (`add-oauth-login`, `fix-pagination-bug`). El desarrollo basado en trunk usa igualmente `main` más ramas muy efímeras que se fusionan en cuestión de horas. Ambos enfoques prefieren nombres cortos, en minúsculas y separados por guiones sin prefijos de categoría: la suposición es que los nombres de rama son temporales y el título y la descripción del PR llevan el contexto.
Convenciones con referencia de ticket
Muchos equipos anteponen a los nombres de rama una referencia de ticket: `JIRA-1234-fix-login-bug` o `feat/GH-456-add-dark-mode`. El ID del ticket proporciona trazabilidad entre la rama y el elemento de trabajo originario. Al construir estos nombres de forma programática, sanea siempre la parte de descripción del ticket: los títulos suelen contener dos puntos, barras y otros caracteres que rompen las reglas de nombres de Git.
Los nombres de rama, como los mensajes de commit, son documentación. Una convención de nombres consistente convierte tu lista de ramas en un changelog legible del trabajo en curso.
Prevenir nombres de ramas inválidos
Corregir errores uno a uno es reactivo. El mejor enfoque es impedir que se creen nombres inválidos desde el principio: mediante herramientas de validación, integraciones del editor y comprobaciones de CI que atrapen los problemas antes de que perturben al equipo.
Hooks de pre-push de Git
Un script `.git/hooks/pre-push` se ejecuta antes de cualquier `git push` y puede validar el nombre de la rama actual contra la convención de tu equipo. Si el nombre falla, el hook termina con código distinto de cero y aborta el push con un mensaje explicativo. Usa el framework `pre-commit` para distribuir los hooks de forma consistente en el equipo: los archivos individuales `.git/hooks/` no se confirman al repositorio, pero un `.pre-commit-config.yaml` sí.
Validación de nombres en el pipeline de CI
Añade un paso de validación de nombre de rama al inicio de tu pipeline de CI. Para GitHub Actions, usa un paso temprano del job que compruebe el nombre de la rama contra un patrón regex y falle el workflow si no coincide. Esto atrapa nombres técnicamente válidos según Git pero que violan la convención del equipo: nombres sin prefijo de tipo, demasiado largos o sin referencia de ticket. El Validador de Convención de Nombres de Rama aplica esta misma lógica localmente en tu navegador, útil para comprobar un nombre antes de crear la rama.
- Valida localmente antes de crear: usa el Validador de Convención de Nombres de Rama para comprobar nombres contra las reglas de Git y las convenciones del equipo.
- Usa un script de creación de ramas: una pequeña función de shell que toma un ID de ticket y una descripción y produce un nombre correctamente formateado elimina por completo los errores manuales de nomenclatura.
- Añade un hook de pre-push: valida el nombre de la rama en cada push - la última línea de defensa antes de que un nombre inválido llegue al remoto.
- Lintea en CI: un paso de GitHub Actions o GitLab CI que valida el nombre de la rama en cada PR evita que se fusionen violaciones de la convención.
- Documenta la convención en CONTRIBUTING.md: los miembros del equipo que conocen las reglas cometen menos errores que quienes adivinan a partir de ejemplos.
Tip
Key takeaways
- Git valida los nombres de rama contra su especificación de refname y rechaza de inmediato los nombres con espacios, `..`, `~`, `^`, `:`, `?`, `*`, `[`, `\\`, `@{`, o los que empiezan/terminan en punto o empiezan por guion.
- La causa más común es pegar un título de ticket con espacios directamente en un comando `git checkout -b` - reemplaza los espacios por guiones antes de usar cualquier título como nombre de rama.
- Usa `git check-ref-format --branch name` en la línea de comandos para probar un nombre, o el Validador de Convención de Nombres de Rama en el navegador.
- Para renombrar una rama existente: `git branch -m old-name new-name` localmente, luego haz push del nuevo nombre y elimina la rama remota antigua con `git push origin --delete old-name`.
- Las reglas de las plataformas amplían la base de Git: GitHub y GitLab rechazan `.lock` en cualquier componente de ruta, y Windows NTFS hace los nombres de rama insensibles a mayúsculas - usa siempre minúsculas para evitar colisiones multiplataforma.
- Previene errores de forma sistemática con un hook de pre-push de Git, un paso de validación en el pipeline de CI y una convención de nombres documentada en tu repositorio.
- La convención multiplataforma más segura: `tipo/minúsculas-con-guiones` (por ejemplo `feat/add-login-form`, `fix/null-pointer-auth`).