Git + GitHub
Guia de apresentação para equipe Webinar 45 min 2 partes
O que é Git 5 min
Git é um sistema de controle de versão distribuído — um software que rastreia todas as mudanças feitas em um conjunto de arquivos ao longo do tempo, permitindo voltar a qualquer versão anterior e colaborar com outras pessoas sem sobrescrever o trabalho de ninguém.
A origem — 2005
Linus Torvalds — criador do Linux — tinha requisitos claros: velocidade, design simples, suporte a desenvolvimento não-linear (milhares de branches paralelos), totalmente distribuído e capaz de lidar com projetos grandes como o kernel do Linux de forma eficiente.
Em 10 dias, Linus escreveu o núcleo do Git. Em 2 semanas, o próprio kernel do Linux já estava sendo gerenciado por ele.
O problema que Git resolve
Distribuído vs Centralizado
Como o versionamento realmente funciona 5 min
A maioria dos VCS armazena diferenças (diffs) entre versões. Git funciona de forma radicalmente diferente: armazena snapshots completos do projeto a cada commit.
Snapshots vs Diffs
Para ver v3, reconstrói somando todos os deltas. Lento para histórico longo.
Arquivos não modificados viram ponteiros para versão anterior. Acesso direto a qualquer versão.
SHA-1 — Endereçamento por conteúdo
Cada objeto no Git tem um identificador único: o hash SHA-1 do seu conteúdo. Isso significa que dois arquivos com conteúdo idêntico sempre terão o mesmo hash — Git os armazena apenas uma vez (deduplicação automática). Se o hash bate, o conteúdo é garantidamente idêntico.
# Git calcula SHA-1 de cada objeto antes de armazenar
echo "hello" | git hash-object --stdin
# → ce013625030ba8dba906f756967f9e9ca394464a
# Cada commit, tree e blob tem um SHA único
git log --oneline
# a3f9c2e feat: adiciona autenticação
# 7b14d01 fix: corrige validação de email
# 9a2c88f chore: setup inicial do projeto
Modelo de Objetos do Git 5 min
Git é, na essência, um banco de dados de chave-valor endereçado por conteúdo. Armazena quatro tipos de objeto — juntos, eles representam todo o histórico do projeto.
Armazena o conteúdo de um arquivo. Não guarda o nome — só os dados. Dois arquivos com conteúdo igual compartilham o mesmo blob (sem duplicação).
Representa um diretório. Contém entradas com SHA-1, permissão, tipo e nome de cada arquivo/subdiretório. Forma a hierarquia de pastas.
Um snapshot completo do projeto em um momento. Aponta para a tree raiz, para o(s) commit(s) pai(s) — formando a cadeia de histórico — e guarda autor, timestamp e mensagem.
Marca um ponto específico do histórico (normalmente um commit de release). Inclui nome do criador, data e mensagem. Pode ser assinada com GPG para garantir autenticidade.
Estrutura de Armazenamento 5 min
Git divide o trabalho em três zonas distintas. Entender onde cada mudança está é fundamental para usar Git com precisão.
.git/.Ciclo de vida de um arquivo
# Ver estado atual
git status
# Adicionar arquivo específico ao stage
git add src/auth.js
# Adicionar partes específicas de um arquivo (interativo)
git add -p src/auth.js
# Ver o que está staged (será commitado)
git diff --staged
# Ver o que está modificado mas ainda não staged
git diff
# Criar o commit
git commit -m "feat: adiciona autenticação JWT"
# Atalho: add + commit de todos os rastreados
git commit -am "fix: corrige validação de email"
Ciclo de Vida do Código 6 min
Branch — um ponteiro leve
Um branch no Git é apenas um arquivo de texto contendo 41 bytes — o SHA-1 do commit que ele aponta. Criar um branch é instantâneo e não duplica nada. HEAD é um ponteiro especial que indica qual branch está ativo no momento.
# Criar e mudar para novo branch
git switch -c feature/autenticacao # Git 2.23+ (recomendado)
git checkout -b feature/autenticacao # forma clássica
# Ver todos os branches
git branch -a
# Visualizar o grafo de commits
git log --oneline --decorate --graph --all
Commit — snapshot identificado
Um commit é uma fotografia completa do projeto naquele momento, identificada por um SHA-1 único. Contém: referência à tree raiz (o diretório do projeto), referência ao(s) commit(s) pai(s) — formando a cadeia de histórico — autor, timestamp e mensagem.
Cadeia de pais — o que é o histórico
Todo commit aponta para o commit anterior (seu "pai"). Essa cadeia é o histórico. Git não guarda diffs — guarda snapshots. Diff é calculado comparando o snapshot do commit com o snapshot do pai.
A ← B ← C ← D (HEAD)
# D tem pai C · C tem pai B · B tem pai A
# A não tem pai → primeiro commit do repo
Merge commit tem 2 pais. O objeto armazena ambas as referências SHA:
tree abc123
parent f1e2d3 ← pai 1 (branch atual)
parent 9a8b7c ← pai 2 (branch mergeada)
# git log --graph mostra:
* D (merge) — pai1=B, pai2=C
|\
| * C — pai=A
* | B — pai=A
|/
* A
Durante conflitos de merge, Git disponibiliza as três versões:
git show :1:arquivo # ancestral comum (base)
git show :2:arquivo # versão pai 1
git show :3:arquivo # versão pai 2
# Boas mensagens de commit (Conventional Commits)
git commit -m "feat: adiciona login com Google OAuth"
git commit -m "fix: corrige timeout na chamada de API"
git commit -m "docs: atualiza README com instruções de setup"
git commit -m "refactor: extrai lógica de validação para helper"
# Ver detalhes de um commit
git show a3f9c2e
# Histórico com estatísticas
git log --stat --oneline
Merge — integrando branches
Git tem duas estratégias principais de merge, dependendo da situação:
Git simplesmente avança o ponteiro do branch de destino. Nenhum commit de merge é criado. O histórico fica linear como se o trabalho tivesse sido feito diretamente no branch.
main: A ─ B ─ C
feature: C ─ D ─ E
# após merge → main aponta para E
Git usa três pontos: a ponta do branch atual, a ponta do branch a ser mergeado e o ancestral comum. Cria um merge commit com dois pais, preservando a história dos dois branches.
main: A ─ B ─ C ─────── M
feature: └─ D ─ E ─┘
Conflitos de merge
Quando dois branches modificam as mesmas linhas do mesmo arquivo, Git não sabe qual versão preservar e pausa o processo com marcadores de conflito:
<<<<<<< HEAD (sua versão)
return user.authenticate(token)
=======
return user.validateToken(token, options)
>>>>>>> feature/auth (versão sendo mergeada)
# 1. Editar o arquivo — remover marcadores, escolher (ou combinar) versões
# 2. Marcar como resolvido
git add src/auth.js
# 3. Finalizar o merge
git commit
Merge vs Rebase 4 min
Ambos integram mudanças de um branch em outro. A diferença está em como o histórico é escrito.
main: A ─ B ─ C ─── M
feature: └─ D ─┘
# M tem dois pais: C e D
antes: main: A ─ B ─ C
feat: B ─ D
após: main: A ─ B ─ C ─ D'
# D' é D reescrito sobre C
# Fluxo típico com rebase (atualizar feature antes do PR)
git switch feature/auth
git fetch origin
git rebase origin/main # replay dos commits da feature sobre o main atual
# Se conflito:
# 1. resolver conflito
git add arquivo-resolvido
git rebase --continue # continua para o próximo commit
# ou
git rebase --abort # desiste do rebase
# Merge final (no GitHub isso vira PR)
git switch main
git merge feature/auth # agora é fast-forward, sem merge commit
Worktree — múltiplos checkouts 3 min
git worktree permite ter múltiplos diretórios de trabalho ativos ao mesmo tempo, todos conectados ao mesmo repositório Git (.git/). Você pode ter dois branches abertos em diretórios separados, sem stash, sem clonar novamente.
Quando usar
Você está no meio de uma feature. Chega um bug crítico em produção. Sem worktree, precisaria de stash ou de um clone separado:
# Criar um worktree para o hotfix em um diretório separado
git worktree add ../hotfix-1234 main
# Agora você tem:
# ~/projeto/ → sua feature em andamento (intacta)
# ~/hotfix-1234/ → branch main, para corrigir o bug
# Depois de corrigir e commitar no hotfix-1234:
git worktree remove ../hotfix-1234
# Listar todos os worktrees ativos
git worktree list
# Criar worktree com branch novo
git worktree add -b fix/login-timeout ../fix-login main
| Abordagem | Repositório | Branches simultâneos | Uso de disco |
|---|---|---|---|
| git worktree | Único .git compartilhado | Sim, N diretórios | Mínimo |
| git clone | Repositório separado | Um por clone | Alto (duplica tudo) |
| git stash | Mesmo repo | Não (salva temporariamente) | Mínimo |
Resumo dos Comandos Principais 3 min
git config --global user.nameDefine nome do autorgit config --global user.emailDefine email do autorgit initInicia repositório no diretório atualgit clone <url>Clona repositório remotogit statusEstado atual do repositóriogit add <arquivo>Adiciona arquivo ao stagegit add -pStage interativo por partes (hunks)git commit -m "msg"Cria commit com mensagemgit diffMudanças não stagedgit diff --stagedMudanças staged (será commitado)git log --oneline --graphHistórico visual compactogit show <sha>Detalhes de um commitgit switch -c <branch>Cria e muda para branchgit switch <branch>Muda para branch existentegit branch -d <branch>Deleta branch (seguro)git merge <branch>Integra branch no atualgit rebase <branch>Replay commits sobre outro branchgit cherry-pick <sha>Aplica commit específico no branch atualgit restore <arquivo>Descarta mudanças no working dirgit restore --staged <arquivo>Remove do stage (mantém mudança)git revert <sha>Cria commit que desfaz outro (seguro)git stashSalva mudanças temporariamentegit stash popRestaura último stashgit reset --soft HEAD~1Desfaz commit, mantém no stagegit remote -vLista remotos configuradosgit fetch originBaixa mudanças sem integrargit pullfetch + merge (ou rebase)git push origin <branch>Envia branch para remotoO que é GitHub 3 min
GitHub é uma plataforma de hospedagem de repositórios Git na nuvem, combinada com ferramentas de colaboração, automação e gerenciamento de projeto. É o maior host de código do mundo: mais de 100 milhões de desenvolvedores e mais de 420 milhões de repositórios.
Em 2018, a Microsoft adquiriu o GitHub por US$ 7,5 bilhões. Desde então, investiu significativamente na plataforma — GitHub Actions, Codespaces, Copilot — mantendo-a independente e open-source-friendly.
Git resolve o controle de versão local e distribuído. GitHub resolve a camada de colaboração: onde o código vive na nuvem, como pessoas trabalham juntas, como mudanças são revisadas antes de entrar no projeto, como automações são disparadas.
Integração Git ↔ GitHub 3 min
Commits, branches, histórico.
Origin (upstream) do projeto.
Configurar o remote
# Ligar repositório local ao GitHub (novo repo)
git remote add origin git@github.com:usuario/repo.git
# Verificar remotes
git remote -v
# Enviar branch pela primeira vez
git push -u origin main # -u define upstream (lembra o tracking)
# Próximos pushes nesse branch
git push
# Baixar mudanças sem integrar (recomendado)
git fetch origin
git merge origin/main # ou: git rebase origin/main
# Atalho: fetch + merge/rebase
git pull --rebase origin main
SSH vs HTTPS
| Protocolo | Autenticação | Recomendado para |
|---|---|---|
SSH |
Chave pública/privada (~/.ssh) | Uso diário — sem senha, seguro |
HTTPS |
Token de acesso pessoal (PAT) | CI/CD, ambientes sem SSH, scripts |
# Gerar chave SSH
ssh-keygen -t ed25519 -C "seu@email.com"
# Exibir chave pública (colar no GitHub → Settings → SSH keys)
cat ~/.ssh/id_ed25519.pub
# Testar conexão
ssh -T git@github.com
# → Hi usuario! You've successfully authenticated.
Vantagens da Integração 2 min
Recursos do GitHub 5 min
fixes #42 em um PR fecha a issue automaticamente no merge.Branch Protection — configurações principais
| Regra | O que protege |
|---|---|
Require pull request reviews |
Exige N aprovações antes do merge |
Require review from Code Owners |
CODEOWNERS devem aprovar PRs que tocam seus arquivos |
Dismiss stale reviews |
Invalida aprovações quando novo código é adicionado |
Require status checks |
CI/CD deve passar antes do merge |
Require linear history |
Proíbe merge commits — força squash ou rebase |
Prevent force push |
Bloqueia git push --force no branch |
Prevent deletion |
Impede deleção acidental do branch |
Include administrators |
Aplica as regras também para admins (sem exceções) |
CODEOWNERS — exemplo
# .github/CODEOWNERS
# Última regra que corresponde tem precedência
* @org/equipe-geral # qualquer arquivo
*.js *.ts @fulano @ciclana # arquivos JS/TS
/docs/ @org/equipe-docs # pasta docs
src/auth/ @org/equipe-seguranca # autenticação
.github/CODEOWNERS @org/admin # o próprio CODEOWNERS
Code Review Workflow 4 min
O workflow de code review no GitHub é construído ao redor dos Pull Requests. É o processo que garante que código seja revisado, discutido e aprovado antes de entrar no branch principal.
Tipos de Review
Estratégias de Merge no PR
| Estratégia | Resultado | Quando usar |
|---|---|---|
Merge commit |
Preserva todos os commits + merge commit | Branches com histórico valioso |
Squash and merge |
Comprime tudo em 1 commit no main | Features com commits de rascunho |
Rebase and merge |
Replay linear, sem merge commit | Histórico limpo, commits bem escritos |
GitHub CLI 3 min
gh é a CLI oficial do GitHub. Permite interagir com Issues, PRs, repos e Actions diretamente do terminal, sem abrir o browser.
# Instalar (Debian/Ubuntu)
sudo apt install gh
# Autenticar (abre browser)
gh auth login
# Verificar autenticação
gh auth status
Repositórios
gh repo create | Cria repositório (interativo ou com flags) |
gh repo clone usuario/repo | Clona repositório |
gh repo fork | Faz fork do repositório atual |
gh repo view --web | Abre repositório no browser |
gh repo sync | Sincroniza fork com upstream |
Issues
gh issue create | Cria issue (interativo) |
gh issue list | Lista issues abertas |
gh issue view 42 | Ver detalhes da issue #42 |
gh issue comment 42 -b "texto" | Comentar na issue |
gh issue close 42 | Fechar issue |
Pull Requests
gh pr create | Cria PR (interativo, com título e body) |
gh pr list | Lista PRs abertos |
gh pr view 15 | Ver detalhes do PR #15 |
gh pr checkout 15 | Faz checkout local do branch do PR |
gh pr review 15 --approve | Aprova o PR |
gh pr review 15 --request-changes -b "msg" | Solicita mudanças |
gh pr merge 15 --squash | Merge com squash |
gh pr diff 15 | Ver diff do PR no terminal |
# Fluxo completo com gh CLI
git switch -c feature/nova-autenticacao
# ... commits ...
gh pr create --title "feat: nova autenticação OAuth" \
--body "Implementa login com Google. Fecha #38." \
--assignee @me \
--label "feature"
# Outro desenvolvedor revisa:
gh pr checkout 22
gh pr review 22 --approve --body "LGTM, excelente trabalho"
# Merge após aprovações
gh pr merge 22 --squash --delete-branch
gh respeita o repositório do diretório atual. Em qualquer pasta git com remote no GitHub, os comandos gh pr list, gh issue list etc. operam no repositório correto automaticamente.
Fim da apresentação
Guias de referência completos disponíveis: