Todo mundo já passou por isso. Uma pasta com projeto_final.zip, projeto_final_v2.zip, projeto_final_v2_revisado.zip e, finalmente, projeto_final_v2_AGORA_VAI.zip. Ninguém lembra qual é a versão boa, o que mudou de uma para a outra, nem quem apagou aquela função que funcionava ontem. Agora multiplique isso por cinco pessoas mexendo no mesmo código, ao mesmo tempo, e você tem o caos.

O Git resolve exatamente esse problema. O GitHub pega essa solução e a transforma em uma plataforma de colaboração usada por praticamente toda a indústria de software. Este guia é longo de propósito: ele vai do "o que é um commit" até rebase interativo, bisect, GitHub Actions e recuperação de desastres, com cada comando explicado passo a passo, a saída que você deve esperar e as armadilhas que pegam até gente experiente.

Os exemplos foram testados no Git 2.52. Qualquer versão a partir da 2.40 serve para praticamente tudo aqui; quando um recurso exige uma versão mais nova, isso é dito explicitamente.

O problema que o controle de versão resolve

Um sistema de controle de versão (VCS, version control system) registra a história de um conjunto de arquivos ao longo do tempo. Para cada mudança, ele guarda o que mudou, quem mudou, quando e, se você escrever uma boa mensagem, por quê. Com isso você ganha superpoderes bem concretos:

  • Voltar no tempo: recuperar qualquer versão anterior de qualquer arquivo, ou do projeto inteiro.
  • Trabalhar em paralelo: várias pessoas (ou várias ideias suas) evoluindo o código ao mesmo tempo, sem uma pisar na outra.
  • Juntar trabalho: combinar mudanças de pessoas diferentes de forma quase sempre automática.
  • Investigar: descobrir em qual mudança um bug apareceu e o contexto em que ela foi feita.
  • Experimentar sem medo: se a ideia não der certo, basta descartá-la.

Existem duas grandes famílias de VCS:

ModeloExemplosComo funciona
CentralizadoCVS, Subversion (SVN)Um servidor guarda o histórico; cada pessoa tem só uma cópia de trabalho. Sem servidor, nada de commit.
DistribuídoGit, MercurialCada clone é uma cópia completa do repositório, com todo o histórico. Você trabalha offline e cada clone é, na prática, um backup.

O Git é distribuído. Isso explica por que quase tudo nele é instantâneo: log, diff, commit e troca de branch acontecem no seu disco, sem ida e volta pela rede.

Uma breve história: Linus Torvalds, o BitKeeper e 2005

Entre 2002 e 2005, o kernel do Linux era versionado com o BitKeeper, uma ferramenta proprietária que a comunidade podia usar de graça. Em 2005, a relação entre os desenvolvedores do kernel e a empresa por trás do BitKeeper azedou e a licença gratuita foi revogada. Linus Torvalds, criador do Linux, decidiu escrever a própria ferramenta, com metas bem claras:

  • ser rápida, mesmo com o histórico gigantesco do kernel;
  • ter um design simples;
  • dar suporte forte a desenvolvimento não linear, com milhares de branches em paralelo;
  • ser totalmente distribuída;
  • garantir a integridade dos dados, de forma que nada seja corrompido sem que se perceba.

O primeiro commit do Git foi feito em 7 de abril de 2005, pelo próprio Linus, com a mensagem "Initial revision of "git", the information manager from hell". Poucos meses depois, Junio C Hamano assumiu a manutenção do projeto, papel que continua exercendo, e a versão 1.0 saiu em dezembro de 2005.

E o nome? O README desse primeiro commit brinca que "git" pode significar qualquer coisa, dependendo do seu humor: de "global information tracker", quando tudo funciona e "anjos cantam", até um xingamento impublicável, quando quebra. Em gíria britânica, git também é uma forma pouco elogiosa de chamar alguém.

Duas décadas depois, o Git é, de longe, o sistema de controle de versão mais usado do mundo.

Git não é GitHub (nem GitLab, nem Bitbucket)

Essa é a confusão número um de quem está começando:

  • Git é o programa que roda no seu computador. É software livre (licença GPLv2), funciona 100% offline e não depende de empresa nenhuma.
  • GitHub é um serviço que hospeda repositórios Git na nuvem e adiciona ferramentas de colaboração: pull requests, issues, revisão de código, GitHub Actions, Pages, Projects e muito mais. Foi lançado em 2008 e comprado pela Microsoft em 2018.

Uma boa analogia: o Git está para o GitHub assim como um arquivo de vídeo está para o YouTube. O vídeo existe sem o YouTube; o YouTube hospeda, distribui e coloca uma camada social em cima.

O GitHub não é o único serviço desse tipo:

ServiçoDestaques
GitHubO maior ecossistema de código aberto; Actions, Codespaces, Copilot
GitLabCI/CD muito integrado; pode ser instalado nos seus próprios servidores
BitbucketDa Atlassian; integra bem com Jira e Confluence
Azure DevOps (Repos)Comum em empresas que já usam o ecossistema Microsoft
Gitea / ForgejoLeves e self-hosted, ótimos para servidores pequenos

A boa notícia: tudo o que você aprender sobre Git vale para todos eles. Muda só a interface web.

Como o Git funciona por dentro

Você pode usar Git decorando comandos, mas vai sofrer na primeira situação fora do roteiro. Entender o modelo interno leva uns 15 minutos e transforma reset, rebase e "detached HEAD" de magia negra em algo lógico. Vale o investimento.

Snapshots, não diferenças

Muitos sistemas antigos guardam cada versão como uma lista de diferenças (deltas) em relação à anterior. O Git pensa de outro jeito: cada commit é um snapshot, uma fotografia completa de como todos os arquivos do projeto estavam naquele momento.

Isso não significa copiar o projeto inteiro a cada commit. Se um arquivo não mudou, o novo snapshot simplesmente aponta para o mesmo conteúdo já guardado. Veja três commits reais de um projeto pequeno:

Texto
              Commit A           Commit B           Commit C
README.md     blob 8ee0c0 ─────▶ (o mesmo) ───────▶ (o mesmo)
index.html    blob b061ee        blob 52caf0 ─────▶ (o mesmo)
style.css     blob bc406f ─────▶ (o mesmo)          blob acd365

No commit B só o index.html mudou, então só ele ganhou um conteúdo novo; o resto é reaproveitado. (Por baixo dos panos, o Git ainda compacta tudo em packfiles com compressão por deltas para economizar disco, mas o modelo com que você raciocina é o de snapshots.)

O diretório .git: o repositório de verdade

