Fluxo de Trabalho
Execute estas etapas em ordem. Pare e reporte ao usuário se qualquer etapa falhar.
1. Avalie a árvore de trabalho
Execute git status e git diff (tanto staged quanto unstaged) para entender o que mudou. Se não houver mudanças, informe ao usuário que não há nada para commitar e pare.
2. Limpe submódulos sujos
Se git status mostrar submódulos com "(modified content)" mas nenhuma mudança de ponteiro de submódulo staged ou intencional, são submódulos aninhados que se desviaram (tipicamente de uma atualização --remote recursiva). Para cada submódulo sujo, execute git -C <caminho-do-submodulo> submodule update --init para restaurar as referências aninhadas para os commits esperados pelo submódulo pai. Após a limpeza, verifique novamente git status para confirmar que a sujeira foi removida. NÃO faça stage de mudanças de ponteiro de submódulo a menos que o usuário as tenha alterado explicitamente.
3. Faça stage de tudo, a menos que o usuário especifique o contrário
Se o usuário não especificou arquivos particulares, faça stage de todas as alterações (rastreadas e não rastreadas) com git add -A. Se o usuário nomeou arquivos ou caminhos específicos, faça stage apenas desses.
4. Lint e auto-fix
Antes de commitar, detecte o linter do projeto e execute-o com auto-fix nos arquivos staged. Ordem de detecção:
- Primeiro, target de lint do projeto: se o Makefile tem um target
lintoulint:fix, ou o package.json tem um scriptlintoulint:fix, prefira esse — ele respeita as convenções próprias do projeto. Prossiga para detecção por linguagem apenas se não existir um target de projeto. - Go (go.mod presente): execute
gofmt -wnos arquivos .go staged, depoisgo vet ./... - JavaScript/TypeScript (package.json presente): execute
npx eslint --fixnos arquivos JS/TS staged se um config do ESLint existir. Se Prettier estiver configurado, execute tambémnpx prettier --writenesses arquivos. - Python (pyproject.toml, setup.py ou requirements.txt presente): execute
ruff check --fixeruff formatnos arquivos .py staged se Ruff estiver configurado. Recorra aoblackse instalado. Recorra aoflake8(apenas relatório, sem auto-fix). - Rust (Cargo.toml presente): execute
cargo fmtecargo clippy --fix --allow-dirty - Nenhum linter detectado: pule esta etapa e prossiga.
Após o auto-fix, faça stage novamente de todos os arquivos modificados com git add -u. Se o linter reportar erros que não puderam ser corrigidos automaticamente, pare e reporte-os ao usuário — não commite com falhas de lint conhecidas.
Se um linter for detectado mas o binário não estiver instalado, avise o usuário e pergunte se deseja prosseguir sem linting ou abortar.
5. Gere a mensagem de commit
Analise o diff staged para produzir uma mensagem de Commit Convencional:
tipo(escopo): resumo curto
Corpo opcional com contexto sobre o que mudou e por quê.
Regras:
- tipo: um de feat, fix, refactor, docs, test, chore, ci, perf, style, build
- escopo: opcional, mas preferido — derive do pacote, módulo ou diretório principal tocado. Omita apenas quando as mudanças abrangem muitas áreas para que um único escopo seja significativo.
- Linha de resumo: minúsculas, modo imperativo, sem ponto final, máximo de 72 caracteres.
- Corpo: adicione apenas quando o diff for não trivial e o resumo sozinho não der a um revisor contexto suficiente. Mantenha conciso.
- Múltiplas mudanças lógicas: escolha a dominante para tipo/escopo, mencione mudanças secundárias no corpo. NÃO divida em múltiplos commits a menos que o usuário peça explicitamente.
- Mudanças de quebra: adicione um rodapé BREAKING CHANGE ou use o sufixo ! (ex.: feat!: ...).
- Se o linter corrigiu arquivos automaticamente, mencione no corpo (ex.: "Inclui auto-fixes do gofmt.").
6. Commit
Execute git commit com a mensagem gerada. Use -m para mensagens apenas com resumo. Para mensagens com corpo, escreva em um arquivo temporário e use git commit -F para preservar quebras de linha, depois limpe o arquivo temporário.
7. Sincronize com o remoto
Determine o nome do branch atual. Então:
- Se o branch tem um upstream, execute
git push. - Se o branch não tem upstream, execute
git push -u origin <nome-do-branch>. - Se o push for rejeitado porque o remoto está à frente, execute
git pull --rebasee então push novamente. Se o rebase produzir conflitos, pare e reporte — não resolva conflitos de merge automaticamente.
8. Confirme
Reporte ao usuário:
- Hash do commit (forma curta)
- Mensagem de commit usada
- Nome do branch e status de sincronização remota
- Arquivos alterados, inserções, deleções (de
git diff --statdo commit) - Qual linter foi executado (ou que nenhum foi detectado)
Casos de borda
- Nenhum remoto configurado: faça commit localmente e informe o usuário.
- HEAD desanexado: avise antes de commitar, sugira criar um branch primeiro.
- Apenas arquivos não rastreados: faça stage e commit normalmente.
- Respeite .gitignore — nunca force-add arquivos ignorados a menos que o usuário peça explicitamente.