Guia completo
Git e GitHub: o guia completo para começar a versionar
O mapa da trilha: o que é Git, o que é GitHub, os doze comandos que resolvem o dia a dia e a ordem para estudar cada assunto sem se perder no meio.
Git registra versões e conecta decisões; GitHub hospeda repositórios Git e organiza colaboração. Para começar sem decorar uma enciclopédia, você precisa dominar três estados, doze comandos e uma sequência de prática. Este guia é o mapa: cada lição resolve uma situação que você consegue reproduzir em uma pasta temporária antes de tocar num projeto importante.
Os exemplos foram executados com a versão abaixo e com remotos bare locais. Um
remoto bare recebe branches e tags, mas não possui working tree. Ele permite
testar push, clone, fetch e erros de concorrência sem criar nem modificar
um repositório no GitHub.
git --versionDuas ferramentas, dois trabalhos
Git é um sistema de controle de versão distribuído. Cada clone normal contém os arquivos atuais e o histórico necessário para trabalhar. Você cria commits, branches, merges e tags sem conexão constante. GitHub é uma plataforma que recebe esse repositório e acrescenta permissões, pull requests, revisão, issues, releases e automações.
Pense numa oficina e numa sala de revisão. Git é a oficina: as ferramentas que registram cada etapa e permitem montar linhas diferentes do produto. GitHub é a sala compartilhada: as pessoas apresentam uma linha de trabalho, conversam, aprovam e decidem quando ela entra na versão principal. O limite da analogia é que GitHub também executa automações e hospeda artefatos; ele não é apenas uma sala. E Git não depende de uma plataforma específica: um remote pode morar em outro serviço ou numa máquina da empresa.
Esse corte evita duas confusões comuns. git commit não envia nada para a
internet. git push não cria um commit; ele transfere commits já existentes.
Também explica por que uma falha de autenticação não apaga seu trabalho local.
Se git log mostra o commit, a versão está gravada na sua máquina mesmo quando
o remoto recusa a conexão.
O modelo de três estados que organiza todos os comandos
Na working tree, você edita arquivos. No stage, escolhe o conteúdo do próximo retrato. No repositório, commits preservam esse retrato e apontam para seus pais. Um remote guarda referências e objetos compartilhados, mas só entra depois desse ciclo local.
O status curto torna estados simultâneos observáveis. No sandbox havia um arquivo modificado apenas na bancada, outro preparado e modificado de novo, um novo preparado e um novo ainda desconhecido:
git status --shortLeia as duas colunas como stage e working tree. M só mudou na bancada; M
estaria apenas preparado; MM tem uma versão em cada estado; ?? ainda não é
rastreado. Quando um comando parece misterioso, volte à pergunta “qual estado
ele lê e qual estado ele move?”. Essa pergunta funciona melhor que memorizar
receitas isoladas.
Doze comandos cobrem o ciclo inicial
Não há uma estatística universal de uso. A seleção abaixo é editorial: ela cobre criação, inspeção, seleção, histórico, ramificação, integração e troca com remoto num projeto inicial. Comandos avançados ficam para depois que você consegue explicar o efeito de cada linha.
| intenção | comando | lê principalmente | muda principalmente |
|---|---|---|---|
| iniciar histórico | git init |
pasta atual | cria .git |
| copiar histórico | git clone |
remoto | cria repositório local |
| diagnosticar | git status |
working tree e stage | nada |
| selecionar | git add |
working tree | stage |
| revisar | git diff |
estados escolhidos | nada |
| registrar | git commit |
stage | histórico e branch |
| ler versões | git log |
histórico | nada |
| criar linha | git switch -c |
commit atual | branch e HEAD |
| integrar | git merge |
duas linhas | branch atual |
| conectar | git remote |
configuração | configuração de remote |
| receber | git fetch |
remoto | referências remotas |
| enviar | git push |
commits locais | referências remotas |
git pull aparece o tempo todo, mas ele combina fetch com uma integração —
merge ou rebase, conforme a escolha. Por isso é melhor aprender fetch antes:
você observa o que chegou sem alterar imediatamente a branch atual. restore,
reset, revert, stash, rebase e tag entram nas etapas seguintes porque
resolvem estados específicos, não o primeiro ciclo.
A primeira volta completa, sem atalho invisível
Imagine que a Livraria Horizonte ainda não tem histórico. Você cria dois
arquivos, lê o status, prepara apenas o que pertence à primeira decisão, revisa
o stage e grava. Cada etapa responde uma pergunta diferente. init pergunta
“esta pasta já é repositório?”. status pergunta “o que difere do último
commit?”. add responde “qual conteúdo quero selecionar?”. diff --cached
responde “o que exatamente selecionei?”. commit transforma essa seleção em
histórico.
git init -b main loja
cd loja
git add README.md catalogo.txt
git diff --cached --stat
git commit -m "docs: inicia catálogo"O hash curto na resposta é suficiente para leitura cotidiana, mas o objeto usa
quarenta caracteres no modo SHA-1 desse repositório. Você não escolhe o hash e
não deve copiá-lo de um tutorial para seus comandos: rode git log e use o
identificador que apareceu no seu histórico. Hashes do material pertencem ao
sandbox executado em 24 de agosto de 2026.
Ao editar dois assuntos, prepare um por vez. Um ajuste de preço e uma mudança na política de frete podem merecer commits separados mesmo que tenham sido feitos na mesma manhã. O stage é a ferramenta que permite essa separação. Ele não é uma sala de espera obrigatória sem propósito; é a proposta exata do próximo registro.
Depois do commit, git status deve estar limpo apenas se você realmente incluiu
ou decidiu descartar todo o trabalho. “Limpo” não significa “correto”. O Git
confirma coerência do histórico, não regra de negócio. Testes, revisão e
execução continuam necessários. Um commit pode registrar perfeitamente um
cálculo de frete errado.
Branch é um nome móvel sobre um grafo
Uma branch não copia a pasta inteira. Ela é uma referência que aponta para um
commit. HEAD normalmente aponta para a branch atual, e cada novo commit move
essa branch. Quando você cria feat/busca, as duas branches começam no mesmo
ponto; depois cada uma pode avançar independentemente.
git switch -c feat/busca
git branch -vv
cat .git/HEADO arquivo HEAD torna o modelo concreto: ele contém o nome da referência.
Quando você faz checkout direto de um commit, HEAD guarda um hash e entra no
estado detached. Isso é útil para inspecionar uma versão, mas um commit novo
feito ali não recebe automaticamente um nome de branch. Antes de sair, crie
uma referência se quiser preservar o trabalho.
Branches resolvem isolamento de intenção, não isolamento absoluto de arquivos.
Ao trocar, o Git atualiza a working tree para o commit escolhido. Alterações não
commitadas podem acompanhar a troca quando não colidem, ou podem bloquear a
operação quando seriam sobrescritas. Leia a mensagem em vez de usar --force:
ela está protegendo conteúdo que ainda não ganhou commit.
Merge reúne linhas. Um fast-forward apenas move um nome porque não houve divergência. Com commits nos dois lados, o merge pode criar um commit com dois pais. Se ambos alteraram a mesma região, o Git devolve o arquivo com marcadores e espera uma decisão. O grafo explica os três resultados sem depender do nome da ferramenta gráfica.
Fetch mostra o remoto antes de integrar
Um remote é um nome associado a um endereço e a regras de referências.
origin é convenção criada pelo clone, não palavra reservada. Depois de outra
cópia enviar um commit, fetch atualiza origin/main sem mover main nem
reescrever seus arquivos. No sandbox, o remoto avançou de 16eb2a6 para
8eb0591:
git fetch origin
git --no-pager log --oneline --decorate --all -3A ordem visual dessas linhas pode variar quando os commits compartilham data;
as relações de ancestralidade não variam. Use --graph e os nomes decorados
para interpretar. origin/main é sua última observação da branch remota. Ele
não é uma conexão ao vivo e pode ficar desatualizado até o próximo fetch.
Com o histórico inspecionado, git merge origin/main integra explicitamente.
git pull --ff-only faz fetch e aceita apenas avanço direto, recusando uma
divergência que exigiria decisão. git pull --rebase reaplica seus commits
locais sobre a nova base. Nenhuma opção é universal: a política do time e o
estado do grafo dizem qual cabe.
Essa distinção também melhora o diagnóstico de push rejeitado. Primeiro faça
fetch, compare main com origin/main e descubra quem avançou. Só depois
integre. Um push --force imediato troca compreensão por risco e pode apagar o
commit da outra cópia.
A ordem de estudo reduz acidentes
Primeiro, confirme instalação e autoria. Depois, repita init, status, add,
diff e commit até prever a saída. Só então abra branches e provoque um
conflito controlado. Remotos vêm depois que o histórico local deixa de parecer
uma caixa-preta. Rebase e publicação de tags fecham a sequência.
O mapa curricular desta trilha tem quinze lições. Os artigos de erro ficam ao lado do percurso, porque são socorro consultado quando a mensagem aparece:
Comece por o que é Git e pela instalação e configuração. Em seguida, construa o primeiro repositório e aprenda a ler status e log. Essa primeira volta já permite versionar projetos pessoais sem remoto.
Na segunda volta, adicione .gitignore e pratique a tabela de desfazer. Na terceira, use branches e switch e provoque um merge com conflito. Só depois conecte um remoto no percurso de push, clone e pull. Esses oito links são os pontos de entrada; a navegação anterior/próxima da trilha conduz às lições intermediárias sem transformar o guia numa lista solta.
Desfazer exige localizar a mudança antes do comando
“Quero voltar” não descreve o problema. Uma edição pode estar apenas no disco, no stage, num commit local ou num commit que outra pessoa já recebeu. O comando seguro muda conforme esse local. A tabela é uma árvore de decisão compacta:
| onde está a mudança | objetivo | escolha inicial | risco principal |
|---|---|---|---|
| working tree | descartar edição não preparada | git restore arquivo |
perde conteúdo não commitado |
| stage | retirar da próxima versão | git restore --staged arquivo |
nenhum conteúdo do disco é apagado |
| último commit local | ajustar mensagem ou seleção | git commit --amend |
hash muda |
| commits locais | mover a branch | git reset |
modo --hard apaga trabalho |
| commit compartilhado | compensar com novo commit | git revert HASH |
pode gerar conflito |
| referência aparentemente perdida | localizar movimento | git reflog |
entradas expiram; aja cedo |
A regra de proteção é simples: preserve histórico que outras pessoas podem ter
puxado. revert adiciona um registro inverso e mantém a sequência. reset e
amend reposicionam ou recriam commits; são úteis localmente e perigosos quando
executados sem coordenação sobre uma branch compartilhada.
No teste, dois commits foram removidos da ponta com reset --hard, mas o reflog
manteve o movimento recente:
git reset --hard HEAD~2
git --no-pager reflog -4O hash e26f0a6 permitiu recuperar a ponta. Isso não transforma reset --hard
em comando inofensivo: arquivos nunca commitados não aparecem magicamente no
reflog. A rede de segurança funciona para referências e commits que existiram.
Sozinho, você otimiza clareza; em time, também preserva contratos
Num projeto individual, uma branch por experimento e commits pequenos já entregam valor. Você controla quando reescrever uma mensagem e sabe se alguém depende da branch. Em time, cada ação tem consumidores: uma pessoa revisa o diff, outra baseia trabalho no mesmo commit e uma automação verifica a branch.
O fluxo mínimo colaborativo começa atualizando a base, cria uma branch de tarefa, registra decisões, envia a branch e abre um pull request. A interface do GitHub não foi automatizada nem alterada nesta produção. As operações Git foram reproduzidas contra bare local; títulos, revisão, proteção de branch e botões de merge são explicados a partir da documentação oficial.
O primeiro push real do sandbox mostrou o vínculo de upstream:
git remote add origin /tmp/grupo-git-remoto.GmCWt4/central.git
git push -u origin mainO caminho é local de propósito. Num GitHub real, origin costuma apontar para
HTTPS ou SSH e a autenticação entra em cena. O efeito Git é o mesmo: objetos
são transferidos e a referência remota avança, se isso não apagar trabalho que
o servidor já conhece.
As mensagens da primeira semana descrevem estados, não castigos
nothing to commit costuma significar que nada mudou ou nada foi preparado.
pathspec did not match indica nome ou caminho que o Git não encontrou.
CONFLICT (content) diz que duas linhas de histórico alteraram a mesma região
de forma que o Git não escolhe sozinho. rejected (fetch first) protege um
remoto que avançou. refusing to merge unrelated histories aponta duas raízes
sem ancestral comum.
O método de diagnóstico é sempre o mesmo. Copie a mensagem inteira, rode
git status, confirme branch e remote, desenhe os commits relevantes e só
então escolha a correção. Não comece por --force. A opção força uma escrita;
ela não explica se a escrita está correta.
Um conflito reproduzido no arquivo precos.js gerou a mensagem abaixo:
git merge feat/frete-expressoO Git parou antes de inventar uma tarifa. A pessoa responsável precisou ler os dois lados, escrever uma versão que preservasse frete padrão e expresso, testar, preparar e concluir. Resolver não é apagar marcadores até o status ficar verde; é tomar uma decisão de produto e provar que ela funciona.
Você sabe o básico quando consegue prever e recuperar
Conhecimento operacional aparece quando você explica antes de executar. Dado
um MM no status, diga qual conteúdo entra no commit. Dadas duas branches que
editaram a mesma linha, preveja o conflito. Dado um push rejeitado, identifique
qual referência remota avançou. Dado um reset acidental, procure o commit no
reflog sem criar novas alterações por pânico.
Use esta checagem prática:
- crie um repositório temporário e três commits coerentes;
- prepare apenas parte de duas mudanças e explique o status curto;
- crie uma branch, produza divergência e resolva um conflito intencional;
- conecte um bare local, faça push, clone e fetch em outra pasta;
- provoque um push rejeitado com dois clones e integre sem
--force; - recupere um commit local pelo reflog;
- marque uma versão e confira quais tags chegaram ao remoto.
Não execute esse roteiro no repositório do trabalho. mktemp -d cria um espaço
descartável, e um remote bare local permite praticar concorrência sem rede. O
critério não é concluir rápido: é narrar o estado antes, a ação e o estado
depois.
Depois da trilha, escolha profundidade pelo problema
GitHub Actions automatiza verificações e entrega, mas pressupõe branches e commits confiáveis. Monorepos acrescentam escala de caminhos, dependências e responsabilidade; não mudam o significado de commit. Submódulos conectam repositórios por um commit específico e exigem disciplina de atualização. Assinatura de commits, políticas no servidor, Git LFS e hooks também respondem a necessidades concretas.
Não avance para um recurso porque ele parece profissional. Avance quando o problema apareceu e você consegue descrever o custo. Se binários estão inflando o histórico, pesquise LFS. Se toda revisão repete os mesmos checks, automatize. Se uma base contém componentes independentes, compare monorepo e multirepo. O básico bem observado sustenta essas decisões.
Seu próximo passo é executar a checagem em um diretório temporário e anotar onde sua previsão divergiu da saída. Depois entre no curso prático de Git para transformar o mapa em sequência de aulas e projeto. A meta não é nunca errar; é reconhecer o estado, preservar o trabalho e escolher a operação menos destrutiva. Guarde também um pequeno diário do laboratório: comando, estado esperado, saída observada e explicação da diferença. Essa anotação revela se a dificuldade está em localizar a mudança, interpretar o grafo ou decidir a política do time. Na repetição seguinte, tente prever sem consultar a receita e use a documentação apenas para confirmar opções. É assim que uma lista de comandos vira um modelo mental que continua funcionando diante de mensagens novas.
Trilha
Git e GitHub
Versionar de verdade: commit, branch, merge e o que fazer quando o histórico complica.
- 01O que é Git: versionar código e por que ele não é o GitHub
- 02Instalar o Git e configurar user.name e user.email
- 03git init e git commit: seu primeiro repositório do zero
- 04git status e git log: ler o estado e o histórico do projeto
- 05.gitignore: como ignorar arquivos e pastas no Git
- 06Desfazer no Git: restore, reset e revert (qual usar)
- 07git branch e git switch: criar, trocar e apagar branches
- 08git merge: juntar branches e resolver conflito na mão
- 09git stash: guardar mudanças sem fazer commit
- 10Subir projeto para o GitHub: remote, push, clone e pull
- 11Pull request no GitHub: abrir, revisar e fazer o merge
- 12git rebase: reescrever o histórico e quando não usar
- 13git tag e release no GitHub: marcar versões do projeto
- 14README no GitHub: o arquivo que mostra o seu portfólio
- 15Fluxo de trabalho com Git em time: branch, PR e main protegida
git
fatal: refusing to merge unrelated histories — resolver
Updates were rejected because the remote contains work: resolver o push
Perguntas frequentes
Quanto tempo leva para aprender Git para o primeiro emprego?
Devo aprender Git pela interface gráfica ou pelo terminal?
GitHub substitui backup do projeto?
O código deste guia foi executado em git version 2.54.0 (Apple Git-156) no macOS 27, e as saídas exibidas são as reais — como produzimos este conteúdo.
Fontes consultadas
- Git — Referência completa — git-scm.com
- Pro Git — livro oficial — git-scm.com
- GitHub Docs — Sobre o Git — docs.github.com

