Encontre o Primeiro Orçamento Incorreto

GitBeginner
Pratique Agora

Introdução

A Little Pine Goods prepara orçamentos de pequenos presentes para retirada. Um cliente informa que a oferta FRIEND10 deixou de conceder o desconto prometido. O histórico recente também contém atualizações úteis de produtos, textos e retirada, portanto voltar a loja inteira a uma versão antiga perderia trabalho válido.

Execute um pedido normal e o pedido de presente com problema; depois, use um teste de negócio determinístico preparado para classificar versões antigas. Pratique um pouco a busca binária manual do Git antes de deixar o mesmo teste automatizar a busca. Compare o primeiro snapshot incorreto com seu pai direto, saia da busca e corrija a loja atual, mantendo as atualizações posteriores. Entregue um arquivo completo de orçamento para o cliente, além do commit de correção.

Os pré-requisitos são navegação básica no terminal, commits, branches e leitura simples de log/diff. Git bisect, cópias temporárias com HEAD destacado, status de saída dos testes e a pequena edição do arquivo de ofertas são explicados aqui. O Python e o programa de orçamentos estão preparados; você os executará sem escrever Python. Trata-se de um histórico Git local real e uma ferramenta de orçamentos baseada em arquivos em uma única máquina de treinamento, com pedidos fictícios e preços em EUR. Não é necessário site, conta hospedada nem implantação em rede. Use o Terminal padrão. A duração de 50 minutos é uma estimativa do autor.

Encontre o Primeiro Orçamento Incorreto

Nesta etapa, estabeleça o resultado de negócio correto, teste snapshots históricos reais e identifique o limite em que o desconto passou a estar errado.

Comece em Terminal e entre no repositório da loja:

cd /home/labex/project/quote-desk/shop

cd altera o diretório deste terminal. Se digitar um caminho incorretamente, use pwd para exibir sua localização e ls para listar esse diretório; depois, repita o cd completo acima. Erros comuns de navegação não exigem restaurar a VM ao estado inicial.

Leia a solicitação do cliente. cat exibe um arquivo de texto; .. significa o diretório pai:

cat ../request.txt

FRIEND10 promete 10% de desconto sobre o subtotal dos itens. Não há frete nem imposto. O pedido de presente é de três canecas de acampamento a EUR 16.00 cada: subtotal EUR 48.00, desconto EUR 4.80, total EUR 43.20. O catálogo, o pedido e a política existentes são os fatos de negócio; não os altere para se ajustarem a um resultado incorreto.

Execute primeiro um pedido normal. python3 executa o programa fornecido quote.py; seu argumento seguinte é o arquivo de pedido preparado. Você não precisa editar nem compreender o código-fonte Python:

python3 quote.py ../orders/plain.order

O pedido de uma caneca usa o cupom NONE. Espere subtotal e total EUR 16.00, desconto EUR 0.00, a mensagem de boas-vindas atual e retirada no sábado até 16:00. Isso estabelece um orçamento normal útil.

Execute o pedido relatado:

python3 quote.py ../orders/gift.order

Para ler o status de saída nativo do último comando, use o valor do shell $?. echo exibe esse valor. Execute-o imediatamente após o comando de orçamento:

echo $?

Espere 0: o programa foi executado com sucesso, embora o resultado monetário esteja errado.

O programa funciona, mas o orçamento está errado: desconto EUR 0.48 e total EUR 47.52. Uma saída bem-sucedida do programa é diferente de uma resposta de negócio correta.

O teste preparado fica fora do repositório para que colocar versões antigas na cópia de trabalho não possa substituí-lo. Ele executa o programa real de orçamentos para várias quantidades e um controle sem cupom, comparando os resultados completos com a política de ofertas inalterada. Execute-o:

python3 /opt/labex/quote-desk/check.py

Leia imediatamente o status deste teste, usando o mesmo valor do shell:

echo $?

Espere 1: este teste detecta a divergência de negócio.

Espere linhas FAIL para FRIEND10 e um status de saída nativo de 1. Os controles NONE passam. O teste retorna 0 para orçamentos corretos, 1 para esta falha de negócio e 128 se não conseguir testar uma versão; a impossibilidade de testar deve interromper a busca, não ser presumida como uma regressão de desconto. Este histórico preparado não tem falhas de compilação nem versões ignoradas.

Inspecione a branch atual e o estado limpo. branch --show-current exibe a branch; --short produz uma lista compacta de arquivos:

git branch --show-current
git status --short

