feat: add inline comments on commit diffs#36862
feat: add inline comments on commit diffs#36862yuvrajangadsingh wants to merge 16 commits intogo-gitea:mainfrom
Conversation
6fd143a to
6194d6f
Compare
|
@wxiaoguang you're right, the PR description was poorly worded. i've read through the full discussion on #4898, your summary comment, and the linked PR #36398 comments. this implementation follows the minimal scope you outlined: comment only, no emoji reactions, no notifications, no attachments, no resolve/hide, no listing page, no indicator counting. just plain text comments on commit lines using the existing conversation JS. the model is a standalone commit_comment table (not reusing the existing review/issue comment system) since you mentioned in the #36398 discussion that a unified conversation system would be ideal long term but copying existing code causes maintainability problems. happy to adjust the approach if this direction is wrong. should i update the PR description to better reflect the scope? |
|
@lunny reworked. the standalone changes:
this means commit comments get reactions, attachments, and all existing comment infrastructure for free. |
|
For discussions, a new notification type should be added for commit comments. When someone replies to a comment on your pushed commit, you (as pusher of that commit) should receive a notification via both email and the UI. In addition, users who are mentioned or directly replied to in the comment should also receive notifications. It would be better to include a screenshot. |
|
@lunny good point on notifications. that said, i think notifications deserve their own PR since the scope is quite different from the inline commenting itself (needs new notification type, email templates, mention parsing, etc). happy to pick that up as a follow-up once this one lands. will add screenshots once CI is green and the UI flow is working end to end. |
|
@lunny screenshots from a local build: inline comment rendered on commit diff:
"+" button on diff lines for adding new comments:
the existing diff JS handles both PR review comments and commit comments, so clicking the "+" button opens the comment form and submits via AJAX to the |
Add a new commit_comment table and full CRUD flow to support inline comments on commit diff views, similar to PR review comments but standalone (no issue/PR required). Changes: - New CommitComment model with migration (v326) - Web handlers for rendering form, creating, and deleting comments - Diff context patch generation for comment positioning - Templates for commit comment conversation, individual comments, form - Modified diff section templates to render existing commit comments - Reuses existing JS for add-code-comment and delete-comment flows Closes go-gitea#4898
Per @lunny's feedback, rework to reuse the existing Comment table instead of a standalone commit_comment table. The junction table (commit_comment) now only stores repo_id, commit_sha, comment_id. Actual comment data (content, tree_path, line, patch, poster) lives in the Comment table with Type = CommentTypeCommitComment (39). This gives commit comments reactions, attachments, and all existing comment infrastructure for free.
- use single query with Cols("comment_id").Table("commit_comment")
instead of loading full CommitComment structs
- remove models/repo/commit_comment.go entirely
1481c1c to
5d720f5
Compare
|
This comment was written by Claude on behalf of @silverwind Critical Issues1. The new A safer design might store 2. No route-level permission checks beyond The new routes at 3. No tests No unit tests for the model functions, no integration tests for the handlers. This is a significant new feature touching multiple layers. At minimum, needs tests for:
Important Issues4. Orphan junction records If a 5. Delete authorization uses
6. Missing composite index The migration creates individual indexes on Minor Issues7. 8. Template 9. Repetitive markdown rendering in |
|
Need quite a bit of work it seems. If you bring the backend up to shape, I can probably assist on frontend/e2e tests. |
|
@silverwind thanks for the thorough review, all valid points. the IssueID=0 thing is the biggest one. i'm going to add CommitSHA and RepoID columns directly on the Comment model instead of the junction table approach. cleaner, no orphan issues, and existing code paths that filter by IssueID won't accidentally pick up commit comments. for the rest:
will push the rework soon. appreciate the offer to help with frontend/e2e tests, that would be great. |
- Remove commit_comment junction table, query Comment directly via repo_id + commit_sha + type filter - Add RepoID column to Comment (migration v326) - Add reqRepoCodeWriter permission checks to all commit comment routes - Fix delete auth: use CanWrite(TypeCode) instead of IsAdmin() - Fix CanComment: gate on write access, not read - Guard LoadIssue against IssueID=0 (commit comments have no issue) - Extract duplicated markdown rendering loop in commit.go - Fix template dict keys: use "root" instead of "." - Show delete button for users with code write access - Add unit tests for create, delete, get, find operations
|
self-review after addressing @silverwind's feedback: architecture: dropped the junction table entirely. commit comments now live directly in the security: every query in template changes: switched dict keys from test coverage: 6 tests covering create, get-by-id (wrong repo returns error), delete (happy path + wrong repo), find-by-sha, and find-for-diff (left/right side organization). all use patch generation: falls back gracefully. tries one thing i'm not 100% sure about: the |
silverwind
left a comment
There was a problem hiding this comment.
Review by Claude on behalf of @silverwind
Permission model is too restrictive
PR review comments only require reqUnitPullsReader (read access to pull requests). This PR uses reqRepoCodeWriter for commit comments, meaning only users with code write access can comment. This is a significant restriction compared to the PR review flow and inconsistent with how other Git forges work. Consider using a reader-level permission instead.
N+1 poster loading
FindCommitCommentsByCommitSHA calls c.LoadPoster(ctx) per comment in a loop. The standard Gitea pattern is batch loading via CommentList.LoadPosters() (see models/issues/comment_list.go). Should use that instead.
Delete silently succeeds for non-existent comments
DeleteCommitComment in the model layer doesn't check affected rows. The handler does call GetCommitCommentByID first (which returns 404 if not found), but there's still a TOCTOU gap. More importantly, the existing DeleteComment in Gitea also doesn't check affected rows, so this is consistent with codebase patterns — but worth noting since this is new code that could do better.
No notifications
Creating a commit comment doesn't trigger any notification or webhook. Users won't know someone commented on their commit unless they revisit the page.
notify the commit author (resolved by email) and @mentioned users when a new commit comment is created. uses the existing NotificationSourceCommit source and follows the same pattern as CreateRepoTransferNotification.
|
@silverwind @lunny addressed all the feedback, here's what changed: permissions (fc9f356) - dropped N+1 poster loading (fc9f356) - replaced the per-comment delete affected rows - keeping the current notifications (d37458c) - added template duplication - checked and this isn't an issue. |
|
I still believe we should use a separate table for commit comments due to performance considerations. When loading commit comments, the query will use repo_id, commit_sha, and type as a composite index. We should avoid adding an index on just repo_id and commit_sha, because most comments are associated with issues rather than commits. Adding that index to the main comments table would significantly increase index size. Adding an extra repo_id column would also be unnecessary for most comments, since the majority of comments are not commit-related. This is especially true for instances that do not use the commit comment feature at all. In addition, the migration could take a long time on large Gitea instances. |
|
@lunny @silverwind makes sense. the index bloat and migration cost on large instances is a fair concern. thinking of going back to a separate table, but not the junction approach from before. a standalone this way:
the tradeoff is we don't get existing comment infrastructure (reactions, attachments) for free, but those weren't in scope for the MVP anyway. does this direction work for both of you? |
If this approach can solve another problem as well, I can accept it. However, my main concern is how we would implement reactions, attachments, and pasted images if we follow this direction. Some people may think these features are unnecessary, but I don’t agree. Once the basic requirements are met, users will inevitably ask for more advanced functionality. That’s why I don’t think it’s a good idea to introduce separate tables for reactions, attachments, and other related features. We need a complete design before starting this work; otherwise, it will make the later stages much more difficult—or even impossible—to implement. |
|
@lunny fair point, painting ourselves into a corner on reactions/attachments would be bad. thinking about it more, the junction table approach actually works for both concerns:
no index bloat on the comment table, no migration touching existing rows, and future features like reactions just work without any extra tables. this is actually where the PR started before silverwind's review pushed it to the standalone column approach. the IssueID=0 concern is valid but fixable with targeted guards rather than a whole redesign. does this work? |


fixes #4898
adds inline commenting on commit diff views, same as PR review comments but standalone, no issue/PR needed.
what this does
commit_commenttable with migration (v326), stores repo_id, commit_sha, tree_path, line, poster, content, diff patchGetFileDiffCutAroundLinehow it works
+button on a commit diff line (same button as PR diffs)/{repo}/commit/{sha}/commentCommitCommentrecord, renders the conversation HTML backFindCommitCommentsForDiffand rendered inlinefiles changed
models/repo/commit_comment.gomodels/migrations/v1_26/v326.gomodels/migrations/migrations.gorouters/web/repo/commit_comment.gorouters/web/repo/commit.gorouters/web/web.gotemplates/repo/diff/box.tmpltemplates/repo/diff/section_unified.tmpltemplates/repo/diff/section_split.tmpltemplates/repo/diff/commit_conversation.tmpltemplates/repo/diff/commit_comments.tmpltemplates/repo/diff/commit_comment_form.tmpltemplates/repo/diff/new_commit_comment.tmplthis is an MVP. follow-up work could include: edit comments, reactions, email notifications, API endpoints, comment counts on commit list pages.