Tutorial

git push: como enviar alterações para o repositório remoto

Atualizado: · Skillaria.Top

O git push envia os commits locais da branch atual para o repositório remoto e move o ponteiro da branch lá. Na primeira vez, publique a branch com git push -u origin nome-da-branch; depois basta git push. Se o servidor tiver commits de outras pessoas, traga-os primeiro com git pull em vez de usar force push.

O que o git push faz

O comando git push pega os commits da sua branch local que ainda não estão no servidor, envia-os para o repositório remoto (normalmente chamado origin) e move lá o ponteiro da branch para o seu último commit. Os arquivos da pasta de trabalho e as alterações não commitadas não vão a lugar nenhum: só o histórico, ou seja, os commits, é enviado.

É importante entender que push não é "sincronização". Ele funciona em um único sentido: do repositório local para o remoto. Para receber as alterações dos outros, você precisa de git fetch ou git pull. Confundir essas direções é a origem de quase todos os problemas que os iniciantes levam ao mentor.

Outra regra do Git: por padrão, o push só é aceito como "avanço rápido" (fast-forward). O servidor aceita seus commits se eles continuarem o histórico que já existe lá. Se alguém enviou commits antes de você, seu push será rejeitado — e isso é uma proteção, não um bug.

Sintaxe do comando

git push [<remote>] [<branch-local>[:<branch-remota>]]

Se você chamar git push sem argumentos, o Git pega a branch atual e envia para a branch definida como upstream (rastreada). A forma explícita é útil quando o upstream ainda não foi configurado ou quando você quer enviar a branch com outro nome:

git push origin main                  # envia a main local para origin/main
git push origin feature/login         # envia a branch feature/login
git push origin fix:hotfix-123        # envia a fix local como hotfix-123 no servidor
git push origin HEAD                  # envia a branch atual com o mesmo nome

Como enviar alterações pela primeira vez

O caminho típico de um projeto novo até o código no GitHub ou GitLab é este. Primeiro você cria um repositório vazio no servidor, depois conecta o repositório local a ele e envia a branch.

git init
git add .
git commit -m "Primeiro commit"
git branch -M main
git remote add origin git@github.com:user/project.git
git push -u origin main

A flag -u (forma longa --set-upstream) liga a branch local main à remota origin/main. A partir daí, basta escrever git push e git pull nessa branch, e o git status passa a mostrar quantos commits você está à frente ou atrás do servidor.

Para conferir para onde o remote aponta, use git remote -v. Se o endereço estiver errado, corrija com git remote set-url origin <novo-endereco>, em vez de apagar e criar o repositório de novo.

Como enviar uma branch nova

Você criou uma branch para a tarefa, fez commits e roda git push. O Git responde:

fatal: The current branch feature/login has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/login

Isso não é um erro, é uma dica: a branch ainda não tem par no servidor. Rode o comando sugerido ou a forma curta git push -u origin feature/login. Para o Git fazer isso automaticamente com todas as branches novas, ative a configuração (disponível a partir do Git 2.37):

git config --global push.autoSetupRemote true

Por que o git push foi rejeitado: rejected, non-fast-forward

A situação mais comum no trabalho em equipe:

! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:user/project.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally.

Um colega enviou commits antes de você. Seu histórico e o do servidor divergiram, e se o Git aceitasse seu push, os commits do colega se perderiam. A solução correta é primeiro trazer as alterações e encaixar as suas sobre elas:

git pull --rebase       # traz os commits dos outros e reaplica os seus por cima
# em caso de conflito: corrija os arquivos, git add, git rebase --continue
git push

Em vez de --rebase, você pode fazer um git pull normal — aí surge um commit de merge. As duas opções são corretas; a maioria dos times prefere rebase para os commits locais, para manter o histórico linear. O principal é não "resolver" a rejeição com --force.

git push --force e --force-with-lease

O envio forçado é necessário quando você reescreveu conscientemente o histórico da sua branch: fez git commit --amend, git rebase ou juntou commits antes do review. O push normal não aceita essa branch, porque os commits antigos no servidor já não são ancestrais dos novos.

git push --force-with-lease

O --force-with-lease sobrescreve a branch no servidor apenas se ela estiver onde o seu Git local a viu pela última vez (pela referência origin/<branch>). Se um colega tiver enviado algo nesse meio-tempo, o comando recusa, e você não apaga o trabalho dele. O --force comum (-f) não faz essa checagem e sobrescreve tudo silenciosamente.

Há um detalhe: se você rodar git fetch logo antes, a referência origin/<branch> é atualizada e a proteção deixa de funcionar — o Git vai entender que você "viu" os commits dos outros. Por isso, não faça fetch logo antes do force push sem olhar o que chegou.

ComandoO que fazQuando usar
git pushSó fast-forwardSempre, por padrão
git push --force-with-leaseSobrescreve com verificaçãoNa sua branch, depois de rebase ou amend
git push --forceSobrescreve sem verificaçãoQuase nunca; nunca em branches compartilhadas

Em branches compartilhadas (main, develop) não se faz push forçado: para todo mundo que já baixou o histórico antigo, ele vai divergir do servidor. Normalmente essas branches também são protegidas nas configurações do repositório, e o servidor devolve protected branch hook declined.

Como enviar tags

O git push comum não envia tags. É preciso enviá-las explicitamente:

git tag -a v1.2.0 -m "Release 1.2.0"
git push origin v1.2.0          # uma tag
git push --tags                 # todas as tags locais
git push --follow-tags          # commits e as tags anotadas que apontam para eles

