mirror of
https://github.com/go-gitea/gitea.git
synced 2025-08-04 06:34:18 +00:00
Fix bug
This commit is contained in:
parent
65a01c2c47
commit
968b2c5dc1
@ -71,9 +71,14 @@ func TestFetchCodeComments(t *testing.T) {
|
||||
res, err := issues_model.FetchCodeComments(db.DefaultContext, issue.Repo, issue.ID, user, false)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, res, "README.md")
|
||||
assert.Contains(t, res["README.md"], int64(4))
|
||||
assert.Len(t, res["README.md"][4], 1)
|
||||
assert.Equal(t, int64(4), res["README.md"][0].ID)
|
||||
fourthLineComments := []*issues_model.Comment{}
|
||||
for _, comment := range res["README.md"] {
|
||||
if comment.Line == 4 {
|
||||
fourthLineComments = append(fourthLineComments, comment)
|
||||
}
|
||||
}
|
||||
assert.Len(t, fourthLineComments, 1)
|
||||
assert.Equal(t, int64(4), fourthLineComments[0].ID)
|
||||
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
res, err = issues_model.FetchCodeComments(db.DefaultContext, issue.Repo, issue.ID, user2, false)
|
||||
|
@ -392,11 +392,16 @@ func (pr *PullRequest) getReviewedByLines(ctx context.Context, writer io.Writer)
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
// GetGitHeadRefName returns git ref for hidden pull request branch
|
||||
// GetGitHeadRefName returns git head commit id ref for the pull request's branch
|
||||
func (pr *PullRequest) GetGitHeadRefName() string {
|
||||
return fmt.Sprintf("%s%d/head", git.PullPrefix, pr.Index)
|
||||
}
|
||||
|
||||
// GetGitMergeRefName returns git merged commit id ref for the pull request
|
||||
func (pr *PullRequest) GetGitMergeRefName() string {
|
||||
return fmt.Sprintf("%s%d/merge", git.PullPrefix, pr.Index)
|
||||
}
|
||||
|
||||
func (pr *PullRequest) GetGitHeadBranchRefName() string {
|
||||
return fmt.Sprintf("%s%s", git.BranchPrefix, pr.HeadBranch)
|
||||
}
|
||||
|
@ -7,11 +7,13 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
pull_model "code.gitea.io/gitea/models/pull"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@ -170,20 +172,50 @@ func renderConversation(ctx *context.Context, comment *issues_model.Comment, ori
|
||||
ctx.ServerError("comment.Issue.LoadPullRequest", err)
|
||||
return
|
||||
}
|
||||
if beforeCommitID == "" {
|
||||
beforeCommitID = comment.Issue.PullRequest.MergeBase
|
||||
|
||||
headCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(comment.Issue.PullRequest.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
ctx.ServerError("GetRefCommitID", err)
|
||||
return
|
||||
}
|
||||
if afterCommitID == "" {
|
||||
var err error
|
||||
afterCommitID, err = ctx.Repo.GitRepo.GetRefCommitID(comment.Issue.PullRequest.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
ctx.ServerError("GetRefCommitID", err)
|
||||
|
||||
prCommitIDs, err := git.CommitIDsBetween(ctx, ctx.Repo.GitRepo.Path, comment.Issue.PullRequest.MergeBase, headCommitID)
|
||||
if err != nil {
|
||||
ctx.ServerError("CommitIDsBetween", err)
|
||||
return
|
||||
}
|
||||
|
||||
if beforeCommitID == "" || beforeCommitID == comment.Issue.PullRequest.MergeBase {
|
||||
beforeCommitID = comment.Issue.PullRequest.MergeBase
|
||||
} else {
|
||||
// beforeCommitID must be one of the pull request commits
|
||||
if !slices.Contains(prCommitIDs, beforeCommitID) {
|
||||
ctx.HTTPError(http.StatusBadRequest, fmt.Sprintf("beforeCommitID[%s] is not a valid pull request commit", beforeCommitID))
|
||||
return
|
||||
}
|
||||
|
||||
beforeCommit, err := ctx.Repo.GitRepo.GetCommit(beforeCommitID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommit", err)
|
||||
return
|
||||
}
|
||||
|
||||
beforeCommit, err = beforeCommit.Parent(0)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetParent", err)
|
||||
return
|
||||
}
|
||||
beforeCommitID = beforeCommit.ID.String()
|
||||
}
|
||||
if afterCommitID == "" {
|
||||
afterCommitID = headCommitID
|
||||
} else if !slices.Contains(prCommitIDs, afterCommitID) { // afterCommitID must be one of the pull request commits
|
||||
ctx.HTTPError(http.StatusBadRequest, fmt.Sprintf("afterCommitID[%s] is not a valid pull request commit", afterCommitID))
|
||||
return
|
||||
}
|
||||
|
||||
showOutdatedComments := origin == "timeline" || ctx.Data["ShowOutdatedComments"].(bool)
|
||||
comments, err := pull_service.FetchCodeCommentsByLine(ctx, ctx.Repo.Repository, comment.IssueID,
|
||||
comments, err := pull_service.FetchCodeCommentsByLine(ctx, ctx.Repo.GitRepo, ctx.Repo.Repository, comment.IssueID,
|
||||
ctx.Doer, beforeCommitID, afterCommitID, comment.TreePath, comment.Line, showOutdatedComments)
|
||||
if err != nil {
|
||||
ctx.ServerError("FetchCodeCommentsByLine", err)
|
||||
|
@ -39,11 +39,11 @@ func StartPRCheckAndAutoMerge(ctx context.Context, pull *issues_model.PullReques
|
||||
return
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
commitID, err := gitRepo.GetRefCommitID(pull.GetGitHeadRefName())
|
||||
headCommitID, err := gitRepo.GetRefCommitID(pull.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
log.Error("GetRefCommitID: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
AddToQueue(pull, commitID)
|
||||
AddToQueue(pull, headCommitID)
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ func ToPullReview(ctx context.Context, r *issues_model.Review, doer *user_model.
|
||||
r.Reviewer = user_model.NewGhostUser()
|
||||
}
|
||||
|
||||
if err := r.Issue.LoadRepo(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &api.PullReview{
|
||||
ID: r.ID,
|
||||
Reviewer: ToUser(ctx, r.Reviewer, doer),
|
||||
|
@ -204,6 +204,11 @@ func DeleteIssue(ctx context.Context, doer *user_model.User, gitRepo *git.Reposi
|
||||
if err := git.RemoveRef(ctx, gitRepo.Path, issue.PullRequest.GetGitHeadRefName()); err != nil {
|
||||
return err
|
||||
}
|
||||
if issue.PullRequest.HasMerged {
|
||||
if err := git.RemoveRef(ctx, gitRepo.Path, issue.PullRequest.GetGitMergeRefName()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notify_service.DeleteIssue(ctx, doer, issue)
|
||||
|
@ -7,33 +7,15 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
org_model "code.gitea.io/gitea/models/organization"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
func getMergeBase(repo *git.Repository, pr *issues_model.PullRequest, baseBranch, headBranch string) (string, error) {
|
||||
// Add a temporary remote
|
||||
tmpRemote := fmt.Sprintf("mergebase-%d-%d", pr.ID, time.Now().UnixNano())
|
||||
if err := repo.AddRemote(tmpRemote, repo.Path, false); err != nil {
|
||||
return "", fmt.Errorf("AddRemote: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := repo.RemoveRemote(tmpRemote); err != nil {
|
||||
log.Error("getMergeBase: RemoveRemote: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
mergeBase, _, err := repo.GetMergeBase(tmpRemote, baseBranch, headBranch)
|
||||
return mergeBase, err
|
||||
}
|
||||
|
||||
type ReviewRequestNotifier struct {
|
||||
Comment *issues_model.Comment
|
||||
IsAdd bool
|
||||
@ -96,15 +78,9 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// get the mergebase
|
||||
mergeBase, err := getMergeBase(repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// https://github.com/go-gitea/gitea/issues/29763, we need to get the files changed
|
||||
// between the merge base and the head commit but not the base branch and the head commit
|
||||
changedFiles, err := repo.GetFilesChangedBetween(mergeBase, pr.GetGitHeadRefName())
|
||||
changedFiles, err := repo.GetFilesChangedBetween(pr.MergeBase, pr.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -726,6 +726,12 @@ func SetMerged(ctx context.Context, pr *issues_model.PullRequest, mergedCommitID
|
||||
return false, issues_model.ErrIssueAlreadyChanged
|
||||
}
|
||||
|
||||
// update merge ref, this is necessary to ensure pr.MergedCommitID can be used to do diff operations even
|
||||
// if the repository rebased/force-pushed and the pull request's merge commit is no longer in the history
|
||||
if err := git.UpdateRef(ctx, pr.BaseRepo.RepoPath(), pr.GetGitMergeRefName(), pr.MergedCommitID); err != nil {
|
||||
return false, fmt.Errorf("UpdateRef: %w", err)
|
||||
}
|
||||
|
||||
if err := committer.Commit(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -113,7 +113,12 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.
|
||||
defer closer.Close()
|
||||
}
|
||||
|
||||
prCommitIDs, err := git.CommitIDsBetween(ctx, gitRepo.Path, beforeCommitID, afterCommitID)
|
||||
headCommitID, err := gitRepo.GetRefCommitID(issue.PullRequest.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetRefCommitID[%s]: %w", issue.PullRequest.GetGitHeadRefName(), err)
|
||||
}
|
||||
|
||||
prCommitIDs, err := git.CommitIDsBetween(ctx, gitRepo.Path, issue.PullRequest.MergeBase, headCommitID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CommitIDsBetween[%s, %s]: %w", beforeCommitID, afterCommitID, err)
|
||||
}
|
||||
@ -138,10 +143,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.
|
||||
beforeCommitID = beforeCommit.ID.String()
|
||||
}
|
||||
if afterCommitID == "" {
|
||||
afterCommitID, err = gitRepo.GetRefCommitID(issue.PullRequest.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetRefCommitID[%s]: %w", issue.PullRequest.GetGitHeadRefName(), err)
|
||||
}
|
||||
afterCommitID = headCommitID
|
||||
} else if !slices.Contains(prCommitIDs, afterCommitID) { // afterCommitID must be one of the pull request commits
|
||||
return nil, fmt.Errorf("afterCommitID[%s] is not a valid pull request commit", afterCommitID)
|
||||
}
|
||||
@ -520,7 +522,7 @@ func ReCalculateLineNumber(hunks []*git.HunkInfo, leftLine int64) int64 {
|
||||
}
|
||||
|
||||
// FetchCodeCommentsByLine fetches the code comments for a given commit, treePath and line number of a pull request.
|
||||
func FetchCodeCommentsByLine(ctx context.Context, repo *repo_model.Repository, issueID int64, currentUser *user_model.User, startCommitID, endCommitID, treePath string, line int64, showOutdatedComments bool) (issues_model.CommentList, error) {
|
||||
func FetchCodeCommentsByLine(ctx context.Context, gitRepo *git.Repository, repo *repo_model.Repository, issueID int64, currentUser *user_model.User, startCommitID, endCommitID, treePath string, line int64, showOutdatedComments bool) (issues_model.CommentList, error) {
|
||||
opts := issues_model.FindCommentsOptions{
|
||||
Type: issues_model.CommentTypeCode,
|
||||
IssueID: issueID,
|
||||
@ -538,7 +540,24 @@ func FetchCodeCommentsByLine(ctx context.Context, repo *repo_model.Repository, i
|
||||
n := 0
|
||||
hunksCache := make(map[string][]*git.HunkInfo)
|
||||
for _, comment := range comments {
|
||||
if comment.CommitSHA == endCommitID {
|
||||
// Code comment should always have a commit SHA, if not, we need to set it based on the line number
|
||||
if comment.CommitSHA == "" {
|
||||
if comment.Line > 0 {
|
||||
comment.CommitSHA = endCommitID
|
||||
} else if comment.Line < 0 {
|
||||
comment.CommitSHA = startCommitID
|
||||
} else {
|
||||
// If the comment has no line number, we cannot display it in the diff view
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
dstCommitID := startCommitID
|
||||
if comment.Line > 0 {
|
||||
dstCommitID = endCommitID
|
||||
}
|
||||
|
||||
if comment.CommitSHA == dstCommitID {
|
||||
if comment.Line == line {
|
||||
comments[n] = comment
|
||||
n++
|
||||
@ -547,18 +566,27 @@ func FetchCodeCommentsByLine(ctx context.Context, repo *repo_model.Repository, i
|
||||
}
|
||||
|
||||
// If the comment is not for the current commit, we need to recalculate the line number
|
||||
hunks, ok := hunksCache[comment.CommitSHA]
|
||||
hunks, ok := hunksCache[comment.CommitSHA+".."+dstCommitID]
|
||||
if !ok {
|
||||
hunks, err = git.GetAffectedHunksForTwoCommitsSpecialFile(ctx, repo.RepoPath(), comment.CommitSHA, endCommitID, treePath)
|
||||
hunks, err = git.GetAffectedHunksForTwoCommitsSpecialFile(ctx, repo.RepoPath(), comment.CommitSHA, dstCommitID, treePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetAffectedHunksForTwoCommitsSpecialFile[%s, %s, %s]: %w", repo.FullName(), comment.CommitSHA, endCommitID, err)
|
||||
return nil, fmt.Errorf("GetAffectedHunksForTwoCommitsSpecialFile[%s, %s, %s]: %w", repo.FullName(), comment.CommitSHA, dstCommitID, err)
|
||||
}
|
||||
hunksCache[comment.CommitSHA] = hunks
|
||||
hunksCache[comment.CommitSHA+".."+dstCommitID] = hunks
|
||||
}
|
||||
|
||||
comment.Line = ReCalculateLineNumber(hunks, comment.Line)
|
||||
comments[n] = comment
|
||||
n++
|
||||
if comment.Line != 0 {
|
||||
dstCommit, err := gitRepo.GetCommit(dstCommitID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetCommit[%s]: %w", dstCommitID, err)
|
||||
}
|
||||
// If the comment is not the first one or the comment created before the current commit
|
||||
if n > 0 || comment.CreatedUnix.AsTime().Before(dstCommit.Committer.When) {
|
||||
comments[n] = comment
|
||||
n++
|
||||
}
|
||||
}
|
||||
}
|
||||
return comments[:n], nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user