git push: como enviar alterações para o repositório remoto
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.
| Comando | O que faz | Quando usar |
|---|---|---|
git push | Só fast-forward | Sempre, por padrão |
git push --force-with-lease | Sobrescreve com verificação | Na sua branch, depois de rebase ou amend |
git push --force | Sobrescreve sem verificação | Quase 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
| Flag | Para que serve |
|---|---|
-u, --set-upstream | Registrar a branch remota como upstream |
-n, --dry-run | Mostrar o que seria enviado, sem enviar nada |
--all | Enviar todas as branches locais |
--tags / --follow-tags | Enviar tags |
-d, --delete | Apagar uma branch ou tag no servidor |
--force-with-lease | Reescrita segura do histórico |
-v, --verbose | Saída detalhada |
--no-verify | Pular 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
git switch -c feature/x— uma branch para a tarefa.- Commits em passos lógicos pequenos.
git fetchegit rebase origin/main— trazer a branch principal atualizada.git push -u origin feature/x— publicar a branch.- Abrir o pull request; depois do review, commits adicionais e um
git pushnormal. - 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).
Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.
Ir para o curso