feat(mr): create diff comments
What does this MR do?
Adds --file, --line, and --old-line flags to glab mr note create for placing diff comments on specific files and lines in the latest MR diff version.
--filetargets a file path in the MR diff--linetargets a new-side line (single number orN:Mrange for multiline)--old-linetargets an old-side (removed) line- Omitting both
--lineand--old-linecreates a file-level comment
New packages
internal/diff— unified diff parser (Parse,FindNewLine,FindOldLine)internal/commands/mr/mrutils/position.go—GetLatestDiffVersion,FindFileDiff,BuildDiffPosition,ParseLine
Mutual exclusivity
| Flag group | Reason |
|---|---|
--line / --old-line |
Cannot target both sides simultaneously |
--reply / --file |
Reply adds to existing thread; diff comment creates new one |
--unique / --file |
Dedup searches flat notes by body, not diff positions |
Validation
--lineor--old-linewithout--file→ error- Empty diff → error
- Line not found in diff → error
- Multiline range end validated
--line 0or negative values → error
Testing strategy
Unit tests
All new logic is covered by unit tests (make test-changed or go test ./internal/...):
internal/diff/parse_test.go— unified diff parser: line mapping, edge cases, empty diffsinternal/commands/mr/mrutils/position_test.go—BuildDiffPosition,ParseLine,FindFileDiffinternal/commands/mr/note/mr_note_create_test.go— flag validation, mutual exclusivity, integration with mocked API
Manual verification
After building (make build), you can post diff comments on this MR to verify end-to-end:
# New-side diff comment on line 17 of a new file
bin/glab mr note create 3171 --file internal/commands/mr/mrutils/position.go --line 17 -m "Test: new-side diff comment"
# New--side range diff comment
bin/glab mr note create 3171 --file internal/commands/mr/mrutils/position.go --line 14:15 -m "Test: new-side range comment"
# Old-side diff comment on a removed line (old line 27)
bin/glab mr note create 3171 --file internal/commands/mr/note/mr_note_create.go --old-line 27 -m "Test: old-side diff comment"Both commands produce a link to the created note. The comments appear inline in the MR diff view at the expected file and line.
Out of scope
Old-side multiline ranges
--old-line currently accepts a single line number only (no range syntax like --line 10:15).
Supporting old-side multiline ranges would require:
- Changing
--old-linefrominttostringto accept range syntax (e.g.,--old-line 5:10) - Adding a parallel
lineCodepath that usesType: "old"and encodes old-side line numbers in thesha1_oldline_0format - A new
LineRangeconstruction withType: "old"on both start/end positions - Tests for all combinations
The GitLab API supports it (LinePositionOptions has both OldLine and Type: "old"), but the use case is niche — commenting on a range of removed lines. This can be added in a follow-up if there is demand.
Binary file detection
If --file points to a binary file (e.g., an image), the diff content is empty and the error message is "diff for image.png is empty", which does not explain that binary files are unsupported. A follow-up could check the Binary field on the diff object and return a clearer error like "binary files do not support diff comments".
Related issues
Closes #8285 (closed)