Quando você roda git init ou git clone, surge uma pasta oculta chamada .git. Ela é o repositório. O resto da pasta do projeto é só a sua área de trabalho. Se você apagar a .git, os arquivos continuam lá, mas todo o histórico some.

Texto
.git/
├── HEAD          → em que branch você está (ex.: ref: refs/heads/main)
├── config        → configurações deste repositório (remotos, branches...)
├── description   → usado só pelo GitWeb; pode ignorar
├── hooks/        → scripts que rodam em eventos (pre-commit, commit-msg...)
├── index         → a staging area (um arquivo binário)
├── info/exclude  → um .gitignore local, que não vai para o repositório
├── logs/         → para onde cada referência apontou ao longo do tempo (reflog)
├── objects/      → o banco de dados: blobs, trees, commits e tags
└── refs/
    ├── heads/    → suas branches locais
    ├── remotes/  → cópias das branches dos remotos (origin/main...)
    └── tags/     → suas tags

Com o tempo também aparecem arquivos como COMMIT_EDITMSG (a mensagem do último commit), ORIG_HEAD (a posição anterior a um merge, rebase ou reset), FETCH_HEAD e packed-refs (referências compactadas em um único arquivo).

Os quatro tipos de objeto

Tudo o que o Git guarda em .git/objects é um de quatro tipos de objeto:

ObjetoO que guardaAnalogia
blobO conteúdo de um arquivo, e só isso: sem nome, sem data, sem permissõesO texto de uma página
treeUma listagem de diretório: nomes, permissões e ponteiros para blobs e outras treesUm índice de pastas
commitUm ponteiro para a tree raiz (o snapshot), o(s) commit(s) pai, autor, committer, datas e mensagemUma foto com legenda e data
tag (anotada)Um ponteiro para outro objeto (quase sempre um commit), com nome, autor, data e mensagemUma etiqueta de "versão 1.0" colada na foto

Você pode inspecionar qualquer objeto com git cat-file: a flag -t mostra o tipo, -s o tamanho e -p imprime o conteúdo de forma legível. Veja o último commit daquele projeto:

Bash
git cat-file -p HEAD
Texto
tree 8adf6bd09b522157a364106e006f15026d2e1be5
parent d3d359b2919025b172d5d372e0b2462b9d630afc
author Ana Souza <ana@exemplo.com> 1790195540 -0300
committer Ana Souza <ana@exemplo.com> 1790195540 -0300
 
feat: saudação completa

O commit aponta para uma tree e para o commit parent. Descendo para a tree (as aspas simples evitam que o PowerShell interprete as chaves):

Bash
git cat-file -p 'HEAD^{tree}'
Texto
100644 blob 8ee0c0ed567d2cef49d241aa892ad0293ae6bb2b    README.md
040000 tree ee1af1465b1a72a8d2d37ad473fb8e4c3c2cd597    css
100644 blob 52caf059a80dd4ffa7e60f36ee519d648e9bab8f    index.html

Os números à esquerda são o modo do arquivo: 100644 é um arquivo comum, 100755 um executável, 040000 um diretório (outra tree) e 120000 um link simbólico. Repare que o blob do README.md (8ee0c0...) é exatamente o mesmo do commit anterior: é o reaproveitamento de snapshots em ação.

Hashes: a impressão digital de cada objeto

Cada objeto é identificado pelo hash SHA-1 do seu conteúdo, um número de 160 bits escrito como 40 caracteres hexadecimais. Como o hash depende só do conteúdo, o mesmo conteúdo gera o mesmo hash em qualquer computador do mundo. Faça o teste no Git Bash, no macOS ou no Linux:

Bash
echo 'hello' | git hash-object --stdin
Texto
ce013625030ba8dba906f756967f9e9ca394464a

Você vai obter exatamente esse valor. O Git calcula o SHA-1 de um pequeno cabeçalho (blob 6 seguido de um byte nulo) mais o conteúdo, e grava o objeto em .git/objects/ce/013625...: os dois primeiros caracteres viram o nome da pasta, o resto vira o nome do arquivo.

Essa ideia simples tem consequências enormes:

  • Integridade: se um único bit de um arquivo ou commit se corromper, o hash não bate mais e o Git percebe.
  • Deduplicação: conteúdo idêntico é guardado uma única vez.
  • Imutabilidade: um commit nunca é alterado. "Editar" um commit (com --amend ou rebase) na verdade cria um commit novo, com hash novo. É por isso que se diz que esses comandos "reescrevem o histórico".
  • Abreviação: você raramente digita os 40 caracteres. Os primeiros 7 (ou mais, se houver ambiguidade) bastam: git show d3d359b.

Sobre a segurança do SHA-1: desde 2017 existem ataques práticos de colisão contra ele, e o Git passou a usar uma versão "endurecida" do algoritmo, que detecta os ataques conhecidos. Além disso, desde a versão 2.29 o Git suporta repositórios com SHA-256 (git init --object-format=sha256, com hashes de 64 caracteres). Ainda não há interoperabilidade entre repositórios SHA-1 e SHA-256, e o ecossistema (bibliotecas, ferramentas e serviços de hospedagem) precisa acompanhar. A documentação do projeto já anuncia que o Git 3.0 deve adotar SHA-256 como padrão para repositórios novos. Na prática, hoje, quase todo repositório que você encontrar usa SHA-1.

Commits formam um grafo

Cada commit guarda o hash do(s) seu(s) pai(s). O primeiro commit do projeto não tem pai (é o root commit), um commit normal tem um pai e um merge commit tem dois (ou mais). Ligando os commits pelos pais, você obtém um grafo acíclico dirigido (DAG, directed acyclic graph):

Texto
               D ─── E
              /       \
    A ─── B ─── C ──── F        ← F é um merge commit: seus pais são C e E

Dois detalhes importantes:

  • As ligações apontam para trás no tempo: cada commit conhece o pai, mas o pai não sabe quais filhos tem.
  • Como o hash de um commit inclui o hash do pai, mudar qualquer commit antigo muda o hash de todos os descendentes. O histórico funciona como uma corrente.

Para se referir a ancestrais sem copiar hashes, o Git tem uma notação própria:

NotaçãoSignificado
HEAD~1 ou HEAD~O pai do commit atual
HEAD~3O bisavô: três gerações para trás, sempre seguindo o primeiro pai
HEAD^O primeiro pai (igual a HEAD~1)
HEAD^2O segundo pai, útil só em merge commits
main~2Dois commits antes da ponta da branch main

Refs, branches e HEAD

