2019-08-14 23:32:19 +08:00
|
|
|
// Copyright 2019 The Gitea Authors.
|
|
|
|
|
// All rights reserved.
|
2022-11-27 13:20:29 -05:00
|
|
|
// SPDX-License-Identifier: MIT
|
2019-08-14 23:32:19 +08:00
|
|
|
|
|
|
|
|
package pull
|
|
|
|
|
|
|
|
|
|
import (
|
2022-01-19 23:26:57 +00:00
|
|
|
"context"
|
2025-05-29 17:34:29 +02:00
|
|
|
"errors"
|
2019-11-14 10:57:36 +08:00
|
|
|
"fmt"
|
2021-02-27 18:46:14 +00:00
|
|
|
"io"
|
2019-11-14 10:57:36 +08:00
|
|
|
|
2025-03-27 19:40:14 +00:00
|
|
|
"forgejo.org/models/db"
|
|
|
|
|
issues_model "forgejo.org/models/issues"
|
|
|
|
|
repo_model "forgejo.org/models/repo"
|
|
|
|
|
user_model "forgejo.org/models/user"
|
|
|
|
|
"forgejo.org/modules/git"
|
|
|
|
|
"forgejo.org/modules/gitrepo"
|
|
|
|
|
"forgejo.org/modules/log"
|
|
|
|
|
"forgejo.org/modules/optional"
|
|
|
|
|
"forgejo.org/modules/setting"
|
|
|
|
|
"forgejo.org/modules/util"
|
|
|
|
|
notify_service "forgejo.org/services/notify"
|
2019-08-14 23:32:19 +08:00
|
|
|
)
|
|
|
|
|
|
2024-03-28 08:19:24 -07:00
|
|
|
// ErrDismissRequestOnClosedPR represents an error when an user tries to dismiss a review associated to a closed or merged PR.
|
|
|
|
|
type ErrDismissRequestOnClosedPR struct{}
|
|
|
|
|
|
|
|
|
|
// IsErrDismissRequestOnClosedPR checks if an error is an ErrDismissRequestOnClosedPR.
|
|
|
|
|
func IsErrDismissRequestOnClosedPR(err error) bool {
|
|
|
|
|
_, ok := err.(ErrDismissRequestOnClosedPR)
|
|
|
|
|
return ok
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (err ErrDismissRequestOnClosedPR) Error() string {
|
|
|
|
|
return "can't dismiss a review associated to a closed or merged PR"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (err ErrDismissRequestOnClosedPR) Unwrap() error {
|
|
|
|
|
return util.ErrPermissionDenied
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-18 05:03:44 +08:00
|
|
|
// checkInvalidation checks if the line of code comment got changed by another commit.
|
|
|
|
|
// If the line got changed the comment is going to be invalidated.
|
fix: display code comments on removed lines-of-code to correct locations in PR view (#12092)
With the completion of #12015, when a comment is left on a changed line in a pull request, we track the comment against the line of code with `git blame` and then identify where it currently is in any diff with `git blame --reverse`. However, this strategy only works for the *modified* lines of code -- eg. the `+...` in diffs, and not the `-...` in diffs. The reason is that `git blame --reverse` can't track a line of code's location past the commit that it was removed in.
To permit comments that are left on lines of code that are removed to appear correctly in the UI, a separate approach is required for those comments. This PR performs two major changes, which have been complex to figure out, but are reasonably easy to understand:
- When a comment is placed on a removed line in a PR, perform a `git blame --reverse` from the PR's base to the currently viewed commit, and use this information to record in the comment:
- the **last commit that the line of code existed in** (stored in the `commit_sha` field)
- the **line of code as of that commit** (stored in the `line` field, negative, to indicate that the comment is on a removal).
- the **patch** where the comment was placed (stored in the field `patch`); existing functionality unchanged in this PR
- When viewing any diff in the PR, for each comment on a removal, perform a diff from the `commit_sha` (last commit that the line of code existed in) to the current commit being viewed, and verify that within that diff the left-hand-side line removal still exists at the same line of code in the diff, by comparing the current diff with the stored patch.
- If present, place the commit in the UI at the line number.
- If the line of code no longer exists in the diff at that point (for example, it was removed, commented upon, and then re-added in a later commit), then the comment is considered outdated and isn't displayed.
The algorithm used for marking a comment as "outdated" is also updated to use this approach.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [x] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12092
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-13 18:26:53 +02:00
|
|
|
func checkInvalidation(ctx context.Context, c *issues_model.Comment, repo *repo_model.Repository, newCommitID string) error {
|
fix: mark code comments as Outdated based upon line-of-code existence in current PR commit (#12054)
Currently when a commit is pushed to a branch, code comments are marked as Outdated if a `git blame` on the current commit's code returns the same commit as the `git blame` did when the comment was originally created. This implementation doesn't make sense:
- It doesn't handle the case correctly where the same line of code exists unaltered in the new commit, but it has been relocated (eg. new lines entered or removed above the location).
- It falsely keeps the commit valid if the line of code that the comment was made upon has been removed, if, coincidentally, the line of code that now exists at the commit came from the same source commit. For example, if the line of code that the comment was on was deleted, but the next line of code came from the same commit, the comment will be kept as valid.
This PR uses the logic introduced in #12015, using a `git blame --reverse` -- the commit & line that was identified as having the comment on it is reversed, and if it still exists in the new head, then the comment is considered valid. Otherwise it is marked as outdated.
Automated tests are added primarily by revising the automated tests in #12015 -- a comment in an existing test case was marked as outdated, even though it shouldn't have been.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
<!--start release-notes-assistant-->
## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
- [PR](https://codeberg.org/forgejo/forgejo/pulls/12054): <!--number 12054 --><!--line 0 --><!--description bWFyayBjb2RlIGNvbW1lbnRzIGFzIE91dGRhdGVkIGJhc2VkIHVwb24gbGluZS1vZi1jb2RlIGV4aXN0ZW5jZSBpbiBjdXJyZW50IFBSIGNvbW1pdA==-->mark code comments as Outdated based upon line-of-code existence in current PR commit<!--description-->
<!--end release-notes-assistant-->
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12054
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-11 23:10:34 +02:00
|
|
|
reverseBlame, err := c.ResolveCurrentLine(ctx, repo, newCommitID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warn("ResolveCurrentLine failed: %s", err.Error())
|
|
|
|
|
} else if reverseBlame.CommitID != newCommitID {
|
|
|
|
|
c.Invalidated = true
|
|
|
|
|
return issues_model.UpdateCommentInvalidate(ctx, c)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-18 05:03:44 +08:00
|
|
|
// InvalidateCodeComments will lookup the prs for code comments which got invalidated by change
|
fix: display code comments on removed lines-of-code to correct locations in PR view (#12092)
With the completion of #12015, when a comment is left on a changed line in a pull request, we track the comment against the line of code with `git blame` and then identify where it currently is in any diff with `git blame --reverse`. However, this strategy only works for the *modified* lines of code -- eg. the `+...` in diffs, and not the `-...` in diffs. The reason is that `git blame --reverse` can't track a line of code's location past the commit that it was removed in.
To permit comments that are left on lines of code that are removed to appear correctly in the UI, a separate approach is required for those comments. This PR performs two major changes, which have been complex to figure out, but are reasonably easy to understand:
- When a comment is placed on a removed line in a PR, perform a `git blame --reverse` from the PR's base to the currently viewed commit, and use this information to record in the comment:
- the **last commit that the line of code existed in** (stored in the `commit_sha` field)
- the **line of code as of that commit** (stored in the `line` field, negative, to indicate that the comment is on a removal).
- the **patch** where the comment was placed (stored in the field `patch`); existing functionality unchanged in this PR
- When viewing any diff in the PR, for each comment on a removal, perform a diff from the `commit_sha` (last commit that the line of code existed in) to the current commit being viewed, and verify that within that diff the left-hand-side line removal still exists at the same line of code in the diff, by comparing the current diff with the stored patch.
- If present, place the commit in the UI at the line number.
- If the line of code no longer exists in the diff at that point (for example, it was removed, commented upon, and then re-added in a later commit), then the comment is considered outdated and isn't displayed.
The algorithm used for marking a comment as "outdated" is also updated to use this approach.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [x] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12092
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-13 18:26:53 +02:00
|
|
|
func InvalidateCodeComments(ctx context.Context, prs issues_model.PullRequestList, doer *user_model.User, repo *repo_model.Repository, newCommitID string) error {
|
2023-01-18 05:03:44 +08:00
|
|
|
if len(prs) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
issueIDs := prs.GetIssueIDs()
|
|
|
|
|
|
2023-11-24 11:49:41 +08:00
|
|
|
codeComments, err := db.Find[issues_model.Comment](ctx, issues_model.FindCommentsOptions{
|
2024-03-22 20:53:52 +08:00
|
|
|
ListOptions: db.ListOptionsAll,
|
2023-01-18 05:03:44 +08:00
|
|
|
Type: issues_model.CommentTypeCode,
|
2024-03-02 16:42:31 +01:00
|
|
|
Invalidated: optional.Some(false),
|
2023-01-18 05:03:44 +08:00
|
|
|
IssueIDs: issueIDs,
|
2023-11-24 11:49:41 +08:00
|
|
|
})
|
|
|
|
|
if err != nil {
|
2023-01-18 05:03:44 +08:00
|
|
|
return fmt.Errorf("find code comments: %v", err)
|
|
|
|
|
}
|
|
|
|
|
for _, comment := range codeComments {
|
fix: display code comments on removed lines-of-code to correct locations in PR view (#12092)
With the completion of #12015, when a comment is left on a changed line in a pull request, we track the comment against the line of code with `git blame` and then identify where it currently is in any diff with `git blame --reverse`. However, this strategy only works for the *modified* lines of code -- eg. the `+...` in diffs, and not the `-...` in diffs. The reason is that `git blame --reverse` can't track a line of code's location past the commit that it was removed in.
To permit comments that are left on lines of code that are removed to appear correctly in the UI, a separate approach is required for those comments. This PR performs two major changes, which have been complex to figure out, but are reasonably easy to understand:
- When a comment is placed on a removed line in a PR, perform a `git blame --reverse` from the PR's base to the currently viewed commit, and use this information to record in the comment:
- the **last commit that the line of code existed in** (stored in the `commit_sha` field)
- the **line of code as of that commit** (stored in the `line` field, negative, to indicate that the comment is on a removal).
- the **patch** where the comment was placed (stored in the field `patch`); existing functionality unchanged in this PR
- When viewing any diff in the PR, for each comment on a removal, perform a diff from the `commit_sha` (last commit that the line of code existed in) to the current commit being viewed, and verify that within that diff the left-hand-side line removal still exists at the same line of code in the diff, by comparing the current diff with the stored patch.
- If present, place the commit in the UI at the line number.
- If the line of code no longer exists in the diff at that point (for example, it was removed, commented upon, and then re-added in a later commit), then the comment is considered outdated and isn't displayed.
The algorithm used for marking a comment as "outdated" is also updated to use this approach.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [x] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12092
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-13 18:26:53 +02:00
|
|
|
if err := checkInvalidation(ctx, comment, repo, newCommitID); err != nil {
|
2023-01-18 05:03:44 +08:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-14 10:57:36 +08:00
|
|
|
// CreateCodeComment creates a comment on the code line
|
fix: when reviewing in PRs, make comments relative to viewed base & head, not just viewed head (#12107)
While developing tests for #12092, I came across a case where making a comment on a single-commit doesn't include the correct diff for the comment. This is because code comment placement occurs between the PR's base and the commit being viewed, but, that diff could be different from the commit's parent to the commit, which is what is being viewed on a single-commit diff.
Similar to #12055, this PR changes code comments to be more precise in their diff generation by providing the backend with both the base commit (`before_commit_id`) and head commit (`after_commit_id`) currently being viewed. As a result, the diffs attached to comments should exactly match the diffs being viewed by the user when the comment was placed.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12107
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-14 17:18:14 +02:00
|
|
|
func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.Repository,
|
|
|
|
|
issue *issues_model.Issue, line int64, content, treePath string, pendingReview bool,
|
|
|
|
|
replyReviewID int64, beforeCommitID, latestCommitID string, attachments []string,
|
|
|
|
|
) (*issues_model.Comment, error) {
|
2019-11-24 02:46:16 -03:00
|
|
|
var (
|
|
|
|
|
existsReview bool
|
|
|
|
|
err error
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// CreateCodeComment() is used for:
|
|
|
|
|
// - Single comments
|
|
|
|
|
// - Comments that are part of a review
|
|
|
|
|
// - Comments that reply to an existing review
|
|
|
|
|
|
2023-03-04 15:13:37 +08:00
|
|
|
if !pendingReview && replyReviewID != 0 {
|
2019-11-24 02:46:16 -03:00
|
|
|
// It's not part of a review; maybe a reply to a review comment or a single comment.
|
|
|
|
|
// Check if there are reviews for that line already; if there are, this is a reply
|
2023-09-29 14:12:54 +02:00
|
|
|
if existsReview, err = issues_model.ReviewExists(ctx, issue, treePath, line); err != nil {
|
2019-11-24 02:46:16 -03:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Comments that are replies don't require a review header to show up in the issue view
|
2023-03-04 15:13:37 +08:00
|
|
|
if !pendingReview && existsReview {
|
2022-04-08 17:11:15 +08:00
|
|
|
if err = issue.LoadRepo(ctx); err != nil {
|
2019-11-14 10:57:36 +08:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-09 12:49:18 +01:00
|
|
|
comment, err := CreateCodeCommentKnownReviewID(ctx,
|
2019-11-14 10:57:36 +08:00
|
|
|
doer,
|
|
|
|
|
issue.Repo,
|
|
|
|
|
issue,
|
|
|
|
|
content,
|
|
|
|
|
treePath,
|
fix: when reviewing in PRs, make comments relative to viewed base & head, not just viewed head (#12107)
While developing tests for #12092, I came across a case where making a comment on a single-commit doesn't include the correct diff for the comment. This is because code comment placement occurs between the PR's base and the commit being viewed, but, that diff could be different from the commit's parent to the commit, which is what is being viewed on a single-commit diff.
Similar to #12055, this PR changes code comments to be more precise in their diff generation by providing the backend with both the base commit (`before_commit_id`) and head commit (`after_commit_id`) currently being viewed. As a result, the diffs attached to comments should exactly match the diffs being viewed by the user when the comment was placed.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12107
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-14 17:18:14 +02:00
|
|
|
beforeCommitID,
|
fix: when reviewing in PRs, make comments relative to the visible code's commit (#12055)
When performing `git blame` to identify the commit that a line of code came from, limit the blame to the commit that is currently being viewed in the UI. Before this change, the blame always occurred on the current head of the PR, causing these problems:
- When you click ➕ to load the comment form, the form that is dynamically loaded would have it's commit field pulled from the current PR head. That may not actually reflect the code that you were viewing at the time you authored the comment -- it could be a newer commit that occurred by the author while you were reviewing.
- When viewing a specific commit within a PR and leaving a comment, the blame would occur from the head -- if the file was changed in a later commit and the line-of-code moved up or down, the comment would be misplaced.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [ ] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
<!--start release-notes-assistant-->
## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
- [PR](https://codeberg.org/forgejo/forgejo/pulls/12055): <!--number 12055 --><!--line 0 --><!--description d2hlbiByZXZpZXdpbmcgaW4gUFJzLCBtYWtlIGNvbW1lbnRzIHJlbGF0aXZlIHRvIHRoZSB2aXNpYmxlIGNvZGUncyBjb21taXQ=-->when reviewing in PRs, make comments relative to the visible code's commit<!--description-->
<!--end release-notes-assistant-->
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12055
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-12 01:20:54 +02:00
|
|
|
latestCommitID,
|
2019-11-14 10:57:36 +08:00
|
|
|
line,
|
|
|
|
|
replyReviewID,
|
2024-02-25 07:00:55 +01:00
|
|
|
attachments,
|
2019-11-14 10:57:36 +08:00
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 17:37:59 +08:00
|
|
|
mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content)
|
2021-01-02 18:04:02 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 02:37:47 +08:00
|
|
|
notify_service.CreateIssueComment(ctx, doer, issue.Repo, issue, comment, mentions)
|
2019-11-14 10:57:36 +08:00
|
|
|
|
|
|
|
|
return comment, nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 17:37:59 +08:00
|
|
|
review, err := issues_model.GetCurrentReview(ctx, doer, issue)
|
2019-11-14 10:57:36 +08:00
|
|
|
if err != nil {
|
2022-06-13 17:37:59 +08:00
|
|
|
if !issues_model.IsErrReviewNotExist(err) {
|
2019-11-14 10:57:36 +08:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 17:37:59 +08:00
|
|
|
if review, err = issues_model.CreateReview(ctx, issues_model.CreateReviewOptions{
|
|
|
|
|
Type: issues_model.ReviewTypePending,
|
2019-11-14 10:57:36 +08:00
|
|
|
Reviewer: doer,
|
|
|
|
|
Issue: issue,
|
2019-12-04 02:08:56 +01:00
|
|
|
Official: false,
|
2020-01-09 02:47:45 +01:00
|
|
|
CommitID: latestCommitID,
|
2020-10-13 03:55:13 +08:00
|
|
|
}); err != nil {
|
2019-11-14 10:57:36 +08:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-09 12:49:18 +01:00
|
|
|
comment, err := CreateCodeCommentKnownReviewID(ctx,
|
2019-11-14 10:57:36 +08:00
|
|
|
doer,
|
|
|
|
|
issue.Repo,
|
|
|
|
|
issue,
|
|
|
|
|
content,
|
|
|
|
|
treePath,
|
fix: when reviewing in PRs, make comments relative to viewed base & head, not just viewed head (#12107)
While developing tests for #12092, I came across a case where making a comment on a single-commit doesn't include the correct diff for the comment. This is because code comment placement occurs between the PR's base and the commit being viewed, but, that diff could be different from the commit's parent to the commit, which is what is being viewed on a single-commit diff.
Similar to #12055, this PR changes code comments to be more precise in their diff generation by providing the backend with both the base commit (`before_commit_id`) and head commit (`after_commit_id`) currently being viewed. As a result, the diffs attached to comments should exactly match the diffs being viewed by the user when the comment was placed.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12107
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-14 17:18:14 +02:00
|
|
|
beforeCommitID,
|
fix: when reviewing in PRs, make comments relative to the visible code's commit (#12055)
When performing `git blame` to identify the commit that a line of code came from, limit the blame to the commit that is currently being viewed in the UI. Before this change, the blame always occurred on the current head of the PR, causing these problems:
- When you click ➕ to load the comment form, the form that is dynamically loaded would have it's commit field pulled from the current PR head. That may not actually reflect the code that you were viewing at the time you authored the comment -- it could be a newer commit that occurred by the author while you were reviewing.
- When viewing a specific commit within a PR and leaving a comment, the blame would occur from the head -- if the file was changed in a later commit and the line-of-code moved up or down, the comment would be misplaced.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [ ] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
<!--start release-notes-assistant-->
## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
- [PR](https://codeberg.org/forgejo/forgejo/pulls/12055): <!--number 12055 --><!--line 0 --><!--description d2hlbiByZXZpZXdpbmcgaW4gUFJzLCBtYWtlIGNvbW1lbnRzIHJlbGF0aXZlIHRvIHRoZSB2aXNpYmxlIGNvZGUncyBjb21taXQ=-->when reviewing in PRs, make comments relative to the visible code's commit<!--description-->
<!--end release-notes-assistant-->
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12055
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-12 01:20:54 +02:00
|
|
|
latestCommitID,
|
2019-11-14 10:57:36 +08:00
|
|
|
line,
|
|
|
|
|
review.ID,
|
2024-02-25 07:00:55 +01:00
|
|
|
attachments,
|
2019-11-14 10:57:36 +08:00
|
|
|
)
|
2019-08-14 23:32:19 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-04 15:13:37 +08:00
|
|
|
if !pendingReview && !existsReview {
|
2019-11-24 02:46:16 -03:00
|
|
|
// Submit the review we've just created so the comment shows up in the issue view
|
2022-06-13 17:37:59 +08:00
|
|
|
if _, _, err = SubmitReview(ctx, doer, gitRepo, issue, issues_model.ReviewTypeComment, "", latestCommitID, nil); err != nil {
|
2019-11-24 02:46:16 -03:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NOTICE: if it's a pending review the notifications will not be fired until user submit review.
|
2019-11-14 10:57:36 +08:00
|
|
|
|
|
|
|
|
return comment, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-25 07:00:55 +01:00
|
|
|
// CreateCodeCommentKnownReviewID creates a plain code comment at the specified line / path
|
fix: when reviewing in PRs, make comments relative to viewed base & head, not just viewed head (#12107)
While developing tests for #12092, I came across a case where making a comment on a single-commit doesn't include the correct diff for the comment. This is because code comment placement occurs between the PR's base and the commit being viewed, but, that diff could be different from the commit's parent to the commit, which is what is being viewed on a single-commit diff.
Similar to #12055, this PR changes code comments to be more precise in their diff generation by providing the backend with both the base commit (`before_commit_id`) and head commit (`after_commit_id`) currently being viewed. As a result, the diffs attached to comments should exactly match the diffs being viewed by the user when the comment was placed.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12107
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-14 17:18:14 +02:00
|
|
|
func CreateCodeCommentKnownReviewID(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
|
|
|
|
|
issue *issues_model.Issue, content, treePath, beforeCommitID, afterCommitID string,
|
|
|
|
|
line, reviewID int64, attachments []string,
|
|
|
|
|
) (*issues_model.Comment, error) {
|
2025-10-31 16:17:23 +01:00
|
|
|
var commitID, blamedCommitID, patch string
|
|
|
|
|
blamedLine := line
|
2022-11-19 09:12:33 +01:00
|
|
|
if err := issue.LoadPullRequest(ctx); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("LoadPullRequest: %w", err)
|
2019-11-14 10:57:36 +08:00
|
|
|
}
|
|
|
|
|
pr := issue.PullRequest
|
2022-11-19 09:12:33 +01:00
|
|
|
if err := pr.LoadBaseRepo(ctx); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("LoadBaseRepo: %w", err)
|
2019-11-14 10:57:36 +08:00
|
|
|
}
|
Simplify how git repositories are opened (#28937)
## Purpose
This is a refactor toward building an abstraction over managing git
repositories.
Afterwards, it does not matter anymore if they are stored on the local
disk or somewhere remote.
## What this PR changes
We used `git.OpenRepository` everywhere previously.
Now, we should split them into two distinct functions:
Firstly, there are temporary repositories which do not change:
```go
git.OpenRepository(ctx, diskPath)
```
Gitea managed repositories having a record in the database in the
`repository` table are moved into the new package `gitrepo`:
```go
gitrepo.OpenRepository(ctx, repo_model.Repo)
```
Why is `repo_model.Repository` the second parameter instead of file
path?
Because then we can easily adapt our repository storage strategy.
The repositories can be stored locally, however, they could just as well
be stored on a remote server.
## Further changes in other PRs
- A Git Command wrapper on package `gitrepo` could be created. i.e.
`NewCommand(ctx, repo_model.Repository, commands...)`. `git.RunOpts{Dir:
repo.RepoPath()}`, the directory should be empty before invoking this
method and it can be filled in the function only. #28940
- Remove the `RepoPath()`/`WikiPath()` functions to reduce the
possibility of mistakes.
---------
Co-authored-by: delvh <dev.lh@web.de>
2024-01-28 04:09:51 +08:00
|
|
|
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo)
|
2019-11-14 10:57:36 +08:00
|
|
|
if err != nil {
|
2022-10-24 21:29:17 +02:00
|
|
|
return nil, fmt.Errorf("RepositoryFromContextOrOpen: %w", err)
|
2019-11-13 15:36:04 -03:00
|
|
|
}
|
2022-01-19 23:26:57 +00:00
|
|
|
defer closer.Close()
|
2019-11-05 19:04:08 +08:00
|
|
|
|
2020-11-09 06:15:09 +00:00
|
|
|
invalidated := false
|
|
|
|
|
head := pr.GetGitRefName()
|
2019-11-14 10:57:36 +08:00
|
|
|
if line > 0 {
|
2020-11-09 06:15:09 +00:00
|
|
|
if reviewID != 0 {
|
2022-06-13 17:37:59 +08:00
|
|
|
first, err := issues_model.FindComments(ctx, &issues_model.FindCommentsOptions{
|
2020-11-09 06:15:09 +00:00
|
|
|
ReviewID: reviewID,
|
|
|
|
|
Line: line,
|
|
|
|
|
TreePath: treePath,
|
2022-06-13 17:37:59 +08:00
|
|
|
Type: issues_model.CommentTypeCode,
|
2021-09-24 19:32:56 +08:00
|
|
|
ListOptions: db.ListOptions{
|
2020-11-09 06:15:09 +00:00
|
|
|
PageSize: 1,
|
|
|
|
|
Page: 1,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
if err == nil && len(first) > 0 {
|
|
|
|
|
commitID = first[0].CommitSHA
|
|
|
|
|
invalidated = first[0].Invalidated
|
|
|
|
|
patch = first[0].Patch
|
2022-06-13 17:37:59 +08:00
|
|
|
} else if err != nil && !issues_model.IsErrCommentNotExist(err) {
|
2022-10-24 21:29:17 +02:00
|
|
|
return nil, fmt.Errorf("Find first comment for %d line %d path %s. Error: %w", reviewID, line, treePath, err)
|
2020-11-09 06:15:09 +00:00
|
|
|
} else {
|
2022-06-13 17:37:59 +08:00
|
|
|
review, err := issues_model.GetReviewByID(ctx, reviewID)
|
2020-11-09 06:15:09 +00:00
|
|
|
if err == nil && len(review.CommitID) > 0 {
|
|
|
|
|
head = review.CommitID
|
2022-06-13 17:37:59 +08:00
|
|
|
} else if err != nil && !issues_model.IsErrReviewNotExist(err) {
|
2022-10-24 21:29:17 +02:00
|
|
|
return nil, fmt.Errorf("GetReviewByID %d. Error: %w", reviewID, err)
|
2020-11-09 06:15:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(commitID) == 0 {
|
|
|
|
|
// FIXME validate treePath
|
|
|
|
|
// Get latest commit referencing the commented line
|
|
|
|
|
// No need for get commit for base branch changes
|
fix: when reviewing in PRs, make comments relative to the visible code's commit (#12055)
When performing `git blame` to identify the commit that a line of code came from, limit the blame to the commit that is currently being viewed in the UI. Before this change, the blame always occurred on the current head of the PR, causing these problems:
- When you click ➕ to load the comment form, the form that is dynamically loaded would have it's commit field pulled from the current PR head. That may not actually reflect the code that you were viewing at the time you authored the comment -- it could be a newer commit that occurred by the author while you were reviewing.
- When viewing a specific commit within a PR and leaving a comment, the blame would occur from the head -- if the file was changed in a later commit and the line-of-code moved up or down, the comment would be misplaced.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [ ] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
<!--start release-notes-assistant-->
## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
- [PR](https://codeberg.org/forgejo/forgejo/pulls/12055): <!--number 12055 --><!--line 0 --><!--description d2hlbiByZXZpZXdpbmcgaW4gUFJzLCBtYWtlIGNvbW1lbnRzIHJlbGF0aXZlIHRvIHRoZSB2aXNpYmxlIGNvZGUncyBjb21taXQ=-->when reviewing in PRs, make comments relative to the visible code's commit<!--description-->
<!--end release-notes-assistant-->
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12055
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-12 01:20:54 +02:00
|
|
|
commit, lineres, err := gitRepo.LineBlame(afterCommitID, treePath, uint64(line))
|
2020-11-09 06:15:09 +00:00
|
|
|
if err == nil {
|
2025-10-31 16:17:23 +01:00
|
|
|
blamedCommitID = commit.ID.String()
|
|
|
|
|
blamedLine = int64(lineres)
|
2025-07-05 16:31:53 +02:00
|
|
|
} else if !errors.Is(err, git.ErrBlameFileDoesNotExist) && !errors.Is(err, git.ErrBlameFileNotEnoughLines) {
|
2022-10-24 21:29:17 +02:00
|
|
|
return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %w", pr.GetGitRefName(), gitRepo.Path, treePath, line, err)
|
2020-11-09 06:15:09 +00:00
|
|
|
}
|
2025-10-31 16:17:23 +01:00
|
|
|
} else {
|
|
|
|
|
blamedCommitID = commitID
|
2019-11-14 10:57:36 +08:00
|
|
|
}
|
fix: display code comments on removed lines-of-code to correct locations in PR view (#12092)
With the completion of #12015, when a comment is left on a changed line in a pull request, we track the comment against the line of code with `git blame` and then identify where it currently is in any diff with `git blame --reverse`. However, this strategy only works for the *modified* lines of code -- eg. the `+...` in diffs, and not the `-...` in diffs. The reason is that `git blame --reverse` can't track a line of code's location past the commit that it was removed in.
To permit comments that are left on lines of code that are removed to appear correctly in the UI, a separate approach is required for those comments. This PR performs two major changes, which have been complex to figure out, but are reasonably easy to understand:
- When a comment is placed on a removed line in a PR, perform a `git blame --reverse` from the PR's base to the currently viewed commit, and use this information to record in the comment:
- the **last commit that the line of code existed in** (stored in the `commit_sha` field)
- the **line of code as of that commit** (stored in the `line` field, negative, to indicate that the comment is on a removal).
- the **patch** where the comment was placed (stored in the field `patch`); existing functionality unchanged in this PR
- When viewing any diff in the PR, for each comment on a removal, perform a diff from the `commit_sha` (last commit that the line of code existed in) to the current commit being viewed, and verify that within that diff the left-hand-side line removal still exists at the same line of code in the diff, by comparing the current diff with the stored patch.
- If present, place the commit in the UI at the line number.
- If the line of code no longer exists in the diff at that point (for example, it was removed, commented upon, and then re-added in a later commit), then the comment is considered outdated and isn't displayed.
The algorithm used for marking a comment as "outdated" is also updated to use this approach.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [x] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12092
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-13 18:26:53 +02:00
|
|
|
} else {
|
|
|
|
|
// Commenting on a line that was removed. In this case, what we want to track in the comment is which line of
|
|
|
|
|
// code was this, in the last commit that the line of code actually existed in. We'll use a reverse git blame to
|
|
|
|
|
// identify this, from the PR base -> commit being viewed.
|
fix: when reviewing in PRs, make comments relative to viewed base & head, not just viewed head (#12107)
While developing tests for #12092, I came across a case where making a comment on a single-commit doesn't include the correct diff for the comment. This is because code comment placement occurs between the PR's base and the commit being viewed, but, that diff could be different from the commit's parent to the commit, which is what is being viewed on a single-commit diff.
Similar to #12055, this PR changes code comments to be more precise in their diff generation by providing the backend with both the base commit (`before_commit_id`) and head commit (`after_commit_id`) currently being viewed. As a result, the diffs attached to comments should exactly match the diffs being viewed by the user when the comment was placed.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12107
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-14 17:18:14 +02:00
|
|
|
blame, err := gitRepo.ReverseLineBlame(beforeCommitID, treePath, uint64(-1*line), afterCommitID)
|
fix: display code comments on removed lines-of-code to correct locations in PR view (#12092)
With the completion of #12015, when a comment is left on a changed line in a pull request, we track the comment against the line of code with `git blame` and then identify where it currently is in any diff with `git blame --reverse`. However, this strategy only works for the *modified* lines of code -- eg. the `+...` in diffs, and not the `-...` in diffs. The reason is that `git blame --reverse` can't track a line of code's location past the commit that it was removed in.
To permit comments that are left on lines of code that are removed to appear correctly in the UI, a separate approach is required for those comments. This PR performs two major changes, which have been complex to figure out, but are reasonably easy to understand:
- When a comment is placed on a removed line in a PR, perform a `git blame --reverse` from the PR's base to the currently viewed commit, and use this information to record in the comment:
- the **last commit that the line of code existed in** (stored in the `commit_sha` field)
- the **line of code as of that commit** (stored in the `line` field, negative, to indicate that the comment is on a removal).
- the **patch** where the comment was placed (stored in the field `patch`); existing functionality unchanged in this PR
- When viewing any diff in the PR, for each comment on a removal, perform a diff from the `commit_sha` (last commit that the line of code existed in) to the current commit being viewed, and verify that within that diff the left-hand-side line removal still exists at the same line of code in the diff, by comparing the current diff with the stored patch.
- If present, place the commit in the UI at the line number.
- If the line of code no longer exists in the diff at that point (for example, it was removed, commented upon, and then re-added in a later commit), then the comment is considered outdated and isn't displayed.
The algorithm used for marking a comment as "outdated" is also updated to use this approach.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [x] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12092
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-13 18:26:53 +02:00
|
|
|
if err != nil {
|
fix: when reviewing in PRs, make comments relative to viewed base & head, not just viewed head (#12107)
While developing tests for #12092, I came across a case where making a comment on a single-commit doesn't include the correct diff for the comment. This is because code comment placement occurs between the PR's base and the commit being viewed, but, that diff could be different from the commit's parent to the commit, which is what is being viewed on a single-commit diff.
Similar to #12055, this PR changes code comments to be more precise in their diff generation by providing the backend with both the base commit (`before_commit_id`) and head commit (`after_commit_id`) currently being viewed. As a result, the diffs attached to comments should exactly match the diffs being viewed by the user when the comment was placed.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12107
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-14 17:18:14 +02:00
|
|
|
return nil, fmt.Errorf("ReverseLineBlame[%s, %s, %d, %s]: %w", beforeCommitID, treePath, -1*line, afterCommitID, err)
|
fix: display code comments on removed lines-of-code to correct locations in PR view (#12092)
With the completion of #12015, when a comment is left on a changed line in a pull request, we track the comment against the line of code with `git blame` and then identify where it currently is in any diff with `git blame --reverse`. However, this strategy only works for the *modified* lines of code -- eg. the `+...` in diffs, and not the `-...` in diffs. The reason is that `git blame --reverse` can't track a line of code's location past the commit that it was removed in.
To permit comments that are left on lines of code that are removed to appear correctly in the UI, a separate approach is required for those comments. This PR performs two major changes, which have been complex to figure out, but are reasonably easy to understand:
- When a comment is placed on a removed line in a PR, perform a `git blame --reverse` from the PR's base to the currently viewed commit, and use this information to record in the comment:
- the **last commit that the line of code existed in** (stored in the `commit_sha` field)
- the **line of code as of that commit** (stored in the `line` field, negative, to indicate that the comment is on a removal).
- the **patch** where the comment was placed (stored in the field `patch`); existing functionality unchanged in this PR
- When viewing any diff in the PR, for each comment on a removal, perform a diff from the `commit_sha` (last commit that the line of code existed in) to the current commit being viewed, and verify that within that diff the left-hand-side line removal still exists at the same line of code in the diff, by comparing the current diff with the stored patch.
- If present, place the commit in the UI at the line number.
- If the line of code no longer exists in the diff at that point (for example, it was removed, commented upon, and then re-added in a later commit), then the comment is considered outdated and isn't displayed.
The algorithm used for marking a comment as "outdated" is also updated to use this approach.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [x] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12092
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-13 18:26:53 +02:00
|
|
|
} else if blame.CommitID == afterCommitID {
|
|
|
|
|
// Although this is a comment on the "previous" side of the diff, the reverse blame indicates that the line
|
|
|
|
|
// of code still exists in the commit being viewed (eg. it was a comment on a white line in the left-side of
|
|
|
|
|
// the diff, not a red removed line). In order to record the right information for where to place this
|
|
|
|
|
// commit, we'll convert this into a right-hand comment -- using the present line number that the reverse
|
|
|
|
|
// blame gave us:
|
|
|
|
|
commit, lineres, err := gitRepo.LineBlame(afterCommitID, treePath, blame.LineNumber)
|
|
|
|
|
if err == nil {
|
|
|
|
|
blamedCommitID = commit.ID.String()
|
|
|
|
|
blamedLine = int64(lineres)
|
|
|
|
|
} else if !errors.Is(err, git.ErrBlameFileDoesNotExist) && !errors.Is(err, git.ErrBlameFileNotEnoughLines) {
|
|
|
|
|
return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %w", pr.GetGitRefName(), gitRepo.Path, treePath, line, err)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
blamedCommitID = blame.CommitID
|
|
|
|
|
// retain negative line numbering to identify we're commenting on the "previous" side of the diff
|
|
|
|
|
blamedLine = -1 * int64(blame.LineNumber)
|
|
|
|
|
}
|
2019-11-14 10:57:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only fetch diff if comment is review comment
|
2020-11-09 06:15:09 +00:00
|
|
|
if len(patch) == 0 && reviewID != 0 {
|
|
|
|
|
if len(commitID) == 0 {
|
2025-09-20 22:47:52 +02:00
|
|
|
commitID, err = gitRepo.GetRefCommitID(head)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("GetRefCommitID[%s]: %w", head, err)
|
|
|
|
|
}
|
2019-11-14 10:57:36 +08:00
|
|
|
}
|
2025-10-31 16:17:23 +01:00
|
|
|
if len(blamedCommitID) == 0 {
|
|
|
|
|
blamedCommitID = commitID
|
|
|
|
|
}
|
2021-02-27 18:46:14 +00:00
|
|
|
reader, writer := io.Pipe()
|
|
|
|
|
defer func() {
|
|
|
|
|
_ = reader.Close()
|
|
|
|
|
_ = writer.Close()
|
|
|
|
|
}()
|
|
|
|
|
go func() {
|
fix: when reviewing in PRs, make comments relative to viewed base & head, not just viewed head (#12107)
While developing tests for #12092, I came across a case where making a comment on a single-commit doesn't include the correct diff for the comment. This is because code comment placement occurs between the PR's base and the commit being viewed, but, that diff could be different from the commit's parent to the commit, which is what is being viewed on a single-commit diff.
Similar to #12055, this PR changes code comments to be more precise in their diff generation by providing the backend with both the base commit (`before_commit_id`) and head commit (`after_commit_id`) currently being viewed. As a result, the diffs attached to comments should exactly match the diffs being viewed by the user when the comment was placed.
## Checklist
The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).
### Tests for Go changes
- I added test coverage for Go changes...
- [ ] in their respective `*_test.go` for unit tests.
- [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
- [x] `make pr-go` before pushing
### Documentation
- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.
### Release notes
- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12107
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-04-14 17:18:14 +02:00
|
|
|
if err := git.GetRepoRawDiffForFile(gitRepo, beforeCommitID, afterCommitID, git.RawDiffNormal, treePath, writer); err != nil {
|
|
|
|
|
_ = writer.CloseWithError(fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %w", gitRepo.Path, pr.MergeBase, afterCommitID, treePath, err))
|
2021-02-27 18:46:14 +00:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
_ = writer.Close()
|
|
|
|
|
}()
|
|
|
|
|
|
2022-06-13 17:37:59 +08:00
|
|
|
patch, err = git.CutDiffAroundLine(reader, int64((&issues_model.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines)
|
2021-02-27 18:46:14 +00:00
|
|
|
if err != nil {
|
|
|
|
|
log.Error("Error whilst generating patch: %v", err)
|
|
|
|
|
return nil, err
|
2019-11-14 10:57:36 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-08-04 21:34:34 +08:00
|
|
|
return issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{
|
2022-06-13 17:37:59 +08:00
|
|
|
Type: issues_model.CommentTypeCode,
|
2020-11-09 06:15:09 +00:00
|
|
|
Doer: doer,
|
|
|
|
|
Repo: repo,
|
|
|
|
|
Issue: issue,
|
|
|
|
|
Content: content,
|
2025-10-31 16:17:23 +01:00
|
|
|
LineNum: blamedLine,
|
2020-11-09 06:15:09 +00:00
|
|
|
TreePath: treePath,
|
2025-10-31 16:17:23 +01:00
|
|
|
CommitSHA: blamedCommitID,
|
2020-11-09 06:15:09 +00:00
|
|
|
ReviewID: reviewID,
|
|
|
|
|
Patch: patch,
|
|
|
|
|
Invalidated: invalidated,
|
2024-02-25 07:00:55 +01:00
|
|
|
Attachments: attachments,
|
2019-11-14 10:57:36 +08:00
|
|
|
})
|
2019-10-18 03:33:19 -05:00
|
|
|
}
|
|
|
|
|
|
2019-11-14 10:57:36 +08:00
|
|
|
// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
|
2022-06-13 17:37:59 +08:00
|
|
|
func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, reviewType issues_model.ReviewType, content, commitID string, attachmentUUIDs []string) (*issues_model.Review, *issues_model.Comment, error) {
|
2024-03-21 21:13:08 +08:00
|
|
|
if err := issue.LoadPullRequest(ctx); err != nil {
|
2019-11-14 10:57:36 +08:00
|
|
|
return nil, nil, err
|
2019-10-18 03:33:19 -05:00
|
|
|
}
|
|
|
|
|
|
2024-03-21 21:13:08 +08:00
|
|
|
pr := issue.PullRequest
|
2020-01-09 02:47:45 +01:00
|
|
|
var stale bool
|
2022-06-13 17:37:59 +08:00
|
|
|
if reviewType != issues_model.ReviewTypeApprove && reviewType != issues_model.ReviewTypeReject {
|
2020-01-09 02:47:45 +01:00
|
|
|
stale = false
|
|
|
|
|
} else {
|
|
|
|
|
headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if headCommitID == commitID {
|
|
|
|
|
stale = false
|
|
|
|
|
} else {
|
2025-07-16 18:19:27 +02:00
|
|
|
testPatchCtx, err := getTestPatchCtx(ctx, pr, true)
|
|
|
|
|
defer testPatchCtx.close()
|
2020-01-09 02:47:45 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
}
|
2025-07-16 18:19:27 +02:00
|
|
|
|
|
|
|
|
stale, err = testPatchCtx.gitRepo.CheckIfDiffDiffers(testPatchCtx.baseRev, commitID, headCommitID, testPatchCtx.env)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, fmt.Errorf("CheckIfDiffDiffers: %w", err)
|
|
|
|
|
}
|
2020-01-09 02:47:45 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-29 14:12:54 +02:00
|
|
|
review, comm, err := issues_model.SubmitReview(ctx, doer, issue, reviewType, content, commitID, stale, attachmentUUIDs)
|
2019-11-14 10:57:36 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
}
|
2020-01-09 02:47:45 +01:00
|
|
|
|
2022-06-13 17:37:59 +08:00
|
|
|
mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comm.Content)
|
2021-01-02 18:04:02 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 02:37:47 +08:00
|
|
|
notify_service.PullRequestReview(ctx, pr, review, comm, mentions)
|
2021-01-02 18:04:02 +01:00
|
|
|
|
|
|
|
|
for _, lines := range review.CodeComments {
|
|
|
|
|
for _, comments := range lines {
|
|
|
|
|
for _, codeComment := range comments {
|
2022-06-13 17:37:59 +08:00
|
|
|
mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, codeComment.Content)
|
2021-01-02 18:04:02 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, err
|
|
|
|
|
}
|
2023-09-06 02:37:47 +08:00
|
|
|
notify_service.PullRequestCodeComment(ctx, pr, codeComment, mentions)
|
2021-01-02 18:04:02 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-08-14 23:32:19 +08:00
|
|
|
|
2019-11-14 10:57:36 +08:00
|
|
|
return review, comm, nil
|
2019-08-14 23:32:19 +08:00
|
|
|
}
|
2021-02-12 01:32:25 +08:00
|
|
|
|
2023-07-20 15:18:52 +08:00
|
|
|
// DismissApprovalReviews dismiss all approval reviews because of new commits
|
|
|
|
|
func DismissApprovalReviews(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest) error {
|
|
|
|
|
reviews, err := issues_model.FindReviews(ctx, issues_model.FindReviewOptions{
|
2024-03-22 20:53:52 +08:00
|
|
|
ListOptions: db.ListOptionsAll,
|
|
|
|
|
IssueID: pull.IssueID,
|
2024-10-01 09:58:55 +08:00
|
|
|
Types: []issues_model.ReviewType{issues_model.ReviewTypeApprove},
|
2024-03-22 20:53:52 +08:00
|
|
|
Dismissed: optional.Some(false),
|
2023-07-20 15:18:52 +08:00
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := reviews.LoadIssues(ctx); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-28 12:06:47 +08:00
|
|
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
2023-07-20 15:18:52 +08:00
|
|
|
for _, review := range reviews {
|
2023-08-28 12:06:47 +08:00
|
|
|
if err := issues_model.DismissReview(ctx, review, true); err != nil {
|
2023-07-20 15:18:52 +08:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-04 21:34:34 +08:00
|
|
|
comment, err := issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{
|
2023-07-20 15:18:52 +08:00
|
|
|
Doer: doer,
|
|
|
|
|
Content: "New commits pushed, approval review dismissed automatically according to repository settings",
|
|
|
|
|
Type: issues_model.CommentTypeDismissReview,
|
|
|
|
|
ReviewID: review.ID,
|
|
|
|
|
Issue: review.Issue,
|
|
|
|
|
Repo: review.Issue.Repo,
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comment.Review = review
|
|
|
|
|
comment.Poster = doer
|
|
|
|
|
comment.Issue = review.Issue
|
|
|
|
|
|
2023-09-06 02:37:47 +08:00
|
|
|
notify_service.PullReviewDismiss(ctx, doer, review, comment)
|
2023-07-20 15:18:52 +08:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 01:32:25 +08:00
|
|
|
// DismissReview dismissing stale review by repo admin
|
2022-07-19 15:20:28 +02:00
|
|
|
func DismissReview(ctx context.Context, reviewID, repoID int64, message string, doer *user_model.User, isDismiss, dismissPriors bool) (comment *issues_model.Comment, err error) {
|
2022-06-13 17:37:59 +08:00
|
|
|
review, err := issues_model.GetReviewByID(ctx, reviewID)
|
2021-02-12 01:32:25 +08:00
|
|
|
if err != nil {
|
2023-07-07 07:31:56 +02:00
|
|
|
return nil, err
|
2021-02-12 01:32:25 +08:00
|
|
|
}
|
|
|
|
|
|
2022-06-13 17:37:59 +08:00
|
|
|
if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject {
|
2025-05-29 17:34:29 +02:00
|
|
|
return nil, errors.New("not need to dismiss this review because it's type is not Approve or change request")
|
2021-02-12 01:32:25 +08:00
|
|
|
}
|
|
|
|
|
|
2022-06-30 23:55:08 +08:00
|
|
|
// load data for notify
|
2023-07-07 07:31:56 +02:00
|
|
|
if err := review.LoadAttributes(ctx); err != nil {
|
2022-06-30 23:55:08 +08:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if the review's repoID is the one we're currently expecting.
|
|
|
|
|
if review.Issue.RepoID != repoID {
|
2025-05-29 17:34:29 +02:00
|
|
|
return nil, errors.New("reviews's repository is not the same as the one we expect")
|
2022-06-30 23:55:08 +08:00
|
|
|
}
|
|
|
|
|
|
2024-03-28 08:19:24 -07:00
|
|
|
issue := review.Issue
|
|
|
|
|
|
|
|
|
|
if issue.IsClosed {
|
|
|
|
|
return nil, ErrDismissRequestOnClosedPR{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if issue.IsPull {
|
|
|
|
|
if err := issue.LoadPullRequest(ctx); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if issue.PullRequest.HasMerged {
|
|
|
|
|
return nil, ErrDismissRequestOnClosedPR{}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-20 15:18:52 +08:00
|
|
|
if err := issues_model.DismissReview(ctx, review, isDismiss); err != nil {
|
2023-07-07 07:31:56 +02:00
|
|
|
return nil, err
|
2021-02-12 01:32:25 +08:00
|
|
|
}
|
|
|
|
|
|
2022-07-19 15:20:28 +02:00
|
|
|
if dismissPriors {
|
2023-07-20 15:18:52 +08:00
|
|
|
reviews, err := issues_model.FindReviews(ctx, issues_model.FindReviewOptions{
|
2022-07-19 15:20:28 +02:00
|
|
|
IssueID: review.IssueID,
|
|
|
|
|
ReviewerID: review.ReviewerID,
|
2024-03-02 16:42:31 +01:00
|
|
|
Dismissed: optional.Some(false),
|
2022-07-19 15:20:28 +02:00
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
for _, oldReview := range reviews {
|
2023-07-20 15:18:52 +08:00
|
|
|
if err = issues_model.DismissReview(ctx, oldReview, true); err != nil {
|
2022-07-19 15:20:28 +02:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 01:32:25 +08:00
|
|
|
if !isDismiss {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-07 07:31:56 +02:00
|
|
|
if err := review.Issue.LoadAttributes(ctx); err != nil {
|
|
|
|
|
return nil, err
|
2021-02-12 01:32:25 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-04 21:34:34 +08:00
|
|
|
comment, err = issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{
|
2021-02-12 01:32:25 +08:00
|
|
|
Doer: doer,
|
|
|
|
|
Content: message,
|
2022-06-13 17:37:59 +08:00
|
|
|
Type: issues_model.CommentTypeDismissReview,
|
2021-02-12 01:32:25 +08:00
|
|
|
ReviewID: review.ID,
|
|
|
|
|
Issue: review.Issue,
|
|
|
|
|
Repo: review.Issue.Repo,
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
2023-07-07 07:31:56 +02:00
|
|
|
return nil, err
|
2021-02-12 01:32:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comment.Review = review
|
|
|
|
|
comment.Poster = doer
|
|
|
|
|
comment.Issue = review.Issue
|
|
|
|
|
|
2023-09-06 02:37:47 +08:00
|
|
|
notify_service.PullReviewDismiss(ctx, doer, review, comment)
|
2021-02-12 01:32:25 +08:00
|
|
|
|
2023-07-07 07:31:56 +02:00
|
|
|
return comment, nil
|
2021-02-12 01:32:25 +08:00
|
|
|
}
|