Competições Senac RS · Seletiva 26

Módulo 02 · Apostila teórica

Módulo 02 — Ambiente, ferramentas e versionamento

BaseUC10 do plano de curso (Realizar configuração e versionamento de software, 36h)Peso na prova5%NaturezaRevisão (com aprofundamento real de Git)
Ocupação: Desenvolvimento de Sistemas Treinador: Diogo Roehrs
💡Nota

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

🛠️ 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):

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)
🎯Foco de prova

🎯 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

⚠️ 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:

  1. Rede de segurança. Quebrou tudo às 3h40 de prova? Volta pro último commit que funcionava e perde minutos, não a prova.
  2. Competência avaliada. Os 5% de configuração e versionamento saem direto da qualidade do teu repositório.
  3. 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)

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

⚠️ 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):

🎯Foco de prova

🎯 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:

  1. O que é gerado/baixado: node_modules/ (Node) e vendor/ (PHP) são reconstruíveis com npm install / composer install. Versionar isso incha o repositório com milhares de arquivos que não são teus.
  2. O que é segredo: arquivo .env com senha do banco e chave do JWT. Nunca entra no Git.
  3. 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

⚠️ 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

⚠️ 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:

  1. A main está funcionando. Nunca se desenvolve funcionalidade nova direto nela.
  2. git switch -c feature/nome-da-funcionalidade
  3. Trabalha ali, commitando em marcos pequenos.
  4. Funcionou e foi testado? git switch main e git merge feature/nome-da-funcionalidade.
  5. A main continua sempre apresentável, e é dela que sai a demo do Módulo D.
🎯Foco de prova

🎯 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

  1. Respira. O projeto não quebrou; o Git está esperando você decidir.
  2. git status mostra quais arquivos estão em conflito (both modified).
  3. 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).
  4. Testa. Arquivo resolvido tem que rodar. Resolver conflito escolhendo errado compila do mesmo jeito, mas quebra o comportamento.
  5. git add config.js e git 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

🛠️ 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:


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á
🎯Foco de prova

🎯 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:

⚠️Pega-ratão

⚠️ 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

  1. O que precisa estar instalado e testado no ambiente antes de a prova começar, e qual o comando que confere cada item?
  2. Qual é o fluxo de montagem de um projeto do zero, na ordem certa, e por que o git init vem antes do código?
  3. Explica os três estados do Git e qual comando move um arquivo de cada estado pro próximo.
  4. Editei um arquivo, dei git add, editei de novo e commitei. O que foi pro commit e como o git status teria me avisado?
  5. O que faz uma boa mensagem de commit? Transforma "mexi no banco" numa mensagem nota 3.
  6. Por que node_modules/, vendor/ e .env nunca entram no repositório, e o que fazer se um deles já foi commitado?
  7. Qual a diferença entre git restore, git revert e git reset --hard, e qual deles nunca usar sozinho na prova?
  8. Qual a diferença entre um merge fast-forward e um merge commit?
  9. O que é um conflito de merge, por que ele acontece e quais os 5 passos pra resolver?
  10. O que faz o git merge --abort e quando usar?
  11. Pra que serve a main-teste no nosso fluxo e o que a main tem que ser sempre?
  12. O que é integração contínua e qual é a "versão manual" dela numa prova individual?
  13. 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):

Mercado e documentação:


💡Nota

Fechou? Ambiente afiado, Git no músculo. Agora vamos pra fundação de dados, onde o projeto inteiro se apoia: 03 — Banco de dados.

Seletiva 26 · Desenvolvimento de Sistemas · Senac RS