Hashes são ótimos para computadores e péssimos para humanos. Por isso o Git tem referências (refs): nomes que apontam para commits.

Uma branch é só isso: um arquivo com o hash de um commit.

Bash
cat .git/refs/heads/main
Texto
d3d359b2919025b172d5d372e0b2462b9d630afc

Criar uma branch é criar um arquivo de 41 bytes. Por isso branches no Git são instantâneas e baratas, e você deve usá-las sem economia. A característica que define uma branch é que ela se move sozinha: quando você faz um commit estando nela, o ponteiro avança para o commit novo.

O HEAD indica onde você está agora. Normalmente ele aponta para uma branch (é uma referência simbólica):

Bash
cat .git/HEAD
Texto
ref: refs/heads/main
Texto
                          HEAD
                           │
                           ▼
                          main
                           │
                           ▼
    A ◀──── B ◀──── C ◀──── D
                    ▲
                    │
              feature/login

Leia o diagrama assim: main aponta para D, feature/login aponta para C, e o HEAD aponta para main, ou seja, você está na main. Se fizer um commit agora, surge um E cujo pai é D, e main passa a apontar para E; feature/login fica onde está.

Existem outros tipos de ref: tags (ponteiros fixos, que não andam), branches de rastreamento remoto como origin/main (a última posição conhecida da main no servidor) e o próprio HEAD. Quando o HEAD aponta direto para um commit, e não para uma branch, você está em detached HEAD, situação que veremos com calma mais adiante.

As três áreas: working tree, staging area e repositório

Este é o conceito mais importante do guia. Todo arquivo transita por três lugares:

  1. Working tree (diretório de trabalho): os arquivos que você vê e edita no seu editor.
  2. Staging area (também chamada de index): o rascunho do próximo commit. Fica em .git/index.
  3. Repositório: os commits já gravados em .git/objects.
Texto
 ┌──────────────┐  git add   ┌──────────────┐ git commit ┌──────────────┐
 │ Working tree │ ─────────▶ │ Staging area │ ─────────▶ │ Repositório  │
 │ (seus        │            │ (index)      │            │ (.git)       │
 │  arquivos)   │            │              │            │              │
 └──────────────┘            └──────────────┘            └──────────────┘
        ▲                       │       ▲                        │
        │  git restore <arq>    │       │ git restore --staged   │
        └───────────────────────┘       └────────────────────────┘
  • git add copia o estado atual de um arquivo do working tree para a staging area.
  • git commit grava o que está na staging area (e não o que está no working tree!) como um novo snapshot.
  • git restore <arquivo> faz o caminho inverso: sobrescreve o arquivo no working tree com a versão da staging area, descartando o que você mudou.
  • git restore --staged <arquivo> sobrescreve a staging area com a versão do último commit, "tirando o arquivo do palco" sem mexer no seu working tree.

Por que existe uma área intermediária? Porque ela permite montar commits com cuidado. Imagine que você corrigiu um bug e, no caminho, renomeou algumas variáveis em outro arquivo. Com a staging area você cria dois commits separados, cada um com um propósito claro, em vez de um commit "corrige bug e mais umas coisas".

Os estados de um arquivo

Do ponto de vista do Git, cada arquivo do seu projeto está em um destes estados:

EstadoSignificado
Untracked (não rastreado)Arquivo novo, que o Git nunca viu em um commit nem na staging area
Unmodified (commitado)Rastreado e idêntico à versão do último commit
Modified (modificado)Rastreado e alterado no working tree, mas a alteração ainda não foi para a staging area
Staged (preparado)A alteração está na staging area e vai entrar no próximo commit
Ignored (ignorado)Casa com uma regra do .gitignore; o Git finge que ele não existe

O ciclo de vida fica assim:

Texto
  untracked ──git add──▶ staged ──git commit──▶ unmodified ──(você edita)──▶ modified
                           ▲                                                    │
                           └───────────────────────── git add ──────────────────┘

Guarde esse desenho. Quase todo comando do dia a dia é uma seta dele.

Instalando o Git

A forma recomendada é o Git for Windows, que traz o Git, o Git Bash (um terminal com comandos Unix) e o Git Credential Manager.

  1. Baixe e instale

    Baixe em git-scm.com/downloads/win ou, pelo terminal:

    PowerShell
    winget install --id Git.Git -e --source winget
  2. Escolhas importantes do instalador

    • Editor padrão: escolha o VS Code se você o usa; o padrão é o Vim.
    • Nome da branch inicial: marque "Override" e digite main.
    • PATH: mantenha a opção recomendada ("Git from the command line and also from 3rd-party software").
    • Finais de linha: "Checkout Windows-style, commit Unix-style" (equivale a core.autocrlf=true).
    • Credential helper: mantenha o Git Credential Manager.
  3. Confira

    Abra um terminal novo e rode git --version.

Configuração inicial

Antes do primeiro commit, diga ao Git quem você é. Esses dados vão em todos os commits:

Bash
git config --global user.name "Seu Nome"
git config --global user.email "voce@exemplo.com"

Use o mesmo e-mail da sua conta do GitHub para que os commits apareçam ligados ao seu perfil. Outras configurações que valem a pena:

Bash
git config --global init.defaultBranch main      # novos repositórios começam na main
git config --global core.editor "code --wait"    # VS Code como editor de mensagens
git config --global pull.rebase false            # pull faz merge (padrão explícito, sem avisos)
git config --global color.ui auto

Finais de linha

Windows usa CRLF no fim das linhas; Linux e macOS, LF. Para que o repositório guarde sempre LF:

Bash
git config --global core.autocrlf true    # no Windows
git config --global core.autocrlf input   # no macOS e no Linux

Em projetos de equipe, o mais robusto é um arquivo .gitattributes na raiz, que vale para todos independentemente da configuração de cada máquina:

.gitattributes
Texto
* text=auto eol=lf
*.bat text eol=crlf
*.png binary

Aliases

Bash
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.lg "log --oneline --graph --decorate --all"

Agora git lg desenha o histórico de todas as branches.

Onde as configurações ficam

NívelArquivoVale para
--system/etc/gitconfigTodos os usuários da máquina
--global~/.gitconfigTodos os seus repositórios
--local (padrão).git/configSó o repositório atual

O nível mais específico vence. git config --list --show-origin mostra cada valor e de qual arquivo ele veio.

Criando repositórios

Há duas formas de começar:

Bash
# 1. Transformar uma pasta existente em repositório
cd meu-projeto
git init
 
# 2. Copiar um repositório existente (com todo o histórico)
git clone https://github.com/usuario/projeto.git
git clone git@github.com:usuario/projeto.git        # mesma coisa, via SSH
git clone https://github.com/usuario/projeto.git outra-pasta