Espere main e nenhuma saída de arquivos alterados. Mantenha a loja limpa durante a busca. Leia seu histórico: --no-pager exibe a saída diretamente em vez de entrar em um visualizador com rolagem, --oneline resume as entradas e --decorate identifica branches e tags:

git --no-pager log --oneline --decorate

A tag fixa incident-tip marca a ponta atual recebida, e known-good marca a versão anterior que funcionava. Os assuntos dos commits descrevem o trabalho, mas sua redação não comprova quando o orçamento falhou. Preserve as duas tags e todos os commits recebidos.

A opção --revision do teste executa o snapshot selecionado de um commit em um diretório temporário isolado, sem alterar sua cópia de trabalho nem corrigi-la. Estabeleça as duas extremidades com comportamento real:

python3 /opt/labex/quote-desk/check.py --revision known-good
python3 /opt/labex/quote-desk/check.py --revision incident-tip

O primeiro comando deve passar com status 0. O segundo deve falhar com status 1. Uma versão correta e uma versão posterior incorreta delimitam a busca. Este exercício tem uma única introdução da falha e nenhuma correção posterior nesse intervalo.

Classifique Duas Versões Manualmente

O bisect do Git reduz esse intervalo testando versões entre os limites. Comece com a revisão sabidamente incorreta primeiro e a sabidamente correta em segundo:

git bisect start incident-tip known-good

O Git coloca um snapshot intermediário na cópia de trabalho e exibe o intervalo restante. Durante a busca, HEAD destacado significa que você está vendo um commit diretamente, em vez de mover a main. Não edite nem crie commits nessas versões temporárias.

Execute o mesmo teste no snapshot que está na cópia de trabalho:

python3 /opt/labex/quote-desk/check.py

Esta primeira seleção preparada falha com status 1. Classifique essa versão observada como incorreta; bad descreve o resultado do teste de negócio, não a mensagem do commit:

git bisect bad

O Git seleciona outro snapshot. Teste-o em vez de adivinhar:

python3 /opt/labex/quote-desk/check.py

Esta seleção passa com status 0. Registre essa observação:

git bisect good

O Git reduz o intervalo novamente. Você viu como cada resultado remove parte do espaço de busca. Para praticar o caminho automático a partir dos mesmos limites originais, saia primeiro desta busca incompleta. bisect reset limpa o estado da busca e retorna à branch e à revisão em que ela começou; ele não desfaz commits:

git bisect reset
git branch --show-current

Espere main. Se classificar uma versão incorretamente durante a prática, esse mesmo reset e um novo início permitem repetir usando os resultados reais do teste, sem descartar arquivos.

Deixe o Teste Conduzir a Busca

Comece novamente e forneça a bisect run o mesmo comando completo de teste. O Git usa cada status de saída nativo para escolher automaticamente entre correto e incorreto:

git bisect start incident-tip known-good
git bisect run python3 /opt/labex/quote-desk/check.py

Espere várias execuções do teste e uma linha terminando em is the first bad commit. O próprio comando de busca termina com status 0 quando encontra o limite com sucesso, embora alguns testes individuais de orçamento tenham falhado. Os IDs dos commits podem ser diferentes.

A referência bisect/bad do Git aponta para o primeiro commit incorreto identificado. O HEAD atual ainda pode ser a última versão correta testada; não suponha que ele seja o resultado relatado. Leia o patch do candidato real. show seleciona esse commit e seu patch; -- separa o caminho do arquivo:

git --no-pager show bisect/bad -- discounts.txt

A porcentagem de FRIEND10 mudou de 10 para 1. Confira os dois lados usando o teste externo. Um ^ no final seleciona o primeiro pai direto de um commit, portanto bisect/bad^ é a versão imediatamente anterior ao candidato, não um intervalo inteiro:

python3 /opt/labex/quote-desk/check.py --revision bisect/bad
python3 /opt/labex/quote-desk/check.py --revision bisect/bad^

Espere que o candidato falhe com status 1 e seu pai passe com status 0. Os valores e o comportamento real concordam. Deixe a busca concluída aberta para este ponto de verificação; a seguir, você voltará à loja atual antes de editar.

Corrija a Loja Atual e Entregue o Orçamento

Nesta etapa, saia da busca histórica, registre uma correção com um único objetivo na branch atual e entregue um orçamento completo sem perder produtos ou informações de retirada posteriores.

Permaneça em Terminal, em /home/labex/project/quote-desk/shop. Volte à branch original usando o reset de busca ensinado:

git bisect reset
git branch --show-current
git --no-pager log -1 --oneline --decorate
git status --short

