Tratando Comentários de Revisão de MR no GitLab
Visão Geral
Comentários de revisão inline em um MR do GitLab vivem em discussões (threads ancoradas a um arquivo+linha). O ciclo completo (buscar com posição → corrigir → responder → resolver) é executado via glab api. Esta skill é a sequência de comandos comprovada; a pegadinha é que o comando óbvio (glab mr view --comments) fornece o texto do comentário, mas não a posição do arquivo/linha, então você não consegue saber a que cada comentário se refere.
CONTEXTO OBRIGATÓRIO: Use superpowers:receiving-code-review para a parte de julgamento: avalie cada comentário com rigor técnico e verifique se está correto antes de aplicar. Esta skill cobre apenas a mecânica do GitLab.
Configuração
MR=511 # o iid do MR
PROJ="<grupo>%2F<subgrupo>%2F<projeto>" # caminho completo codificado em URL
API="projects/$PROJ/merge_requests/$MR"
Codifique o caminho em URL (/ → %2F). Obtenha-o de glab repo view se não tiver certeza.
1. Buscar comentários COM posição
glab mr view $MR --comments NÃO inclui posições de linha, então não use para comentários inline. Acesse a API de discussões e analise position. --paginate é obrigatório: o endpoint retorna 20 threads por página e, sem ele, o restante é descartado sem erro. Threads já resolvidas são ignoradas:
glab api --paginate --output ndjson "$API/discussions" | python3 -c '
import sys, json
for line in sys.stdin:
d = json.loads(line)
n = d["notes"][0]
if n.get("system") or n.get("resolved"): continue
p = n.get("position") or {}
print(d["id"], "|", n["author"]["username"], "|", n["body"])
if p: print(" ->", p.get("new_path"), "new_line:", p.get("new_line"), "old_line:", p.get("old_line"))
'
new_line= a linha no arquivo atual (pós-alteração) → é isso que você lê para interpretar o comentário.- Um comentário em uma linha alterada carrega tanto
old_linequantonew_line; ancore emnew_path+new_line. - Sem
position→ é um comentário geral (não inline).
2. Ler o código em cada new_path:new_line, depois corrigir
Abra o arquivo na linha citada para que o comentário faça sentido no contexto. Aplique a correção somente após avaliá-la (consulte receiving-code-review). Faça commit como um único commit de revisão e envie:
git add <arquivos>
git commit -m "fix(<escopo>): trata revisão sobre <coisa>" # Conventional Commits, id do ticket no corpo
git fetch origin <alvo> && git rebase origin/<alvo>
git push --force-with-lease # um simples `git push` é suficiente apenas se o rebase foi um no-op
3. Responder e resolver cada thread
Postar no endpoint notes de uma discussão adiciona automaticamente a resposta à thread (sem in_reply_to_id). Depois, faça PUT resolved=true:
DISC="<id da discussão da etapa 1>"
glab api -X POST "$API/discussions/$DISC/notes" -f "body=Feito: <o que você alterou>."
glab api -X PUT "$API/discussions/$DISC?resolved=true"
Nunca encapsule glab em uma função de shell: as regras de permissão só correspondem ao comando literal, então escreva ambas as chamadas completas para cada thread.
Escrevendo a resposta
Mantenha-se no que mudou e por quê. Um revisor quer o delta, não a investigação.
- Aplicado: uma ou duas frases. O que você mudou, qualquer coisa que você ampliou além da linha citada, o sha do commit.
Feito, estilo bloco em todos os lugares: todos os seis componentes, não apenas esta linha. Saída renderizada inalterada. f6511f29 - Discordou ou adiou: o fato decisivo primeiro, a opção em segundo, a bola de volta para o revisor. Dois parágrafos curtos é o limite. Corte a observação de retenção, o terceiro argumento de apoio, o encerramento "feliz em discutir".
- Nunca narre a sequência de suas próprias correções e nunca repita o comentário do revisor de volta para ele.
Quais threads resolver
Resolva apenas aquelas que você realmente encerrou.
- Aplicou a alteração -> responda + resolva.
- Respondeu a uma pergunta e a resposta a resolve -> responda + resolva.
- Uma decisão que não é sua (ambiente alvo, escopo, prioridade) -> responda, não resolva. Resolver uma thread que o revisor ainda precisa arbitrar parece desconsiderá-la, e ela sai da lista de revisão dele.
Referência Rápida
| Etapa | Comando |
|---|---|
| Listar comentários inline + posição | glab api --paginate --output ndjson "$API/discussions" → analisar .notes[].position.{new_path,new_line,old_line} |
| Responder a uma thread | glab api -X POST "$API/discussions/<id>/notes" -f "body=..." |
| Resolver uma thread | glab api -X PUT "$API/discussions/<id>?resolved=true" |
Erros Comuns
- Usar
glab mr view --commentspara comentários inline: fornece texto sem arquivo/linha; você não consegue localizá-los. Use a API de discussões. - Inventar
glab mr note resolve: resolva viaglab api -X PUT ".../discussions/<id>?resolved=true". - Ler
old_lineem vez denew_line: para um comentário em uma linha alterada, o código atual está emnew_line. - Esquecer
--paginate: além de 20 threads, a API de discussões retorna silenciosamente apenas a primeira página. - Usar
--forcepuro após o rebase: use--force-with-lease, para que um commit que o revisor enviou enquanto isso não seja sobrescrito. - Aplicar comentários cegamente: avalie primeiro (receiving-code-review). Responda com o que você realmente alterou, depois resolva.
- Truncar o id da discussão ao listar threads: a API espera o id completo de 40 caracteres; um prefixo de 8 caracteres retorna
404 Discussão Não Encontrada. Imprimad["id"]por inteiro. - Explicar demais na resposta: veja "Escrevendo a resposta". A justificativa pertence à descrição do MR ou ao ticket.
- Resolver uma decisão adiada: se o revisor ainda precisa escolher, deixe a thread aberta.