O git init cria a pasta oculta .git. É nela que mora todo o repositório: objetos, branches, configurações. Apagar o .git transforma a pasta de volta em uma pasta comum; apagar os arquivos do projeto não apaga o histórico.

O ciclo básico, passo a passo

  1. Crie ou altere um arquivo

    Bash
    echo "# Meu projeto" > README.md
  2. Veja o estado

    Bash
    git status
    Texto
    On branch main
     
    No commits yet
     
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            README.md
  3. Prepare as mudanças (staging)

    Bash
    git add README.md     # um arquivo
    git add .             # tudo a partir da pasta atual
    git add -p            # escolhe trecho por trecho, interativamente
  4. Grave o commit

    Bash
    git commit -m "Adiciona README"
  5. Confira o histórico

    Bash
    git log --oneline
    Texto
    3f2a1c9 (HEAD -> main) Adiciona README

git commit -am "mensagem" faz add e commit de uma vez, mas só para arquivos já rastreados; arquivos novos precisam de git add.

Boas mensagens de commit

Um histórico legível é documentação. As convenções mais aceitas:

  • Assunto curto (até uns 50 caracteres), no imperativo: "Corrige cálculo de frete", não "corrigido" nem "corrigindo".
  • Linha em branco e, se precisar, um corpo explicando o porquê, com linhas de até ~72 caracteres.
  • Um commit, um propósito.
Git
Corrige arredondamento no cálculo do frete
 
O valor era arredondado antes de aplicar o desconto, o que gerava
diferenças de um centavo em pedidos com cupom.

Conventional Commits

Muitos projetos adotam um prefixo que diz o tipo da mudança. Ferramentas usam isso para gerar changelogs e versões automaticamente.

TipoQuando usarExemplo
featNova funcionalidadefeat: adiciona login com Google
fixCorreção de bugfix: corrige frete para CEP sem número
docsDocumentaçãodocs: explica variáveis de ambiente
styleFormatação, sem mudar lógicastyle: aplica prettier
refactorReestruturação sem mudar comportamentorefactor: extrai serviço de pagamento
perfDesempenhoperf: adiciona índice na busca de pedidos
testTestestest: cobre cálculo de desconto
buildBuild e dependênciasbuild: atualiza next para 15.3
ciIntegração contínuaci: roda testes no pull request
choreTarefas geraischore: remove arquivos temporários

Mudanças que quebram compatibilidade levam !: feat!: remove endpoint v1.

Inspecionando o repositório

Bash
git status -s                  # status resumido (M = modificado, A = adicionado, ?? = novo)
git diff                       # o que mudou e ainda NÃO está na staging area
git diff --staged              # o que está na staging area e vai no próximo commit
git diff main..feature         # diferença entre duas branches
git log                        # histórico completo
git log --oneline --graph --all --decorate
git log -p arquivo.ts          # histórico com o conteúdo das mudanças de um arquivo
git log --stat                 # quais arquivos cada commit alterou
git log --author="Ana"         # commits de uma pessoa
git log --since="2 weeks ago"
git log -S "calculaFrete"      # commits que adicionaram ou removeram esse texto
git show 3f2a1c9               # detalhes de um commit
git blame arquivo.ts           # quem alterou cada linha por último
git shortlog -sn               # quantidade de commits por autor

.gitignore: o que não deve ser versionado

Dependências baixadas, builds, logs, arquivos do sistema e, principalmente, segredos não entram no repositório. Liste-os no .gitignore:

.gitignore
Texto
# Dependências e builds
node_modules/
dist/
.next/
*.o
*.exe
 
# Logs e temporários
*.log
.DS_Store
Thumbs.db
 
# Variáveis de ambiente (NUNCA versione)
.env
.env.local
!.env.example

Regras da sintaxe:

PadrãoSignificado
*.logQualquer arquivo terminado em .log, em qualquer pasta
build/Pastas chamadas build
/config.jsonSó o config.json da raiz
docs/**/*.pdfPDFs em qualquer subpasta de docs
!importante.logExceção: volta a rastrear este arquivo
# textoComentário

O GitHub mantém modelos prontos para cada linguagem no repositório github/gitignore. Para arquivos que só você gera (configurações do seu editor, por exemplo), use um gitignore global:

Bash
git config --global core.excludesFile ~/.gitignore_global

Desfazendo coisas

Esta é a seção que você mais vai consultar. Os comandos estão em ordem, do mais seguro ao mais destrutivo.

Descartar mudanças no working tree

Bash
git restore arquivo.ts        # volta o arquivo para a versão da staging area (ou do último commit)
git restore .                 # descarta TODAS as mudanças não preparadas

As mudanças descartadas assim não vão para lugar nenhum: não há como recuperá-las pelo Git.

Tirar da staging area

Bash
git restore --staged arquivo.ts   # tira do "palco", mas mantém as mudanças no arquivo

Corrigir o último commit

Bash
git commit --amend -m "Mensagem corrigida"   # troca a mensagem
git add esquecido.ts
git commit --amend --no-edit                 # inclui um arquivo esquecido, mantendo a mensagem

O --amend cria um commit novo no lugar do anterior. Se o commit já foi enviado ao remoto, evite: você reescreveria um histórico que outras pessoas já têm.

git reset: voltando a branch

git reset move a branch atual para outro commit. As três variações diferem no que acontece com as mudanças:

Texto
Antes:  A ─ B ─ C   ← main (HEAD)
 
git reset --soft  HEAD~1   → main aponta para B; as mudanças de C ficam na STAGING AREA
git reset --mixed HEAD~1   → main aponta para B; as mudanças de C ficam no WORKING TREE (padrão)
git reset --hard  HEAD~1   → main aponta para B; as mudanças de C são DESCARTADAS

HEAD~1 significa "um commit antes do HEAD"; HEAD~3, três antes. --soft é ótimo para refazer os últimos commits como um só; --hard apaga trabalho e deve ser usado com cuidado.

git revert: desfazer sem reescrever o histórico

Bash
git revert 3f2a1c9

Cria um novo commit que faz o contrário do commit indicado. É a forma segura de desfazer algo que já está no remoto e que outras pessoas já baixaram.

git reflog: a rede de segurança

O Git registra por onde o HEAD passou nos últimos meses (por padrão, 90 dias para entradas alcançáveis). Mesmo depois de um reset --hard desastroso, os commits ainda existem:

