Pré-voo GitHub
Fazer push de um novo repositório falha de algumas maneiras chatas e repetitivas, e as mensagens de erro apontam para a coisa errada. src refspec main does not match any parece um problema de branch, mas geralmente significa que não há commits. Um push que tem sucesso silenciosamente com uma conta de trabalho parece idêntico a um que teve sucesso corretamente. Esta skill encontra esses problemas antes que o usuário desperdice um push com eles.
A regra principal: diagnosticar, não modificar. Relate os achados e forneça comandos de correção para copiar e colar. O usuário os executa. As pessoas mantêm múltiplas contas precisamente porque se importam com qual delas age, então executar silenciosamente git config ou git remote set-url em nome delas é exatamente o instinto errado aqui.
Executando
bash <skill-dir>/scripts/preflight.sh [caminho-do-repo] [nome-remoto]
Ambos os argumentos são opcionais — eles usam como padrão o diretório atual e origin. O script apenas lê: git config --get, ls-remote, ssh -T, push --dry-run. Ele nunca escreve.
Se o script não puder ser executado por algum motivo, as verificações abaixo são cada uma de uma linha; execute-as diretamente e interprete-as da mesma forma.
O que as verificações significam
O script imprime linhas PASS / WARN / FAIL. A interpretação importa mais do que a saída bruta, então traduza em vez de colar:
Repo / arquivos / commits. Um diretório vazio ou um repositório sem commits produz src refspec <branch> does not match any na hora do push. O Git não pode construir um commit a partir do nada. Esta é a causa mais comum de um primeiro push falho, então comece com ela quando ocorrer.
Branch. Um git init novo pode resultar em master enquanto o remoto espera main. Renomear é seguro após o primeiro commit (git branch -M main) — em um branch não nascido ainda não há nada para renomear, e é por isso que ordenar os comandos de forma errada desperdiça um ciclo.
URL remota efetiva. Vale a pena saber com precisão, porque é fácil verificar isso errado: git remote get-url já expande url.<base>.insteadOf, assim como git ls-remote --get-url. Comparar esses dois, portanto, não detecta nada. O valor bruto sobrevive apenas em git config --get remote.<name>.url, então é isso que o script compara com git remote get-url --push (a forma --push adicionalmente cobre pushurl e pushInsteadOf, que é o que um push realmente usa). Quando os dois diferem, a URL configurada pelo usuário não é a que o Git contatará. A armadilha clássica é um url."https://github.com/".insteadOf = [email protected]: global, que redireciona silenciosamente SSH para HTTPS e, portanto, para qualquer conta que o auxiliar de credenciais detenha — muitas vezes não a que o usuário pretendia. Sempre relate a URL efetiva e sinalize a diferença explicitamente.
Conta autenticadora. Para SSH, o script resolve o host através de ssh -G (para que aliases de host como github-pessoal sejam seguidos até seu nome de host real e chave) e então pergunta diretamente ao GitHub com ssh -T. O GitHub responde Hi <usuário>! e sai com 1 — saída 1 é o caso de sucesso aqui, não uma falha. Para HTTPS, ele lê a conta gh ativa. Compare essa conta com o segmento de proprietário da URL: uma incompatibilidade significa que o push resultará em 403 ou cairá no namespace errado.
Identidade do commit. user.email herdado da configuração global é a falha silenciosa. O push autentica como uma conta enquanto cada commit é autoral sob outro endereço — e corrigir isso depois significa alterar ou reescrever o histórico. Trate uma identidade de escopo global em um repositório cujo remoto pertence a um proprietário diferente como um WARN que vale a pena levantar proeminentemente, mesmo que nada esteja tecnicamente quebrado ainda.
Estado remoto. Remoto vazio significa que o primeiro push está limpo. Referências existentes significam que um push simples será rejeitado como não-fast-forward e o usuário precisa fazer pull/rebase primeiro — diga isso antes de eles encontrarem a rejeição. Um erro aqui geralmente significa que o repositório não existe ou a conta não tem acesso; o GitHub relata deliberadamente ambos como "não encontrado", então ofereça ambas as explicações em vez de adivinhar.
Push de simulação (dry-run). Só é possível após existir um commit. Esta é a verificação real de ponta a ponta — ela exercita autenticação e negociação de referência sem escrever. Observe seu ponto cego: ela não pegará rejeições do lado do servidor como GH007 (privacidade de email), porque essas são avaliadas no recebimento real.
Relatando
Forneça uma pequena tabela de verificações e, então — apenas para as coisas que falharam ou emitiram aviso — os comandos exatos para corrigi-las, em ordem executável. Não despeje verificações aprovadas como prosa; o usuário quer saber o que está errado e o que digitar.
Quando a identidade precisar ser configurada, prefira configuração local do repositório em vez de tocar na global, já que o objetivo é que este repositório difira do padrão da máquina:
git config user.name "<conta>"
git config user.email "<email>"
Se vários repositórios precisarem do mesmo tratamento, mencione includeIf como a correção durável:
[includeIf "gitdir:~/pessoal/"]
path = ~/.gitconfig-pessoal
E se o push for rejeitado com GH007, aponte para o endereço @users.noreply.github.com de GitHub → Configurações → Emails em vez de adivinhar um endereço pessoal — comentários de chave e configuração local são rótulos, não prova do que a conta aceita.