O --follow-tags é mais prático que o --tags: ele não envia tags leves locais criadas por acaso, só as anotadas e só as alcançáveis a partir dos commits enviados.

Como apagar uma branch no servidor

A exclusão também é feita via push:

git push origin --delete feature/login
# sintaxe antiga, faz a mesma coisa:
git push origin :feature/login

A branch local continua existindo; para removê-la, use git branch -d feature/login. E os colegas ainda vão ter a referência origin/feature/login até rodarem git fetch --prune.

Flags úteis do git push

FlagPara que serve
-u, --set-upstreamRegistrar a branch remota como upstream
-n, --dry-runMostrar o que seria enviado, sem enviar nada
--allEnviar todas as branches locais
--tags / --follow-tagsEnviar tags
-d, --deleteApagar uma branch ou tag no servidor
--force-with-leaseReescrita segura do histórico
-v, --verboseSaída detalhada
--no-verifyPular o hook pre-push (use com consciência)

Erros comuns no git push e como resolver

Permission denied (publickey)

O servidor não aceitou sua chave SSH. Verifique se a chave existe (ls ~/.ssh), se a parte pública foi adicionada à conta e se a conexão funciona: ssh -T git@github.com. Se o remote estiver configurado via HTTPS, o Git vai pedir usuário e token, não a chave — confira com git remote -v.

Authentication failed via HTTPS

O GitHub e muitos outros serviços há tempos não aceitam a senha da conta via HTTPS. Você precisa de um token de acesso pessoal ou migrar para SSH. Para guardar o token, use um credential helper: git config --global credential.helper store (guarda em texto puro) ou o gerenciador de credenciais do seu sistema operacional.

src refspec main does not match any

Não existe branch com esse nome na sua máquina. Na maioria das vezes, o repositório vazio ainda não tem nenhum commit ou a branch se chama master. Confira com git branch e faça um commit ou renomeie a branch: git branch -M main.

Everything up-to-date, mesmo havendo alterações

Você esqueceu de commitar. O git push envia commits, não arquivos. Rode git status, depois git add e git commit. Outra possibilidade: você não está na branch que espera ver no servidor.

Arquivo grande demais

Os serviços limitam o tamanho dos arquivos (no GitHub, 100 MB). Se esse arquivo já entrou no histórico, não basta removê-lo num novo commit: é preciso reescrever o histórico ou tirá-lo dos commits ainda não enviados (git reset --soft e depois commitar de novo). Para arquivos binários grandes, use Git LFS.

Ciclo de trabalho com git push

  1. git switch -c feature/x — uma branch para a tarefa.
  2. Commits em passos lógicos pequenos.
  3. git fetch e git rebase origin/main — trazer a branch principal atualizada.
  4. git push -u origin feature/x — publicar a branch.
  5. Abrir o pull request; depois do review, commits adicionais e um git push normal.
  6. Se precisar reescrever o histórico — git push --force-with-lease.

Antes de enviar, vale ver o que exatamente vai para o servidor: git log origin/main..HEAD --oneline mostra os commits que ainda não estão lá.

O que configurar uma vez só

Algumas configurações globais evitam a maioria das surpresas no envio. O push.default define o que o git push sem argumentos envia. O padrão nas versões atuais é simple: só a branch atual é enviada, e só para a branch upstream de mesmo nome. Em geral não é preciso mudar, mas vale conferir se não sobrou um matching numa configuração antiga, que envia de uma vez todas as branches com nomes coincidentes.

git config --global push.default simple
git config --global push.autoSetupRemote true
git config --global push.followTags true
git config --global pull.rebase true

O push.followTags torna o --follow-tags o comportamento padrão, e o pull.rebase evita commits de merge desnecessários quando o push é rejeitado e você precisa trazer antes as alterações dos outros.

Hook pre-push

O arquivo .git/hooks/pre-push é executado antes do envio. Se ele terminar com código diferente de zero, o push não acontece. Times costumam rodar ali os testes ou o linter, para que código quebrado não chegue ao servidor. Pular o hook com --no-verify só faz sentido quando você sabe exatamente por que ele está falhando.

Conclusão

O git push publica seus commits no repositório remoto e funciona em um único sentido. Faça o primeiro envio da branch com -u; em caso de rejeição, traga antes as alterações dos outros com pull; e envie o histórico reescrito da sua branch somente com --force-with-lease. O trabalho com repositórios remotos, push, pull e chaves SSH é praticado no curso de Git.

Perguntas frequentes

O git push envia alterações não commitadas?

Não. O push envia só commits; as alterações na pasta de trabalho e no índice ficam locais até você commitá-las.

Como desfazer um git push?

Na sua branch, dá para desfazer o commit localmente (git reset) e enviar com git push --force-with-lease. Numa branch compartilhada, é mais seguro criar um commit inverso com git revert e fazer um push normal.

Dá para enviar só um commit?

Sim, indicando o hash: git push origin abc1234:main envia todo o histórico até esse commit inclusive, mas não os commits posteriores. Não é possível enviar um commit sem seus ancestrais.

Qual a diferença entre git push e git push origin main?

Sem argumentos, o Git usa o upstream configurado da branch atual; a forma explícita indica o remote e a branch diretamente e funciona mesmo sem upstream configurado.

Como fazer push para dois repositórios ao mesmo tempo?

Adicione um segundo remote e envie para os dois pelo nome, ou adicione ao origin dois endereços de push com git remote set-url --add --push origin endereco (execute para os dois endereços, incluindo o original, senão o push vai só para o segundo).

Aprenda este tema em vídeo

Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.

Ir para o curso