Bash
git reflog
Texto
9c1d2e3 HEAD@{0}: reset: moving to HEAD~2
7b8a9f0 HEAD@{1}: commit: Implementa checkout
5e4d3c2 HEAD@{2}: commit: Adiciona carrinho
Bash
git reset --hard 7b8a9f0      # volta para antes do reset
git branch recuperada 7b8a9f0 # ou cria uma branch apontando para lá

O mesmo vale para uma branch apagada por engano: ache o último commit dela no reflog e recrie a branch.

git clean: apagar arquivos não rastreados

Bash
git clean -n     # simula: mostra o que seria apagado
git clean -fd    # apaga arquivos e pastas não rastreados

Qual comando usar?

SituaçãoComando
Estraguei um arquivo e quero a versão do último commitgit restore arquivo
Dei git add no arquivo erradogit restore --staged arquivo
Errei a mensagem do último commit (não enviado)git commit --amend -m "..."
Esqueci um arquivo no último commit (não enviado)git add arquivo && git commit --amend --no-edit
Quero desfazer o último commit mantendo as mudançasgit reset --soft HEAD~1
Quero jogar fora os últimos commits locaisgit reset --hard HEAD~N
Preciso desfazer um commit que já está no GitHubgit revert <hash>
Apaguei algo com reset ou perdi uma branchgit reflog e depois git reset --hard ou git branch
Quero remover arquivos não rastreadosgit clean -n e depois git clean -fd

Branches

Uma branch é apenas um ponteiro móvel para um commit. Criar uma branch custa praticamente nada: o Git grava um arquivo com o hash do commit. A cada novo commit, a branch em que você está (a que o HEAD aponta) avança.

Texto
            ┌── feature/login
            ▼
A ─ B ─ C ─ D
        ▲
        └── main
Bash
git branch                       # lista as branches locais (* marca a atual)
git branch -a                    # inclui as remotas
git switch -c feature/login      # cria e troca para a nova branch
git switch main                  # troca de branch
git switch -                     # volta para a branch anterior
git branch -m nome-novo          # renomeia a branch atual
git branch -d feature/login      # apaga (só se já foi mesclada)
git branch -D feature/login      # apaga à força

git switch foi criado em 2019 (Git 2.23) para separar as funções do antigo git checkout, que fazia de tudo. git checkout -b nome ainda funciona e aparece em muitos tutoriais.

Convenções de nome comuns: feature/descricao, fix/descricao, hotfix/descricao, chore/descricao, sempre em minúsculas e com hifens.

Merge: juntando branches

Fast-forward

Se a main não andou desde que a branch foi criada, o merge só avança o ponteiro:

Texto
Antes:  A ─ B ← main
             \
              C ─ D ← feature
 
git switch main && git merge feature
 
Depois: A ─ B ─ C ─ D ← main, feature

Merge de três vias

Se as duas branches receberam commits, o Git cria um commit de merge com dois pais:

Texto
Antes:  A ─ B ─ E ← main
             \
              C ─ D ← feature
 
Depois: A ─ B ─ E ─ M ← main
             \     /
              C ─ D

git merge --no-ff feature força a criação do commit de merge mesmo quando daria fast-forward, preservando no histórico o registro de que existiu uma branch.

Resolvendo conflitos, passo a passo

Quando as duas branches alteram as mesmas linhas, o Git para e pede sua decisão:

Texto
Auto-merging src/preco.ts
CONFLICT (content): Merge conflict in src/preco.ts
Automatic merge failed; fix conflicts and then commit the result.
  1. Veja quais arquivos estão em conflito

    git status lista os arquivos em "both modified".

  2. Abra o arquivo e encontre os marcadores

    Texto
    <<<<<<< HEAD
    const desconto = 0.10;
    =======
    const desconto = 0.15;
    >>>>>>> feature/promocao

    Acima do ======= está a versão da sua branch atual (HEAD); abaixo, a da branch que está entrando.

  3. Edite para o resultado final e apague os marcadores

    O VS Code mostra botões "Accept Current", "Accept Incoming" e "Accept Both" sobre cada conflito.

  4. Marque como resolvido e conclua

    Bash
    git add src/preco.ts
    git commit            # a mensagem de merge já vem preenchida

Mudou de ideia no meio? git merge --abort volta tudo para antes do merge.

Rebase: reescrevendo a base

O rebase reaplica os commits da sua branch em cima de outra base, como se você tivesse começado a trabalhar a partir do ponto mais recente:

Texto
Antes:  A ─ B ─ E ← main
             \
              C ─ D ← feature
 
git switch feature && git rebase main
 
Depois: A ─ B ─ E ← main
                 \
                  C' ─ D' ← feature

C' e D' são commits novos (com hashes diferentes), com as mesmas mudanças de C e D. O resultado é um histórico linear, sem commit de merge.

Se houver conflito durante o rebase, resolva o arquivo e continue:

Bash
git add arquivo
git rebase --continue    # segue para o próximo commit
git rebase --skip        # descarta o commit atual
git rebase --abort       # cancela e volta ao estado anterior

Rebase interativo: arrumando commits antes de publicar

Bash
git rebase -i HEAD~3

O Git abre o editor com a lista dos últimos 3 commits:

Texto
pick 1a2b3c4 Adiciona formulário de login
pick 5d6e7f8 wip
pick 9a0b1c2 Corrige typo

Troque a palavra antes de cada commit:

ComandoEfeito
pickMantém o commit
rewordMantém, mas permite editar a mensagem
editPara nesse commit para você alterá-lo
squashJunta com o commit anterior, combinando as mensagens
fixupJunta com o anterior, descartando esta mensagem
dropRemove o commit
MergeRebase
HistóricoPreserva exatamente o que aconteceuLinear e mais limpo
Reescreve commitsNãoSim
Seguro em branch compartilhadaSimNão
ConflitosResolvidos uma vezPodem aparecer commit a commit
Uso típicoIntegrar na mainAtualizar sua branch com a main

Stash: guardando mudanças para depois

Você está no meio de uma tarefa e precisa trocar de branch para corrigir algo urgente? Guarde as mudanças numa pilha temporária:

Bash
git stash push -m "formulário pela metade"   # guarda e limpa o working tree
git stash -u                                  # inclui arquivos não rastreados
git stash list                                # lista o que está guardado
git stash show -p stash@{0}                   # mostra o conteúdo
git stash pop                                 # reaplica o último e remove da pilha
git stash apply stash@{1}                     # reaplica sem remover
git stash drop stash@{0}                      # descarta um item

Repositórios remotos

Um remoto é uma cópia do repositório em outro lugar, normalmente no GitHub. Por convenção, o principal se chama origin.

