¿Qué hace Verificación previa de GitHub?
Hacer push de un nuevo repositorio falla de un puñado de formas aburridas y repetibles, y los mensajes de error apuntan a lo incorrecto. src refspec main does not match any suena a un problema de rama pero normalmente significa que no hay commits. Un push que silenciosamente tiene éxito bajo una cuenta de trabajo se ve idéntico a uno que tuvo éxito correctamente. Esta habilidad encuentra esos problemas antes de que el usuario queme un push en ellos.
La regla rectora: diagnosticar, no mutar. Reporta hallazgos y devuelve comandos de corrección para copiar y pegar. El usuario los ejecuta. Las personas mantienen múltiples cuentas precisamente porque les importa cuál actúa, así que ejecutar silenciosamente git config o git remote set-url en su nombre es exactamente el instinto equivocado aquí.
Cómo ejecutarlo
bash <directorio-skill>/scripts/preflight.sh [ruta-repo] [nombre-remoto]
Ambos argumentos son opcionales: por defecto usan el directorio actual y origin. El script solo lee: git config --get, ls-remote, ssh -T, push --dry-run. Nunca escribe.
Si el script no se puede ejecutar por alguna razón, las comprobaciones siguientes son cada una de una línea; ejecútalas directamente e interprétalas de la misma manera.
Qué significan las comprobaciones
El script imprime líneas PASS / WARN / FAIL. La interpretación importa más que la salida bruta, así que traduce en lugar de pegar:
Repo / archivos / commits. Un directorio vacío o un repo sin commits produce src refspec <rama> does not match any al hacer push. Git no puede construir un commit de la nada. Esta es la causa más común de un primer push fallido, así que encabeza con ella cuando ocurra.
Rama. Un git init fresco puede caer en master mientras que el remoto espera main. Renombrar es seguro después del primer commit (git branch -M main) — en una rama no nacida no hay nada que renombrar todavía, por eso ordenar los comandos incorrectamente desperdicia un ciclo.
URL remota efectiva. Vale la pena saberla con precisión, porque es fácil comprobarlo mal: git remote get-url ya expande url.<base>.insteadOf, al igual que git ls-remote --get-url. Comparar ambos por lo tanto no detecta nada. El valor bruto solo sobrevive en git config --get remote.<nombre>.url, así que eso es lo que el script compara contra git remote get-url --push (la forma --push además cubre pushurl y pushInsteadOf, que es lo que realmente usa un push). Cuando los dos difieren, la URL configurada por el usuario no es la que Git contactará. La trampa clásica es un url."https://github.com/".insteadOf = [email protected]: global, que redirige silenciosamente SSH a HTTPS y por lo tanto a la cuenta que tenga el helper de credenciales — a menudo no la que el usuario pretendía. Siempre reporta la URL efectiva y señala la diferencia explícitamente.
Cuenta autenticada. Para SSH, el script resuelve el host a través de ssh -G (para que alias de host como github-personal se sigan hasta su nombre de host real y clave) y luego pregunta a GitHub directamente con ssh -T. GitHub responde Hi <usuario>! y sale con 1 — la salida 1 es el caso de éxito aquí, no un fallo. Para HTTPS lee la cuenta gh activa. Compara esa cuenta contra el segmento propietario de la URL: una discrepancia significa que el push dará 403, o caerá en el espacio de nombres equivocado.
Identidad del commit. user.email heredado de la configuración global es el fallo silencioso. El push se autentica como una cuenta mientras que cada commit se autoría bajo otra dirección — y arreglarlo después implica enmendar o reescribir la historia. Trata una identidad de ámbito global en un repo cuyo remoto pertenece a un propietario diferente como un WARN que vale la pena resaltar, aunque técnicamente nada esté roto todavía.
Estado del remoto. Remoto vacío significa que el primer push está limpio. Referencias existentes significan que un push simple será rechazado como no-avance-rápido y el usuario necesita hacer pull/rebase primero — di eso antes de que se encuentren con el rechazo. Un error aquí normalmente significa que el repo no existe o la cuenta carece de acceso; GitHub reporta deliberadamente ambos como "no encontrado", así que ofrece ambas explicaciones en lugar de adivinar.
Push de prueba (dry-run). Solo es posible una vez que existe un commit. Esta es la comprobación real de extremo a extremo — ejercita la autenticación y la negociación de referencias sin escribir. Ten en cuenta su punto ciego: no detectará rechazos del lado del servidor como GH007 (privacidad de email), porque esos se evalúan en la recepción real.
Informe
Da una tabla corta de comprobaciones, luego — solo para las cosas que fallaron o advirtieron — los comandos exactos para arreglarlas, en orden ejecutable. No vomites comprobaciones exitosas como prosa; el usuario quiere saber qué está mal y qué escribir.
Cuando la identidad necesite establecerse, prefiere la configuración local del repo sobre tocar la global, ya que el punto es que este repo difiere del valor por defecto de la máquina:
git config user.name "<cuenta>"
git config user.email "<email>"
Si varios repos necesitan el mismo tratamiento, menciona includeIf como la solución duradera:
[includeIf "gitdir:~/personal/"]
path = ~/.gitconfig-personal
Y si el push es rechazado con GH007, apunta a la dirección @users.noreply.github.com desde GitHub → Configuración → Correos electrónicos en lugar de adivinar una dirección personal — los comentarios clave y la configuración local son etiquetas, no prueba de lo que la cuenta acepta.