Competições Senac RS · Seletiva 26
Módulo 02 · Apostila teórica
Módulo 02 — Ambiente, ferramentas e versionamento
Por que começar por aqui. Ambiente e versionamento não dão glória, mas dão base. Um ambiente afiado faz você trabalhar rápido nas 10h30 de prova, e o versionamento bem feito vale 5% da nota e, mais importante, é a rede de segurança: se algo quebra, você volta pra versão que funcionava em segundos. Tem ainda um terceiro papel que quase ninguém enxerga: o histórico do Git é evidência pra banca. Um histórico que conta a história do projeto mostra método, e método é o que a avaliação de julgamento procura. Esse é o primeiro assunto do treinamento (Seg 03/08) porque tudo que vem depois passa por ele: o banco vai ser versionado, a API vai ser versionada, o front vai ser versionado.
1. O ambiente das duas stacks
A gente treina com duas stacks de back-end (Node.js + Express e PHP), as duas falando com MySQL, e um front único em HTML/CSS/JS. Na prova você usa a que estiver liberada e mais afiada. O ambiente precisa estar pronto e idêntico nas duas máquinas: mesma versão de tudo, mesmas extensões, mesmos atalhos. Máquinas diferentes geram o clássico "na minha funciona", que é tempo perdido.
1.1 O que instala e como conferir
| Ferramenta | Pra quê | Como conferir que funciona |
|---|---|---|
| Node.js LTS (traz o npm junto) | Runtime do back em JavaScript | node -v e npm -v respondem versão |
| PHP 8+ | Runtime do back em PHP | php -v responde versão |
| Composer | Gerenciador de pacotes do PHP | composer -V responde versão |
| MySQL Server 8 | O banco das duas stacks | mysql -u root -p loga no console |
| MySQL Workbench (ou DBeaver) | Ver tabelas e dados sem decorar console | Conecta no servidor local |
| Git | Versionamento | git --version responde versão |
| VS Code | Editor | Abre, formata, tem as extensões da tabela 1.2 |
| Postman (ou Insomnia) | Testar a API sem depender do front | Faz um GET em qualquer URL pública |
| Navegador com DevTools | Console, aba Network, inspecionar elemento | F12 abre e você sabe onde está cada aba |
Depois de instalar, configurar o Git uma vez (identidade que assina cada commit):
git config --global user.name "Seu Nome"
git config --global user.email "seu@email.com"
git config --global init.defaultBranch main
🛠️ Gambiarra boa: o servidor embutido do PHP. Não precisa de Apache nem XAMPP configurado pra desenvolver: php -S localhost:8000 na pasta do projeto sobe um servidor local na hora. Pra prova e pra treino é mais que suficiente, e elimina uma camada inteira de configuração que pode dar problema.
🛠️ Gambiarra boa: nodemon no Node. npm install --save-dev nodemon e rodar com npx nodemon app.js: o servidor reinicia sozinho a cada arquivo salvo. Sem isso você vai esquecer de reiniciar depois de uma mudança e perder minutos caçando um bug que não existe.
1.2 VS Code: extensões e configurações que pagam o tempo investido
Extensão é ferramenta, não enfeite. As que valem pra nossa realidade:
| Extensão | Pra quê |
|---|---|
| Prettier | Formata HTML/CSS/JS num padrão único com um atalho |
| PHP Intelephense | Autocompletar e destaque de erro pra PHP |
| Live Server | Sobe o front com recarga automática ao salvar |
| ESLint | Aponta erro de JS antes de você rodar |
| GitLens (opcional) | Mostra quem mudou cada linha e quando, direto no editor |
Duas configurações que mudam o jogo (Ctrl+, abre as configurações):
- Format On Save ligado: todo arquivo sai formatado sem você pensar nisso. Código formatado é um dos itens mais baratos de organização que a banca enxerga.
- Auto Save em
onFocusChange: nunca mais "mas eu tinha certeza que salvei".
1.3 Atalhos: velocidade que vira escopo entregue
Boa parte da velocidade de dev é não usar o mouse pra tudo. Os que valem treinar até virarem automáticos:
| Atalho (Windows) | O que faz |
|---|---|
Ctrl+P |
Abre qualquer arquivo pelo nome, sem caçar na árvore |
Ctrl+D |
Seleciona a próxima ocorrência igual (multi-cursor) |
Alt+clique |
Cria cursores em vários pontos ao mesmo tempo |
F2 |
Renomeia a variável/função no projeto inteiro |
Ctrl+Shift+F |
Busca em todos os arquivos do projeto |
Shift+Alt+F |
Formata o arquivo inteiro |
Ctrl+' (crase) |
Abre o terminal dentro do editor |
Ctrl+B |
Esconde/mostra a barra lateral (mais tela pro código) |
🎯 Isso conta na prática. Cada minuto que você não gasta caçando arquivo com o mouse é um minuto pro Módulo C, que é onde a nota está. Produtividade de ambiente não aparece direto na planilha, mas aparece indireto: em quanto do escopo você conseguiu terminar.
1.4 O fluxo de montagem: subir um projeto do zero
Nos primeiros minutos da prova, quem tem o caminho de montagem decorado sai na frente. Não é decorar código, é decorar o fluxo. As duas sequências, lado a lado:
Node.js + Express:
mkdir wedding-pass && cd wedding-pass
git init
npm init -y
npm install express mysql2
npm install --save-dev nodemon
# cria app.js com o esqueleto do servidor
# cria .gitignore (seção 5)
git add .
git commit -m "estrutura inicial do projeto Node com Express e mysql2"
PHP:
mkdir wedding-pass && cd wedding-pass
git init
mkdir public src
# cria public/index.php com o roteador básico
# cria src/conexao.php com o PDO
# cria .gitignore (seção 5)
git add .
git commit -m "estrutura inicial do projeto PHP com PDO"
php -S localhost:8000 -t public
O esqueleto de código de cada uma (servidor mínimo, conexão com o banco) é assunto do módulo 04. Aqui o ponto é o ritual: pasta → git init → esqueleto → .gitignore → primeiro commit. Sempre nessa ordem, sempre com o Git nascendo junto com o projeto, nunca depois.
⚠️ Pega-ratão: deixar o git init "pra quando o projeto estiver andando". O versionamento só protege o que ele viu acontecer. Projeto que nasce sem Git tem uma janela inteira de trabalho sem rede de segurança e sem evidência.
2. Versionamento: a máquina do tempo (e a testemunha)
Versionamento é a máquina do tempo do código. Cada vez que você salva um marco (um commit), o Git guarda uma foto do projeto inteiro naquele instante. Você pode voltar pra qualquer foto, comparar o que mudou entre duas, e trabalhar em ideias novas sem medo de estragar o que já funciona.
No mercado isso é inegociável: nenhum time trabalha sem controle de versão. Na prova, são três papéis ao mesmo tempo:
- Rede de segurança. Quebrou tudo às 3h40 de prova? Volta pro último commit que funcionava e perde minutos, não a prova.
- Competência avaliada. Os 5% de configuração e versionamento saem direto da qualidade do teu repositório.
- Evidência de método. A banca pode ler o histórico. Vinte commits pequenos com mensagens claras contam a história de alguém que trabalha com método. Um commit gigante "projeto final" não conta história nenhuma.
3. Os três estados: como o Git enxerga teus arquivos
Aqui mora a base de tudo. Todo arquivo num repositório Git está em um de três lugares:
Working Directory ──git add──▶ Staging Area ──git commit──▶ Repositório
(teus arquivos, (a "área de (histórico
como estão agora) embarque": permanente
o que vai entrar de commits)
no próximo commit)
- Working directory: os arquivos como estão no teu disco agora, com tudo que você editou e ainda não marcou pra salvar.
- Staging area (área de preparação): a lista do que vai entrar no próximo commit. É uma área de embarque: você escolhe o que sobe.
- Repositório: o histórico permanente. O que foi commitado está guardado e tem um endereço (o hash).
Os comandos que movem os arquivos entre os estados:
git status # onde está cada arquivo agora (o comando mais usado do Git)
git add arquivo.js # move arquivo do working pra staging
git add . # move tudo que mudou pra staging
git commit -m "mensagem" # grava a staging no histórico
git diff # o que mudou e AINDA NÃO está na staging
git diff --staged # o que está na staging e vai entrar no próximo commit
⚠️ Pega-ratão clássico dos três estados: editar um arquivo, dar git add, editar o mesmo arquivo de novo e commitar. O commit leva a versão que estava na staging na hora do add, não a mais recente do disco. O git status mostra o arquivo nas duas listas ao mesmo tempo ("staged" e "modified") quando isso acontece. Regra prática: git status antes de todo commit, sempre.
🛠️ Gambiarra boa: staging seletiva pra commits limpos. Mexeu em três coisas diferentes de uma vez (aconteceu, não era o ideal)? Não precisa commitar tudo junto num commit bagunçado. git add só dos arquivos de uma mudança, commita com a mensagem certa, depois add e commit do resto. O histórico sai limpo mesmo quando o trabalho não foi.
4. Commits que contam história
4.1 A anatomia de um commit
Cada commit guarda: um hash (o endereço único, tipo a3f9c21), o autor (o user.name e user.email que você configurou), a data, a mensagem, e um ponteiro pro commit anterior. Essa corrente de ponteiros é o histórico. Pra ver:
git log # histórico completo, um bloco por commit
git log --oneline # uma linha por commit (o dia a dia)
git log --oneline --graph --all # o desenho dos branches (seção 7)
4.2 O que faz uma mensagem boa
Uma boa mensagem completa a frase "este commit...": começa com verbo no presente, diz o que mudou e, quando não for óbvio, por quê. É escrita pra alguém ler daqui a duas semanas (e esse alguém é você, ou a banca).
| ❌ Mensagem ruim | ✅ Mensagem boa |
|---|---|
att |
adiciona validação de e-mail no cadastro de convidado |
ajustes |
corrige capacidade da mesa que aceitava número negativo |
wip |
cria tela de login com feedback de erro |
agora vai |
corrige check-in duplicado: valida antes de inserir |
mudanças no banco |
adiciona UNIQUE em convite pra impedir RSVP duplo |
Um padrão leve de prefixo ajuda a bater o olho no git log --oneline e entender o histórico (o mercado chama de conventional commits; pra nós, a versão enxuta basta):
feat:funcionalidade nova (feat: adiciona dashboard de ocupação)fix:correção de bug (fix: corrige mesa que estourava a capacidade)style:só visual/CSS (style: alinha cards do dashboard no grid)refactor:melhora sem mudar comportamento (refactor: extrai validação pra função própria)docs:documentação (docs: adiciona dicionário de dados)
🎯 Frequência é critério de julgamento. Não existe número mágico, mas existe um ritmo: um commit por marco que funciona. Fechou o login? Commit. O CRUD respondeu? Commit. A tela renderizou certo? Commit. Numa prova de 4 horas isso dá naturalmente algo entre 8 e 15 commits, e um histórico assim é a diferença entre nota 1 e nota 3 no critério.
🛠️ Gambiarra boa: commit é checkpoint de videogame. Toda vez que uma parte passa a funcionar, commita antes de começar a próxima. Se a mudança seguinte quebrar tudo, git restore . te devolve pro último checkpoint em dois segundos (seção 6). Sob pressão de prova, esse hábito já salvou muita gente de refazer uma hora de trabalho.
5. .gitignore: o que nunca entra no repositório
Nem tudo que está na pasta do projeto deve ser versionado. Três categorias ficam de fora:
- O que é gerado/baixado:
node_modules/(Node) evendor/(PHP) são reconstruíveis comnpm install/composer install. Versionar isso incha o repositório com milhares de arquivos que não são teus. - O que é segredo: arquivo
.envcom senha do banco e chave do JWT. Nunca entra no Git. - O que é lixo do sistema:
.DS_Store,Thumbs.db, logs.
O .gitignore é um arquivo de texto na raiz do projeto listando o que o Git deve fingir que não existe. O nosso, que serve pras duas stacks:
node_modules/
vendor/
.env
*.log
.DS_Store
Thumbs.db
⚠️ Pega-ratão: o .gitignore não é retroativo. Se você commitou o node_modules/ e depois criou o .gitignore, o Git continua rastreando o que já entrou. Pra tirar do rastreio sem apagar do disco: git rm -r --cached node_modules/ e commita. Por isso o .gitignore nasce no primeiro commit, junto com o projeto (o fluxo da seção 1.4).
🎯 Senha commitada é ponto perdido em segurança. Se a banca abre o repositório e encontra a senha do banco num commit, isso conversa direto com os critérios de segurança (módulo 04). Configuração sensível vai no .env, o .env vai no .gitignore, e o projeto ganha um .env.example versionado só com os nomes das variáveis, sem os valores.
6. Desfazer sem drama
Errar faz parte; o Git existe pra isso. O mapa de "deu ruim → comando":
| Situação | Comando | O que acontece |
|---|---|---|
| Editei um arquivo e me arrependi (não commitei) | git restore arquivo.js |
Arquivo volta a ser como no último commit. A edição se perde. |
| Quebrei tudo, quero voltar pro último checkpoint | git restore . |
Todos os arquivos voltam pro último commit |
Dei git add sem querer |
git restore --staged arquivo.js |
Sai da staging, a edição continua no disco |
| Errei a mensagem do commit que acabei de fazer | git commit --amend -m "mensagem certa" |
Reescreve o último commit |
| Quero ver como o projeto estava num commit antigo | git log --oneline + git diff a3f9c21 |
Compara o agora com aquele ponto |
| Um commit antigo introduziu um bug | git revert a3f9c21 |
Cria um commit novo desfazendo aquele. O histórico fica intacto |
⚠️ Pega-ratão: git reset --hard. Esse comando existe e você vai ver na internet. Ele apaga commits e mudanças de verdade, sem lixeira. Na prova, o desfazer seguro é git restore (pra mudanças) e git revert (pra commits): os dois nunca destroem histórico. reset --hard só com o professor do lado e certeza absoluta.
7. Branch: linhas de trabalho paralelas
7.1 O conceito
Um branch é uma linha de trabalho paralela. Tecnicamente é só um ponteiro pra um commit (por isso criar branch é instantâneo e de graça), mas na prática é isso: você cria um branch pra desenvolver uma funcionalidade nova sem tocar na versão estável. A main é o tronco, a versão que sempre funciona e da qual sai a demo.
git branch # lista os branches (o * mostra onde você está)
git switch -c feature/check-in # cria o branch E já muda pra ele
git switch main # volta pra main
git branch -d feature/check-in # apaga o branch (depois do merge)
Nomes que se explicam: feature/rsvp-convidado, feature/dashboard, fix/capacidade-mesa. O prefixo diz o tipo, o resto diz o assunto.
7.2 O fluxo que a prova valoriza
O padrão profissional, que é o mesmo que o CIS quer ver:
- A
mainestá funcionando. Nunca se desenvolve funcionalidade nova direto nela. git switch -c feature/nome-da-funcionalidade- Trabalha ali, commitando em marcos pequenos.
- Funcionou e foi testado?
git switch mainegit merge feature/nome-da-funcionalidade. - A
maincontinua sempre apresentável, e é dela que sai a demo do Módulo D.
🎯 No nosso cronograma isso tem endereço. No primeiro dia (Seg 03/08) a gente organiza a main e a main-teste de cada uma: a main é o tronco sagrado, e a main-teste é o branch de experimento, onde vale testar ideia, quebrar e bagunçar sem medo. E na semana de 14 a 18/09, o comprovante em PDF nasce num branch com merge de propósito, pra rotina de branch → commit → merge estar no músculo bem antes da prova.
8. Merge: juntando as linhas (e resolvendo o conflito real)
8.1 Os dois tipos de merge
Fast-forward: a main não andou desde que o branch nasceu. O Git só desliza o ponteiro pra frente. Sem drama, sem commit extra:
main: A──B
\
feature: C──D → merge → main: A──B──C──D
Merge commit (three-way): a main também andou enquanto o branch existia. O Git cria um commit de merge que junta as duas linhas:
main: A──B──────E
\ \
feature: C──D──M ← commit de merge
Os dois são normais e corretos. O merge commit ainda tem um bônus: aparece no git log --graph como prova visual de que você trabalhou com branches.
8.2 Conflito: o que é de verdade
Conflito acontece quando as duas linhas de trabalho mexeram na mesma região do mesmo arquivo e o Git não tem como decidir sozinho qual versão fica. Não é erro, não é castigo: é o Git pedindo uma decisão humana.
Cenário concreto no Wedding Pass: na main você ajustou o limite de convidados por mesa pra 8 no config.js; no branch feature/dashboard, o mesmo arquivo ganhou o limite 10. Na hora do merge:
$ git merge feature/dashboard
Auto-merging config.js
CONFLICT (content): Merge conflict in config.js
Automatic merge failed; fix conflicts and then commit the result.
O Git marca o trecho conflitado dentro do arquivo:
<<<<<<< HEAD
const LIMITE_MESA = 8; // o que está na main (onde você está)
=======
const LIMITE_MESA = 10; // o que veio do branch
>>>>>>> feature/dashboard
8.3 Resolvendo, passo a passo
- Respira. O projeto não quebrou; o Git está esperando você decidir.
git statusmostra quais arquivos estão em conflito (both modified).- Abre o arquivo no VS Code. Ele destaca o trecho e oferece os botões Accept Current (fica o da main), Accept Incoming (fica o do branch) e Accept Both. Ou edita na mão: apaga os marcadores
<<<<<<<,=======,>>>>>>>e deixa o código final como deve ser (às vezes a resposta certa é uma mistura dos dois). - Testa. Arquivo resolvido tem que rodar. Resolver conflito escolhendo errado compila do mesmo jeito, mas quebra o comportamento.
git add config.jsegit commit(o Git já sugere a mensagem de merge). Pronto, as linhas se juntaram.
Se enrolar de vez: git merge --abort cancela o merge e devolve tudo pro estado de antes. Ninguém se machucou, tenta de novo com calma.
🛠️ Gambiarra boa: conflito se treina em laboratório. Dá pra fabricar um conflito de propósito em 2 minutos: cria um repo, commita um arquivo, cria um branch, muda a linha 1 e commita, volta pra main, muda a mesma linha 1 pra outra coisa e commita, e faz o merge. Quem já resolveu dez conflitos de treino não trava quando aparece um na prova.
⚠️ Pega-ratão: começar um merge com mudanças não commitadas no working directory. Mistura o que era teu com o que veio do merge e vira um nó. Regra: working limpo antes de todo merge (git status sem nada vermelho, commit ou git stash antes).
9. Remoto, GitHub e a tal da nuvem
Tudo até aqui aconteceu no repositório local, na tua máquina. Um remoto (GitHub, GitLab) é uma cópia do repositório hospedada fora dela:
git remote add origin https://github.com/usuario/wedding-pass.git
git push -u origin main # primeira vez: envia e vincula o branch
git push # daí em diante: envia os commits novos
git pull # traz o que mudou no remoto
git clone URL # baixa um repositório inteiro
Pra nossa realidade:
- No treino: cada uma tem o repositório no GitHub. Serve de backup (a máquina pode morrer, o histórico não), e o professor acompanha a evolução dos commits sem pedir zip pra ninguém.
- Na prova: o que vale é o repositório local bem organizado (confirmando a regra do dia). O remoto é conceito da UC10 e assunto de apresentação: saber explicar como o projeto seria compartilhado num time real.
- Nuvem, no sentido da UC10, é isso: o código e os serviços hospedados fora da tua máquina. GitHub é nuvem pra código; hospedagem de aplicação é assunto do módulo 04 em diante.
10. Integração contínua: o conceito que fecha a UC10
Integração contínua (CI) é a prática de juntar o trabalho de todo mundo no tronco com frequência (diária, no mínimo) e rodar uma verificação automática a cada junção: o servidor de CI pega o código, instala, builda e roda os testes. Quebrou? O time fica sabendo em minutos, não na véspera da entrega. No GitHub isso tem nome de GitHub Actions; um arquivo de configuração no repositório dispara os testes a cada push.
Numa prova individual e curta não tem servidor de CI, mas a disciplina que o CI automatiza é exatamente o nosso ritual manual:
| No time com CI | Na prova, versão manual |
|---|---|
| Integra pequeno e frequente | Commit pequeno por marco que funciona |
| Build e teste automáticos a cada push | Testar antes de commitar, sempre |
| Quebrou o build, conserta já | Quebrou, volta pro checkpoint e conserta já |
🎯 Isso rende na apresentação. "Eu trabalhei com commits pequenos e testados, que é a disciplina que a integração contínua automatiza nas equipes" é uma frase de 5 segundos no Módulo D que mostra que você entende o conceito além do decoreba. A banca ouve UC10 inteira nessa frase.
11. Como o CIS pontua versionamento
O versionamento aparece com peso 5%, misturando critério objetivo e julgamento. O mapa completo, agora com a régua 0-3 explícita:
| O que a banca olha | Tipo | Como garantir |
|---|---|---|
| Existe um repositório Git com histórico? | Objetivo (sim/não) | git init no primeiro minuto, commitar desde o começo |
| Os commits são frequentes e com marcos claros? | Julgamento (0-3) | Um commit por funcionalidade fechada, não só no fim |
| As mensagens descrevem as mudanças? | Julgamento (0-3) | O que + por quê, prefixos, zero "att/ajustes" |
| Uso de branch e merge pra funcionalidades? | Julgamento (0-3) | Branch por funcionalidade, merge na main testado |
E a régua de julgamento na prática, do zero ao três:
- 0: um commit só ("projeto final"), ou repositório sem histórico útil.
- 1: poucos commits, genéricos ("ajustes", "att"), tudo na main.
- 2: commits frequentes com mensagens razoáveis, mas tudo na main, sem branch.
- 3: commits frequentes com mensagens que contam história, branches por funcionalidade, merges limpos visíveis no
git log --graph. O histórico sozinho explica como o projeto foi construído.
⚠️ Pega-ratão clássico: deixar pra "organizar o Git no fim". Aí sobra um commit gigante, com mensagem "projeto pronto", e o histórico não conta história nenhuma. Nota 0 ou 1 num critério que era dos mais fáceis de tirar 3. Commitar durante o trabalho, não depois. E não existe "arrumar o histórico depois": a data e a ordem dos commits ficam gravadas.
12. Autoavaliação do módulo
- O que precisa estar instalado e testado no ambiente antes de a prova começar, e qual o comando que confere cada item?
- Qual é o fluxo de montagem de um projeto do zero, na ordem certa, e por que o
git initvem antes do código? - Explica os três estados do Git e qual comando move um arquivo de cada estado pro próximo.
- Editei um arquivo, dei
git add, editei de novo e commitei. O que foi pro commit e como ogit statusteria me avisado? - O que faz uma boa mensagem de commit? Transforma "mexi no banco" numa mensagem nota 3.
- Por que
node_modules/,vendor/e.envnunca entram no repositório, e o que fazer se um deles já foi commitado? - Qual a diferença entre
git restore,git revertegit reset --hard, e qual deles nunca usar sozinho na prova? - Qual a diferença entre um merge fast-forward e um merge commit?
- O que é um conflito de merge, por que ele acontece e quais os 5 passos pra resolver?
- O que faz o
git merge --aborte quando usar? - Pra que serve a
main-testeno nosso fluxo e o que amaintem que ser sempre? - O que é integração contínua e qual é a "versão manual" dela numa prova individual?
- Descreve um histórico de commits nota 3 e um nota 1 no critério de julgamento do CIS.
Referências do módulo
Bibliografia da UC10 (plano de curso):
- AQUILES, Alexandre; FERREIRA, Rodrigo. Controlando versões com Git e GitHub. Casa do Código.
- SKOULIKARI, Anna. Aprendendo Git. Novatec.
Mercado e documentação:
- Pro Git (livro oficial, em português): O básico de Branch e Merge — o capítulo que cobre as seções 7 e 8 direto da fonte.
- freeCodeCamp: Como escrever boas mensagens de commit — o guia prático por trás da seção 4.
- GitHub Docs: Resolvendo um conflito de merge na linha de comando — o passo a passo oficial do cenário da seção 8.
Fechou? Ambiente afiado, Git no músculo. Agora vamos pra fundação de dados, onde o projeto inteiro se apoia: 03 — Banco de dados.