Bash
git remote -v                                            # lista os remotos
git remote add origin git@github.com:usuario/projeto.git
git remote set-url origin git@github.com:usuario/novo.git
git remote rename origin github
git remote remove github

fetch, pull e push

Bash
git fetch                 # baixa as novidades do remoto sem mexer nas suas branches
git pull                  # fetch + merge na branch atual
git pull --rebase         # fetch + rebase (histórico linear)
git push                  # envia seus commits
git push -u origin main   # primeira vez: envia e liga a branch local à remota

O -u (upstream) grava que a sua main acompanha a origin/main. Depois disso, git push e git pull sem argumentos já sabem para onde ir. git branch -vv mostra quem acompanha quem e quantos commits estão à frente ou atrás.

Bash
git push -u origin feature/login        # publica uma branch nova
git push origin --delete feature/login  # apaga a branch remota
git fetch --prune                       # remove referências a branches remotas que não existem mais

Force push com segurança

Depois de um rebase, o push normal é recusado porque o histórico divergiu. Se a branch é só sua:

Bash
git push --force-with-lease

Diferente de --force, o --force-with-lease recusa o envio se alguém tiver enviado commits que você ainda não baixou, evitando apagar o trabalho dos outros.

GitHub, passo a passo

Criando a conta e o primeiro repositório

  1. Crie sua conta em github.com e ative a autenticação em dois fatores (Settings → Password and authentication).
  2. Crie um repositório com o botão New: escolha o nome, público ou privado, e se deseja um README, um .gitignore e uma licença.
  3. Opcional: crie um repositório com o mesmo nome do seu usuário e um README.md nele. Ele vira o README do seu perfil.

Publicando um projeto que já existe no seu computador

  1. Transforme a pasta em repositório e faça o primeiro commit

    Bash
    cd meu-projeto
    git init
    git add .
    git commit -m "Primeiro commit"
  2. Crie o repositório no GitHub

    Crie-o vazio (sem README, sem .gitignore, sem licença) para não haver conflito com o seu histórico local.

  3. Conecte e envie

    Bash
    git remote add origin git@github.com:usuario/meu-projeto.git
    git branch -M main
    git push -u origin main

    git branch -M main garante que a branch se chama main, caso o seu Git tenha criado master.

Autenticação: HTTPS, tokens e SSH

Desde agosto de 2021, o GitHub não aceita a senha da conta para operações Git por HTTPS. Existem duas alternativas.

HTTPS com Git Credential Manager ou token

O Git Credential Manager (instalado junto com o Git for Windows e disponível para macOS e Linux) abre o navegador na primeira vez e guarda a credencial com segurança. Sem ele, você usa um Personal Access Token (Settings → Developer settings → Personal access tokens) no lugar da senha. Prefira os tokens fine-grained, com acesso só aos repositórios necessários e data de expiração.

SSH, passo a passo

  1. Gere a chave

    Bash
    ssh-keygen -t ed25519 -C "voce@exemplo.com"

    Aceite o caminho padrão e defina uma passphrase.

  2. Carregue a chave no agente

    No PowerShell como administrador, ative o serviço uma vez:

    PowerShell
    Get-Service ssh-agent | Set-Service -StartupType Automatic
    Start-Service ssh-agent
    ssh-add $env:USERPROFILE\.ssh\id_ed25519
  3. Copie a chave pública

    Bash
    cat ~/.ssh/id_ed25519.pub

    Copie a linha inteira (começa com ssh-ed25519). Nunca compartilhe o arquivo sem .pub.

  4. Cadastre no GitHub

    Settings → SSH and GPG keys → New SSH key. Cole a chave e salve.

  5. Teste a conexão

    Bash
    ssh -T git@github.com
    Texto
    Hi usuario! You've successfully authenticated, but GitHub does not provide shell access.
  6. Troque um remoto HTTPS para SSH (se necessário)

    Bash
    git remote set-url origin git@github.com:usuario/projeto.git

GitHub CLI

A ferramenta oficial gh traz o GitHub para o terminal:

Bash
gh auth login                        # autentica (abre o navegador)
gh repo create meu-projeto --private --source=. --push   # cria no GitHub e envia a pasta atual
gh repo clone usuario/projeto
gh pr create --fill                  # abre um pull request com os dados dos commits
gh pr list
gh pr checkout 42                    # baixa o PR 42 para revisar localmente
gh pr merge 42 --squash
gh issue list
gh issue create

Colaborando: pull requests

Um pull request (PR) é um pedido para mesclar uma branch em outra, com espaço para revisão, comentários e verificações automáticas.

Clone ou fork?

  • Clone: você tem permissão de escrita no repositório (seu ou da sua equipe). Crie branches nele mesmo.
  • Fork: é uma cópia do repositório na sua conta. Usado para contribuir com projetos em que você não tem permissão de escrita, como projetos open source.

O fluxo completo

  1. Atualize a main e crie uma branch

    Bash
    git switch main
    git pull
    git switch -c feature/filtro-por-data
  2. Trabalhe em commits pequenos

    Bash
    git add .
    git commit -m "feat: adiciona filtro por data na listagem"
  3. Publique a branch

    Bash
    git push -u origin feature/filtro-por-data
  4. Abra o pull request

    O GitHub mostra um botão "Compare & pull request". Escreva o que mudou, por que e como testar. Use Closes #12 na descrição para fechar a issue 12 automaticamente quando o PR for mesclado. Marque como draft se ainda não estiver pronto para revisão.

  5. Responda à revisão

    Faça novos commits na mesma branch e dê git push: o PR é atualizado sozinho.

  6. Mescle e limpe

    Depois de aprovado, mescle pelo GitHub e apague a branch. Localmente:

    Bash
    git switch main
    git pull
    git branch -d feature/filtro-por-data
    git fetch --prune

As três formas de mesclar no GitHub

OpçãoResultadoQuando usar
Create a merge commitMantém todos os commits e cria um commit de mergeQuando o histórico da branch importa
Squash and mergeJunta todos os commits do PR em um sóPRs com commits de "wip" e ajustes; histórico limpo na main
Rebase and mergeReaplica os commits na main sem commit de mergeCommits já bem organizados e histórico linear

Mantendo um fork atualizado

Bash
git remote add upstream https://github.com/projeto-original/repo.git
git fetch upstream
git switch main
git merge upstream/main
git push origin main

O botão Sync fork na página do seu fork faz o mesmo pelo navegador.

