-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
feat(commit_comment): Add inline comments on commit diffs #35896
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
brymut
wants to merge
1
commit into
go-gitea:main
Choose a base branch
from
brymut:feat-add-commit-comments
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+920
−14
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // Copyright 2025 The Gitea Authors. All rights reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package v1_26 | ||
|
|
||
| import ( | ||
| "code.gitea.io/gitea/modules/timeutil" | ||
|
|
||
| "xorm.io/xorm" | ||
| ) | ||
|
|
||
| func AddCommitCommentTable(x *xorm.Engine) error { | ||
| type CommitComment struct { | ||
| ID int64 `xorm:"pk autoincr"` | ||
| RepoID int64 `xorm:"INDEX"` | ||
| CommitSHA string `xorm:"VARCHAR(64) INDEX"` | ||
| TreePath string `xorm:"VARCHAR(4000)"` | ||
| Line int64 | ||
| Content string `xorm:"LONGTEXT"` | ||
| ContentVersion int `xorm:"NOT NULL DEFAULT 0"` | ||
| PosterID int64 `xorm:"INDEX"` | ||
| OriginalAuthor string | ||
| OriginalAuthorID int64 | ||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||
| } | ||
|
|
||
| return x.Sync2(new(CommitComment)) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,194 @@ | ||
| // Copyright 2025 The Gitea Authors. All rights reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package repo | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "html/template" | ||
|
|
||
| "code.gitea.io/gitea/models/db" | ||
| user_model "code.gitea.io/gitea/models/user" | ||
| "code.gitea.io/gitea/modules/timeutil" | ||
|
|
||
| "xorm.io/builder" | ||
| ) | ||
|
|
||
| // CommitComment represents a comment on a specific line in a commit diff | ||
| type CommitComment struct { | ||
| ID int64 `xorm:"pk autoincr"` | ||
| RepoID int64 `xorm:"INDEX"` | ||
| Repo *Repository `xorm:"-"` | ||
| CommitSHA string `xorm:"VARCHAR(64) INDEX"` | ||
| TreePath string `xorm:"VARCHAR(4000)"` // File path (same field name as issue comments) | ||
| Line int64 // - previous line / + proposed line | ||
| Content string `xorm:"LONGTEXT"` | ||
| ContentVersion int `xorm:"NOT NULL DEFAULT 0"` | ||
| RenderedContent template.HTML `xorm:"-"` | ||
| PosterID int64 `xorm:"INDEX"` | ||
| Poster *user_model.User `xorm:"-"` | ||
| OriginalAuthor string | ||
| OriginalAuthorID int64 | ||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||
| Attachments []*Attachment `xorm:"-"` | ||
|
|
||
| // Fields for template compatibility with PR comments | ||
| Review any `xorm:"-"` // Always nil for commit comments | ||
| Invalidated bool `xorm:"-"` // Always false for commit comments | ||
| ResolveDoer any `xorm:"-"` // Always nil for commit comments | ||
| Reactions any `xorm:"-"` // Reactions for this comment | ||
| } | ||
|
|
||
| // IsResolved returns false (commit comments don't support resolution) | ||
| func (c *CommitComment) IsResolved() bool { | ||
| return false | ||
| } | ||
|
|
||
| // HasOriginalAuthor returns if a comment was migrated and has an original author | ||
| func (c *CommitComment) HasOriginalAuthor() bool { | ||
| return c.OriginalAuthor != "" && c.OriginalAuthorID != 0 | ||
| } | ||
|
|
||
| func init() { | ||
| db.RegisterModel(new(CommitComment)) | ||
| } | ||
|
|
||
| // ErrCommitCommentNotExist represents a "CommitCommentNotExist" kind of error. | ||
| type ErrCommitCommentNotExist struct { | ||
| ID int64 | ||
| } | ||
|
|
||
| // IsErrCommitCommentNotExist checks if an error is a ErrCommitCommentNotExist. | ||
| func IsErrCommitCommentNotExist(err error) bool { | ||
| _, ok := err.(ErrCommitCommentNotExist) | ||
| return ok | ||
| } | ||
|
|
||
| func (err ErrCommitCommentNotExist) Error() string { | ||
| return fmt.Sprintf("commit comment does not exist [id: %d]", err.ID) | ||
| } | ||
|
|
||
| // CreateCommitComment creates a new commit comment | ||
| func CreateCommitComment(ctx context.Context, comment *CommitComment) error { | ||
| return db.Insert(ctx, comment) | ||
| } | ||
|
|
||
| // GetCommitCommentByID returns a commit comment by ID | ||
| func GetCommitCommentByID(ctx context.Context, id int64) (*CommitComment, error) { | ||
| comment := new(CommitComment) | ||
| has, err := db.GetEngine(ctx).ID(id).Get(comment) | ||
| if err != nil { | ||
| return nil, err | ||
| } else if !has { | ||
| return nil, ErrCommitCommentNotExist{id} | ||
| } | ||
| return comment, nil | ||
| } | ||
|
|
||
| // FindCommitCommentsOptions describes the conditions to find commit comments | ||
| type FindCommitCommentsOptions struct { | ||
| db.ListOptions | ||
| RepoID int64 | ||
| CommitSHA string | ||
| Path string | ||
| Line int64 | ||
| } | ||
|
|
||
| // ToConds implements FindOptions interface | ||
| func (opts FindCommitCommentsOptions) ToConds() builder.Cond { | ||
| cond := builder.NewCond() | ||
| if opts.RepoID > 0 { | ||
| cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) | ||
| } | ||
| if opts.CommitSHA != "" { | ||
| cond = cond.And(builder.Eq{"commit_sha": opts.CommitSHA}) | ||
| } | ||
| if opts.Path != "" { | ||
| cond = cond.And(builder.Eq{"tree_path": opts.Path}) | ||
| } | ||
| if opts.Line != 0 { | ||
| cond = cond.And(builder.Eq{"line": opts.Line}) | ||
| } | ||
| return cond | ||
| } | ||
|
|
||
| // FindCommitComments returns commit comments based on options | ||
| func FindCommitComments(ctx context.Context, opts FindCommitCommentsOptions) ([]*CommitComment, error) { | ||
| comments := make([]*CommitComment, 0, 10) | ||
| sess := db.GetEngine(ctx).Where(opts.ToConds()) | ||
| if opts.Page > 0 { | ||
| sess = db.SetSessionPagination(sess, &opts) | ||
| } | ||
| return comments, sess.Find(&comments) | ||
| } | ||
|
|
||
| // LoadPoster loads the poster user | ||
| func (c *CommitComment) LoadPoster(ctx context.Context) error { | ||
| if c.Poster != nil { | ||
| return nil | ||
| } | ||
| var err error | ||
| c.Poster, err = user_model.GetPossibleUserByID(ctx, c.PosterID) | ||
| if err != nil { | ||
| if user_model.IsErrUserNotExist(err) { | ||
| c.PosterID = user_model.GhostUserID | ||
| c.Poster = user_model.NewGhostUser() | ||
| } | ||
| } | ||
| return err | ||
| } | ||
|
|
||
| // LoadRepo loads the repository | ||
| func (c *CommitComment) LoadRepo(ctx context.Context) error { | ||
| if c.Repo != nil { | ||
| return nil | ||
| } | ||
| var err error | ||
| c.Repo, err = GetRepositoryByID(ctx, c.RepoID) | ||
| return err | ||
| } | ||
|
|
||
| // LoadAttachments loads attachments | ||
| func (c *CommitComment) LoadAttachments(ctx context.Context) error { | ||
| if len(c.Attachments) > 0 { | ||
| return nil | ||
| } | ||
| var err error | ||
| c.Attachments, err = GetAttachmentsByCommentID(ctx, c.ID) | ||
| return err | ||
| } | ||
|
|
||
| // DiffSide returns "previous" if Line is negative and "proposed" if positive | ||
| func (c *CommitComment) DiffSide() string { | ||
| if c.Line < 0 { | ||
| return "previous" | ||
| } | ||
| return "proposed" | ||
| } | ||
|
|
||
| // UnsignedLine returns the absolute value of the line number | ||
| func (c *CommitComment) UnsignedLine() uint64 { | ||
| if c.Line < 0 { | ||
| return uint64(c.Line * -1) | ||
| } | ||
| return uint64(c.Line) | ||
| } | ||
|
|
||
| // HashTag returns unique hash tag for comment | ||
| func (c *CommitComment) HashTag() string { | ||
| return fmt.Sprintf("commitcomment-%d", c.ID) | ||
| } | ||
|
|
||
| // UpdateCommitComment updates a commit comment | ||
| func UpdateCommitComment(ctx context.Context, comment *CommitComment) error { | ||
| _, err := db.GetEngine(ctx).ID(comment.ID).AllCols().Update(comment) | ||
| return err | ||
| } | ||
|
|
||
| // DeleteCommitComment deletes a commit comment | ||
| func DeleteCommitComment(ctx context.Context, comment *CommitComment) error { | ||
| _, err := db.GetEngine(ctx).ID(comment.ID).Delete(comment) | ||
| return err | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can have a
reply_id?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not only one or two fields, the table's design overall doesn't seem right. I have explained in discord.