Compare commits

..

No commits in common. "a9ba7379fe97fd8a1157ed076b268a3b4f2454b2" and "9f5e44bf5051d1bfd4b848378696b03cb635f525" have entirely different histories.

3 changed files with 51 additions and 60 deletions

View File

@ -96,7 +96,6 @@ func (ns *notificationService) NotifyIssueChangeStatus(doer *user_model.User, is
_ = ns.issueQueue.Push(issueNotificationOpts{ _ = ns.issueQueue.Push(issueNotificationOpts{
IssueID: issue.ID, IssueID: issue.ID,
NotificationAuthorID: doer.ID, NotificationAuthorID: doer.ID,
CommentID: actionComment.ID,
}) })
} }

View File

@ -5,7 +5,6 @@
package util package util
import ( import (
"errors"
"io" "io"
) )
@ -19,24 +18,3 @@ func ReadAtMost(r io.Reader, buf []byte) (n int, err error) {
} }
return n, err return n, err
} }
// ErrNotEmpty is an error reported when there is a non-empty reader
var ErrNotEmpty = errors.New("not-empty")
// IsEmptyReader reads a reader and ensures it is empty
func IsEmptyReader(r io.Reader) (err error) {
var buf [1]byte
for {
n, err := r.Read(buf[:])
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if n > 0 {
return ErrNotEmpty
}
}
}

View File

@ -5,12 +5,14 @@
package pull package pull
import ( import (
"bufio"
"bytes"
"context" "context"
"fmt" "fmt"
"io" "io"
"os"
"regexp" "regexp"
"strings" "strings"
"time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -28,7 +30,6 @@ import (
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/util"
issue_service "code.gitea.io/gitea/services/issue" issue_service "code.gitea.io/gitea/services/issue"
) )
@ -351,56 +352,69 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string,
// checkIfPRContentChanged checks if diff to target branch has changed by push // checkIfPRContentChanged checks if diff to target branch has changed by push
// A commit can be considered to leave the PR untouched if the patch/diff with its merge base is unchanged // A commit can be considered to leave the PR untouched if the patch/diff with its merge base is unchanged
func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) { func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) {
tmpBasePath, err := createTemporaryRepo(ctx, pr) if err = pr.LoadHeadRepoCtx(ctx); err != nil {
if err != nil { return false, fmt.Errorf("LoadHeadRepo: %w", err)
log.Error("CreateTemporaryRepo: %v", err) } else if pr.HeadRepo == nil {
return false, err // corrupt data assumed changed
return true, nil
} }
defer func() {
if err := repo_module.RemoveTemporaryPath(tmpBasePath); err != nil {
log.Error("checkIfPRContentChanged: RemoveTemporaryPath: %s", err)
}
}()
tmpRepo, err := git.OpenRepository(ctx, tmpBasePath) if err = pr.LoadBaseRepoCtx(ctx); err != nil {
return false, fmt.Errorf("LoadBaseRepo: %w", err)
}
headGitRepo, err := git.OpenRepository(ctx, pr.HeadRepo.RepoPath())
if err != nil { if err != nil {
return false, fmt.Errorf("OpenRepository: %w", err) return false, fmt.Errorf("OpenRepository: %w", err)
} }
defer tmpRepo.Close() defer headGitRepo.Close()
// Find the merge-base // Add a temporary remote.
_, base, err := tmpRepo.GetMergeBase("", "base", "tracking") tmpRemote := "checkIfPRContentChanged-" + fmt.Sprint(time.Now().UnixNano())
if err = headGitRepo.AddRemote(tmpRemote, pr.BaseRepo.RepoPath(), true); err != nil {
return false, fmt.Errorf("AddRemote: %s/%s-%s: %w", pr.HeadRepo.OwnerName, pr.HeadRepo.Name, tmpRemote, err)
}
defer func() {
if err := headGitRepo.RemoveRemote(tmpRemote); err != nil {
log.Error("checkIfPRContentChanged: RemoveRemote: %s/%s-%s: %v", pr.HeadRepo.OwnerName, pr.HeadRepo.Name, tmpRemote, err)
}
}()
// To synchronize repo and get a base ref
_, base, err := headGitRepo.GetMergeBase(tmpRemote, pr.BaseBranch, pr.HeadBranch)
if err != nil { if err != nil {
return false, fmt.Errorf("GetMergeBase: %w", err) return false, fmt.Errorf("GetMergeBase: %w", err)
} }
cmd := git.NewCommand(ctx, "diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base) diffBefore := &bytes.Buffer{}
stdoutReader, stdoutWriter, err := os.Pipe() diffAfter := &bytes.Buffer{}
if err != nil { if err := headGitRepo.GetDiffFromMergeBase(base, oldCommitID, diffBefore); err != nil {
return false, fmt.Errorf("unable to open pipe for to run diff: %w", err) // If old commit not found, assume changed.
log.Debug("GetDiffFromMergeBase: %v", err)
return true, nil
}
if err := headGitRepo.GetDiffFromMergeBase(base, newCommitID, diffAfter); err != nil {
// New commit should be found
return false, fmt.Errorf("GetDiffFromMergeBase: %w", err)
} }
if err := cmd.Run(&git.RunOpts{ diffBeforeLines := bufio.NewScanner(diffBefore)
Dir: tmpBasePath, diffAfterLines := bufio.NewScanner(diffAfter)
Stdout: stdoutWriter,
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { for diffBeforeLines.Scan() && diffAfterLines.Scan() {
_ = stdoutWriter.Close() if strings.HasPrefix(diffBeforeLines.Text(), "index") && strings.HasPrefix(diffAfterLines.Text(), "index") {
defer func() { // file hashes can change without the diff changing
_ = stdoutReader.Close() continue
}() } else if strings.HasPrefix(diffBeforeLines.Text(), "@@") && strings.HasPrefix(diffAfterLines.Text(), "@@") {
return util.IsEmptyReader(stdoutReader) // the location of the difference may change
}, continue
}); err != nil { } else if !bytes.Equal(diffBeforeLines.Bytes(), diffAfterLines.Bytes()) {
if err == util.ErrNotEmpty {
return true, nil return true, nil
} }
}
log.Error("Unable to run diff on %s %s %s in tempRepo for PR[%d]%s/%s...%s/%s: Error: %v", if diffBeforeLines.Scan() || diffAfterLines.Scan() {
newCommitID, oldCommitID, base, // Diffs not of equal length
pr.ID, pr.BaseRepo.FullName(), pr.BaseBranch, pr.HeadRepo.FullName(), pr.HeadBranch, return true, nil
err)
return false, fmt.Errorf("Unable to run git diff --name-only -z %s %s %s: %w", newCommitID, oldCommitID, base, err)
} }
return false, nil return false, nil