Fluxos de trabalho

  • GitHub Flow: a main está sempre pronta para produção; cada mudança nasce numa branch curta e entra por PR. Simples e suficiente para a maioria dos projetos.
  • Git Flow: branches develop, release e hotfix além da main. Útil para software com versões lançadas em ciclos, mas pesado para aplicações web com deploy contínuo.
  • Trunk-based development: todos integram na main com muita frequência (branches de horas, não de semanas), usando feature flags para esconder o que não está pronto.

Recursos do GitHub que valem conhecer

  • Issues: registro de bugs, tarefas e ideias, com labels (bug, enhancement...) e milestones para agrupar por entrega.
  • Projects: quadros no estilo kanban ligados às issues e PRs.
  • Discussions: fórum para perguntas e ideias, separado das issues.
  • README.md: a página de apresentação do repositório.
  • LICENSE: sem licença, ninguém tem permissão legal de reutilizar o código. A MIT é a mais simples e permissiva.
  • CONTRIBUTING.md e templates em .github/ para padronizar issues e PRs.
  • CODEOWNERS: define quem revisa automaticamente cada parte do código.
  • Regras de proteção de branch: exigem PR, revisão e testes passando antes de mesclar na main.

Tags e releases

Tags marcam versões específicas do histórico:

Bash
git tag                                   # lista
git tag -a v1.0.0 -m "Primeira versão"    # tag anotada (com autor, data e mensagem)
git tag v1.0.1                            # tag leve (só um nome)
git push origin v1.0.0                    # tags não vão no push normal
git push origin --tags                    # envia todas
git tag -d v1.0.1                         # apaga localmente
git push origin --delete v1.0.1           # apaga no remoto

O padrão de numeração mais usado é o Semantic Versioning: MAJOR.MINOR.PATCH. Incremente o MAJOR quando quebrar compatibilidade, o MINOR ao adicionar funcionalidades compatíveis e o PATCH em correções. No GitHub, uma Release é uma tag com notas de versão e arquivos anexados.

Ferramentas avançadas

cherry-pick: trazer um commit específico

Bash
git switch main
git cherry-pick 9a0b1c2    # aplica só esse commit na branch atual

bisect: encontrando o commit que introduziu um bug

O bisect faz uma busca binária no histórico. Com 1.000 commits, você encontra o culpado em cerca de 10 passos.

Bash
git bisect start
git bisect bad                 # a versão atual tem o bug
git bisect good v1.2.0         # essa versão funcionava
# O Git faz checkout de um commit no meio. Teste e responda:
git bisect good                # ou: git bisect bad
# ... repita até o Git anunciar "abc1234 is the first bad commit"
git bisect reset               # volta para onde você estava

Se houver um script de teste que retorna 0 quando funciona, automatize: git bisect run npm test.

worktree: duas branches abertas ao mesmo tempo

Bash
git worktree add ../projeto-hotfix hotfix/pagamento   # outra pasta com outra branch
git worktree list
git worktree remove ../projeto-hotfix

Outras ferramentas

  • Submódulos (git submodule add URL pasta): um repositório dentro de outro, fixado num commit. Poderosos, mas confusos para a equipe; considere alternativas antes.
  • Git LFS: guarda arquivos grandes (vídeos, modelos, binários) fora do repositório, deixando só ponteiros no histórico.
  • Hooks: scripts executados em eventos (pre-commit, commit-msg, pre-push), na pasta .git/hooks. Em projetos JavaScript, o Husky facilita compartilhá-los com a equipe.
  • Commits assinados: provam que o commit veio de você. É possível assinar com a própria chave SSH (git config --global gpg.format ssh), e o GitHub mostra o selo "Verified".

GitHub Actions: automação e CI

Integração contínua (CI) é rodar testes e verificações automaticamente a cada push ou pull request. No GitHub, isso é feito com o GitHub Actions, configurado em arquivos YAML dentro de .github/workflows/.

.github/workflows/ci.yml
YAML
name: CI
 
on:
  push:
    branches: [main]
  pull_request:
 
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm test

Os resultados aparecem na aba Actions e como verificações no pull request. Combinado com a proteção de branch, impede que código com testes quebrados chegue à main. Outros recursos úteis: GitHub Pages (hospedagem gratuita de sites estáticos) e Dependabot (abre PRs atualizando dependências e alertando sobre vulnerabilidades).

Segurança: segredos no repositório

Nunca faça commit de senhas, tokens, chaves de API ou arquivos .env. Robôs varrem repositórios públicos atrás de credenciais em questão de minutos.

O GitHub ajuda com secret scanning e push protection, que bloqueiam o push quando detectam um token conhecido.

Erros comuns e como resolver

fatal: not a git repository. Você não está dentro de um repositório. Confira a pasta com pwd ou rode git init.

Author identity unknown / Please tell me who you are. Configure user.name e user.email com git config --global.

! [rejected] main -> main (fetch first). O remoto tem commits que você não tem. Rode git pull (resolva conflitos, se houver) e depois git push.

refusing to merge unrelated histories. Os dois históricos não têm commit em comum, geralmente porque o repositório do GitHub foi criado com README e o local foi iniciado separadamente. Se tiver certeza de que quer juntá-los: git pull origin main --allow-unrelated-histories.

You are in 'detached HEAD' state. Você fez checkout de um commit, não de uma branch. Para guardar o que fizer ali, crie uma branch: git switch -c nova-branch. Para sair: git switch main.

Permission denied (publickey). A chave SSH não está cadastrada no GitHub ou não foi carregada no agente. Teste com ssh -T git@github.com e revise a seção de SSH.

error: src refspec main does not match any. A branch main não existe localmente: ou ainda não há nenhum commit, ou a branch se chama master. Faça o primeiro commit ou use git branch -M main.

Your branch is ahead of 'origin/main' by 3 commits. Não é erro: há commits locais ainda não enviados. git push resolve.

Commitei na branch errada. Se ainda não enviou: crie a branch certa no ponto atual (git branch feature/certa), volte a atual (git reset --hard HEAD~1) e troque (git switch feature/certa).

LF will be replaced by CRLF. Aviso de conversão de finais de linha no Windows. Configure core.autocrlf e um .gitattributes como mostrado no início.

File is 120.00 MB; this exceeds GitHub's file size limit of 100.00 MB. O GitHub recusa arquivos acima de 100 MB. Remova o arquivo do histórico (não basta apagar num commit novo) e use Git LFS se precisar versioná-lo.

Tabela completa de comandos Git

Todos os comandos do guia, organizados para consulta rápida. Para situações de emergência explicadas uma a uma, veja também o artigo Git: comandos que salvam sua vida.

Cheat sheet

Git e GitHub: comandos essenciais

