← Voltar ao blog

Staging por linha: adicione exatamente o que você quer

feature tutorial

Por que o staging granular importa

Um histórico Git bem elaborado conta uma história. Cada commit representa uma única mudança lógica: uma correção de bug, um refactoring, uma nova funcionalidade. Mas o desenvolvimento real raramente é tão organizado. Você corrige um bug, depois nota um erro de digitação próximo, depois ajusta alguma formatação, depois começa um pequeno refactoring -- tudo no mesmo arquivo. Se você fizer staging e commit do arquivo inteiro de uma vez, acaba com um commit que mistura mudanças não relacionadas. Isso torna a revisão de código mais difícil, torna a busca de bugs com bisect mais difícil, e torna o histórico de commits menos útil como documentação.

O staging granular permite que você divida seu trabalho em commits significativos, mesmo quando as mudanças estão entrelaçadas dentro do mesmo arquivo. Em vez de fazer commit de tudo de uma vez, você escolhe exatamente quais mudanças pertencem juntas.

Três níveis de staging

Staging a nível de arquivo

O nível mais básico. Você faz staging de arquivos inteiros com git add:

git add src/auth.ts src/utils.ts

Isso é suficiente quando cada arquivo contém apenas uma mudança lógica. Mas assim que um arquivo contém múltiplas modificações não relacionadas, o staging a nível de arquivo é grosseiro demais.

Staging a nível de hunk

Git pode dividir as mudanças de um arquivo em "hunks" -- blocos contíguos de linhas modificadas separados por código inalterado. Usando git add -p (modo patch), Git apresenta cada hunk um de cada vez e pergunta se deve fazer staging:

git add -p src/auth.ts

Para cada hunk, você escolhe y (staging), n (pular), s (dividir em hunks menores), ou e (editar manualmente). Esta é uma melhoria importante sobre o staging a nível de arquivo, mas tem limitações. Hunks são definidos por proximidade: se duas mudanças não relacionadas estão próximas (separadas por menos de três linhas de contexto), Git as agrupa em um único hunk. Separá-las requer edição manual de patch, que é tedioso e propenso a erros.

Staging a nível de linha

O staging a nível de linha é a opção mais precisa. Em vez de trabalhar com arquivos ou hunks, você seleciona linhas individuais para fazer staging. Quer fazer staging das linhas 12 e 15, mas não da linha 14? Você pode. Isso dá controle completo sobre o que entra em cada commit, independentemente de quão próximas as mudanças estão no arquivo.

Na linha de comando, staging a nível de linha significa editar patches manualmente com git add -p e a opção e. Você precisa entender o formato unified diff, modificar cuidadosamente o patch e torcer para não introduzir erros. Funciona, mas não é algo que a maioria dos desenvolvedores queira fazer regularmente.

Staging a nível de linha no GitSquid

GitSquid torna o staging a nível de linha visual e direto. Quando você seleciona um arquivo modificado, o visualizador de diff mostra cada linha alterada. Para fazer staging de linhas específicas:

  • Clique em uma única linha para selecioná-la.
  • Cmd+Click (Ctrl+Click no Windows/Linux) para selecionar múltiplas linhas individuais.
  • Shift+Click para selecionar um intervalo de linhas.

Depois de selecionar as linhas desejadas, faça staging delas. Apenas essas linhas são adicionadas ao índice. O restante permanece como modificações sem staging no seu diretório de trabalho, pronto para ser incluído em um commit diferente.

O mesmo fluxo de trabalho funciona ao contrário. Se você já fez staging de linhas que quer remover da área de staging, pode selecioná-las no diff em staging e remover do staging apenas essas linhas.

Como funciona por baixo dos panos

Quando você faz staging de linhas individuais, GitSquid gera um patch no lado do servidor que inclui apenas as mudanças selecionadas. Este patch é então aplicado ao índice usando o mecanismo de patch do Git. Ao lidar com a geração do patch no servidor em vez de manipular o diff no cliente, o resultado é confiável e corresponde exatamente ao que Git espera. Não há problemas de formatação ou erros de deslocamento que você poderia encontrar ao editar patches manualmente.

Exemplos práticos

Separando uma correção de bug de um refactoring

Você está trabalhando em um refactoring e nota um bug. Você o corrige imediatamente porque a correção é óbvia. Agora seu arquivo tem dois tipos de mudanças: o refactoring e a correção do bug. Com staging a nível de linha, você seleciona apenas as linhas da correção do bug, faz commit com uma mensagem clara como "fix null check in auth validation", e depois faz commit do refactoring separadamente. O resultado são dois commits limpos e revisáveis em vez de um confuso.

Separando código de debug de código de produção

Você adicionou algumas instruções console.log durante a depuração, bem ao lado das mudanças reais do código. Em vez de tentar lembrar quais linhas são debug e quais são reais, você seleciona visualmente apenas as mudanças de produção, faz staging e commit. As linhas de debug ficam no seu diretório de trabalho onde você pode continuar usando ou descartá-las depois.

Preparando um commit parcial para revisão

Você tem um grande conjunto de mudanças, mas apenas parte do trabalho está pronto para revisão. O staging a nível de linha permite que você faça commit das partes prontas enquanto mantém o código em progresso sem commit. Sua pull request permanece focada, e o revisor não precisa navegar por código incompleto.

Mantendo commits atômicos

Um commit atômico é aquele que contém uma única mudança lógica e completa. Ele passa nos testes, não quebra o build e pode ser entendido sozinho. Commits atômicos não são apenas questão de organização. Eles têm benefícios práticos:

  • Revisão de código. Revisores podem entender cada commit independentemente. Um commit intitulado "fix input validation" que só toca lógica de validação é fácil de revisar. Um commit intitulado "various changes" que toca validação, estilo e configuração não é.
  • Caça a bugs. Quando algo quebra, git bisect pode identificar o commit exato que introduziu o problema. Commits atômicos tornam o resultado significativo: você encontra a mudança específica que causou o bug, não um amontoado de modificações não relacionadas.
  • Revert. Se um commit precisa ser revertido, um commit atômico pode ser revertido de forma limpa. Um commit misto pode forçar você a reverter mudanças que realmente queria manter.
  • Histórico como documentação. Meses depois, quando alguém lê o histórico de commits para entender por que um trecho de código existe, commits atômicos com mensagens claras contam uma história útil.

O staging a nível de linha é a ferramenta que torna os commits atômicos práticos. Sem ele, criar commits limpos a partir do desenvolvimento real desordenado requer disciplina e esforço manual. Com ele, o processo é tão simples quanto selecionar as linhas que pertencem juntas.

Os melhores commits são os que fazem exatamente uma coisa. O staging granular dá o controle para que isso aconteça, mesmo quando seu diretório de trabalho conta uma história diferente.