Espere main, a ponta recebida marcada por incident-tip e nenhuma saída de arquivos alterados. A opção de log -1 limita a saída ao commit mais recente. Não corrija uma versão histórica destacada nem substitua a loja inteira por known-good: o trabalho posterior válido pertence ao resultado.

Leia o pequeno arquivo de ofertas e os detalhes atuais que você deve preservar:

cat discounts.txt
cat welcome.txt pickup.txt care.txt
cat catalog.json

A árvore atual inclui o Trail pin, a nova mensagem de boas-vindas e retirada no sábado até 16:00. Apenas a porcentagem de FRIEND10 está errada. O arquivo de ofertas contém uma configuração CODE=integer-percent por linha; TRAIL15 continua 15 e STUDENT5 continua 5.

Substitua apenas este pequeno arquivo. printf exibe valores conforme um formato: %s significa texto e \n adiciona uma quebra de linha após cada valor fornecido. As aspas simples preservam o texto literal. > grava a saída no arquivo nomeado, substituindo apenas esse arquivo:

printf '%s\n' 'FRIEND10=10' 'TRAIL15=15' 'STUDENT5=5' > discounts.txt

Revise a correção real. Um diff simples compara os arquivos de trabalho com o índice, a área de preparação do Git:

git --no-pager diff -- discounts.txt

Espere apenas FRIEND10 mudando de 1 de volta para 10. Configure uma identidade de commit local ao repositório antes de registrar a correção. --local evita configuração global; as aspas mantêm um nome com espaços como um único valor. Estes exemplos fictícios podem ser substituídos:

git config --local user.name "Little Pine Maintainer"
git config --local user.email "maintainer@little-pine.example"

Prepare esse arquivo com add. Inspecione o patch preparado com --cached, que compara o índice com o commit atual:

git add discounts.txt
git --no-pager diff --cached -- discounts.txt

Registre a correção com um único objetivo em um commit. -m fornece diretamente uma mensagem significativa:

git commit -m "Restore the promised FRIEND10 discount"

Compare com a ponta recebida fixa. Este é um novo commit de correção, que mantém todos os commits originais em vez de reescrever o histórico:

git --no-pager diff incident-tip HEAD
git --no-pager log -2 --oneline --decorate
git status --short

Espere apenas a correção da porcentagem, sua correção imediatamente após incident-tip e um estado rastreado limpo. A mensagem exata e os valores de autor não são o critério de sucesso.

Execute o teste preparado no programa atual real:

python3 /opt/labex/quote-desk/check.py

Todos os casos agora passam com status 0. Gere o orçamento do cliente:

python3 quote.py ../orders/gift.order

Espere a descrição atual da caneca e a mensagem de boas-vindas, quantidade 3, FRIEND10, subtotal EUR 48.00, desconto EUR 4.80, total EUR 43.20 e retirada atual até sábado às 16:00.

Entregue essa saída real no diretório quotes preparado. Como ensinado, > salva stdout neste arquivo nomeado; ele não altera o pedido nem o programa:

python3 quote.py ../orders/gift.order > ../quotes/mug-gift.txt
cat ../quotes/mug-gift.txt

Leia o orçamento salvo completo, não apenas seu nome de arquivo. O arquivo é o resultado utilizável pelo cliente, enquanto o commit torna a correção repetível.

Confira o pedido normal e o produto posterior, que devem permanecer utilizáveis:

python3 quote.py ../orders/plain.order
python3 quote.py ../orders/new-item.order

A caneca sem desconto continua EUR 16.00. Dois Trail pins com STUDENT5 têm subtotal EUR 10.00, desconto EUR 0.50 e total EUR 9.50. Ambos mantêm os detalhes atuais de boas-vindas e retirada. O ponto de verificação observa o commit atual real, a árvore completa preservada, o comportamento do limite histórico e o orçamento entregue; ele não avalia uma transcrição de comandos nem uma palavra-chave da mensagem.

Resumo

Você usou pedidos normais e incorretos para definir um teste de negócio, classificou versões históricas manualmente e automatizou a mesma busca com Git bisect. Você distinguiu a referência do primeiro commit incorreto de HEAD, verificou o candidato e seu pai, voltou à main e registrou uma correção com um único objetivo sem perder atualizações posteriores da loja. O cliente recebeu um orçamento completo e correto.

O desafio independente muda o cupom, o pedido do cliente e a posição da falha, usando o mesmo programa fornecido, a mesma política e o mesmo formato de teste. Escolha com base nas evidências reais em vez de copiar um deslocamento de commit.