Do primeiro commit ao pull request.

Configuração

Uma vez por máquina

ComandoDescrição
git config --global user.name "Nome"Define seu nome nos commits
git config --global user.email "email"Define seu e-mail nos commits
git config --global init.defaultBranch mainBranch inicial main
git config --global core.editor "code --wait"VS Code como editor
git config --global core.autocrlf trueFinais de linha (Windows)
git config --global pull.rebase falsepull faz merge
git config --global alias.lg "log --oneline --graph --all"Cria um atalho
git config --list --show-originMostra tudo e de onde veio

Criar e clonar

Começando um repositório

ComandoDescrição
git initCria repositório na pasta atual
git clone URLCopia um repositório remoto
git clone URL pastaClona em outra pasta
git clone --depth 1 URLSó o último commit (mais rápido)
gh repo clone usuario/repoClona com o GitHub CLI

Ciclo básico

O dia a dia

ComandoDescrição
git statusEstado dos arquivos
git status -sEstado resumido
git add arquivoPrepara um arquivo
git add .Prepara tudo
git add -pPrepara trecho por trecho
git commit -m "mensagem"Grava o commit
git commit -am "mensagem"Add + commit dos rastreados
git rm arquivoRemove e prepara a remoção
git rm --cached arquivoPara de rastrear, mantém o arquivo
git mv antigo novoRenomeia

Inspecionar histórico

O que mudou, quando e quem

ComandoDescrição
git log --onelineHistórico resumido
git log --oneline --graph --allÁrvore de todas as branches
git log -p arquivoMudanças de um arquivo
git log --author="Ana"Commits de uma pessoa
git log -S "texto"Commits que mexeram nesse texto
git diffMudanças não preparadas
git diff --stagedMudanças preparadas
git diff main..featureDiferença entre branches
git show HASHDetalhes de um commit
git blame arquivoAutor de cada linha
git shortlog -snCommits por autor

Desfazer mudanças

Do mais seguro ao mais destrutivo

ComandoDescrição
git restore arquivoDescarta mudanças no arquivo
git restore --staged arquivoTira da staging area
git commit --amend -m "msg"Corrige o último commit
git commit --amend --no-editInclui arquivo esquecido
git reset --soft HEAD~1Desfaz commit, mantém preparado
git reset HEAD~1Desfaz commit, mantém no working tree
git reset --hard HEAD~1Desfaz commit e descarta mudanças
git revert HASHNovo commit que desfaz outro
git reflogHistórico do HEAD (recuperação)
git clean -n / git clean -fdSimula / apaga não rastreados

Branches

Linhas de trabalho independentes

ComandoDescrição
git branchLista branches locais
git branch -aInclui as remotas
git branch -vvMostra upstream e diferença
git switch -c nomeCria e troca
git switch nomeTroca de branch
git switch -Volta para a anterior
git branch -m novo-nomeRenomeia a atual
git branch -d nomeApaga (se mesclada)
git branch -D nomeApaga à força
git checkout -b nomeForma antiga de criar e trocar

Merge

Juntando branches

ComandoDescrição
git merge featureMescla na branch atual
git merge --no-ff featureSempre cria commit de merge
git merge --squash featureJunta tudo num commit só
git merge --abortCancela um merge com conflito
git diff --name-only --diff-filter=UArquivos em conflito
git mergetoolAbre a ferramenta de merge

Rebase

Reescrevendo a base (só local)

ComandoDescrição
git rebase mainReaplica sua branch sobre a main
git rebase -i HEAD~3Edita os últimos 3 commits
git rebase --continueSegue após resolver conflito
git rebase --skipPula o commit atual
git rebase --abortCancela o rebase
git pull --rebaseAtualiza com rebase

Stash

Guarde mudanças temporariamente

ComandoDescrição
git stashGuarda as mudanças
git stash push -m "nome"Guarda com descrição
git stash -uInclui não rastreados
git stash listLista o que foi guardado
git stash popReaplica e remove da pilha
git stash apply stash@{1}Reaplica sem remover
git stash drop stash@{0}Descarta um item
git stash clearApaga todos

Remotos e sincronização

Conversando com o GitHub

ComandoDescrição
git remote -vLista os remotos
git remote add origin URLAdiciona remoto
git remote set-url origin URLTroca a URL
git fetchBaixa sem mesclar
git fetch --pruneLimpa branches remotas apagadas
git pullBaixa e mescla
git pushEnvia commits
git push -u origin nomeEnvia e define upstream
git push origin --delete nomeApaga branch remota
git push --force-with-leaseForce push seguro

Tags e releases

Marcando versões

ComandoDescrição
git tagLista tags
git tag -a v1.0.0 -m "msg"Cria tag anotada
git push origin v1.0.0Envia uma tag
git push origin --tagsEnvia todas as tags
git tag -d v1.0.0Apaga localmente
git push origin --delete v1.0.0Apaga no remoto
gh release create v1.0.0Cria release no GitHub

Ferramentas avançadas

Para situações específicas

ComandoDescrição
git cherry-pick HASHAplica um commit específico
git bisect startInicia a caça ao commit do bug
git bisect good / git bisect badMarca o commit testado
git bisect resetEncerra o bisect
git worktree add ../pasta branchOutra branch em outra pasta
git submodule update --initBaixa os submódulos
git lfs track "*.psd"Versiona arquivos grandes com LFS
git gcCompacta o repositório

GitHub CLI

O GitHub no terminal

ComandoDescrição
gh auth loginAutentica
gh repo create nome --private --source=. --pushCria e envia
gh pr create --fillAbre pull request
gh pr listLista PRs
gh pr checkout 42Baixa o PR 42
gh pr merge 42 --squashMescla o PR
gh issue createCria issue
gh issue listLista issues
gh run listExecuções do Actions

SSH e autenticação

Acesso sem senha

ComandoDescrição
ssh-keygen -t ed25519 -C "email"Gera chave SSH
ssh-add ~/.ssh/id_ed25519Carrega no agente
cat ~/.ssh/id_ed25519.pubMostra a chave pública
ssh -T git@github.comTesta a conexão
git remote set-url origin git@github.com:u/r.gitMuda o remoto para SSH
git config --global gpg.format sshAssina commits com SSH

Referências e leituras recomendadas

Se você trabalha no terminal, o guia completo de Linux complementa este.

Teste seus conhecimentos
1 / 7

7 perguntas sobre Git e GitHub.

Qual a diferença entre git fetch e git pull?

Não foi dessa vez. Explicação:

git pull é um git fetch seguido de merge (ou rebase) na branch atual.