|
4 | 4 | package pull
|
5 | 5 |
|
6 | 6 | import (
|
7 |
| - "bufio" |
8 |
| - "bytes" |
9 | 7 | "context"
|
10 | 8 | "fmt"
|
11 | 9 | "io"
|
12 | 10 | "regexp"
|
13 | 11 | "strings"
|
14 |
| - "time" |
15 | 12 |
|
16 | 13 | "code.gitea.io/gitea/models"
|
17 | 14 | "code.gitea.io/gitea/models/db"
|
@@ -351,72 +348,47 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string,
|
351 | 348 | // checkIfPRContentChanged checks if diff to target branch has changed by push
|
352 | 349 | // A commit can be considered to leave the PR untouched if the patch/diff with its merge base is unchanged
|
353 | 350 | func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) {
|
354 |
| - if err = pr.LoadHeadRepo(ctx); err != nil { |
355 |
| - return false, fmt.Errorf("LoadHeadRepo: %w", err) |
356 |
| - } else if pr.HeadRepo == nil { |
357 |
| - // corrupt data assumed changed |
358 |
| - return true, nil |
359 |
| - } |
360 |
| - |
361 |
| - if err = pr.LoadBaseRepo(ctx); err != nil { |
362 |
| - return false, fmt.Errorf("LoadBaseRepo: %w", err) |
363 |
| - } |
364 |
| - |
365 |
| - headGitRepo, err := git.OpenRepository(ctx, pr.HeadRepo.RepoPath()) |
| 351 | + tmpBasePath, err := createTemporaryRepo(ctx, pr) |
366 | 352 | if err != nil {
|
367 |
| - return false, fmt.Errorf("OpenRepository: %w", err) |
368 |
| - } |
369 |
| - defer headGitRepo.Close() |
370 |
| - |
371 |
| - // Add a temporary remote. |
372 |
| - tmpRemote := "checkIfPRContentChanged-" + fmt.Sprint(time.Now().UnixNano()) |
373 |
| - if err = headGitRepo.AddRemote(tmpRemote, pr.BaseRepo.RepoPath(), true); err != nil { |
374 |
| - return false, fmt.Errorf("AddRemote: %s/%s-%s: %w", pr.HeadRepo.OwnerName, pr.HeadRepo.Name, tmpRemote, err) |
| 353 | + log.Error("CreateTemporaryPath: %v", err) |
| 354 | + return false, err |
375 | 355 | }
|
376 | 356 | defer func() {
|
377 |
| - if err := headGitRepo.RemoveRemote(tmpRemote); err != nil { |
378 |
| - log.Error("checkIfPRContentChanged: RemoveRemote: %s/%s-%s: %v", pr.HeadRepo.OwnerName, pr.HeadRepo.Name, tmpRemote, err) |
| 357 | + if err := repo_module.RemoveTemporaryPath(tmpBasePath); err != nil { |
| 358 | + log.Error("checkIfPRContentChanged: RemoveTemporaryPath: %s", err) |
379 | 359 | }
|
380 | 360 | }()
|
381 |
| - // To synchronize repo and get a base ref |
382 |
| - _, base, err := headGitRepo.GetMergeBase(tmpRemote, pr.BaseBranch, pr.HeadBranch) |
| 361 | + |
| 362 | + tmpRepo, err := git.OpenRepository(ctx, tmpBasePath) |
383 | 363 | if err != nil {
|
384 |
| - return false, fmt.Errorf("GetMergeBase: %w", err) |
| 364 | + return false, fmt.Errorf("OpenRepository: %w", err) |
385 | 365 | }
|
| 366 | + defer tmpRepo.Close() |
386 | 367 |
|
387 |
| - diffBefore := &bytes.Buffer{} |
388 |
| - diffAfter := &bytes.Buffer{} |
389 |
| - if err := headGitRepo.GetDiffFromMergeBase(base, oldCommitID, diffBefore); err != nil { |
390 |
| - // If old commit not found, assume changed. |
391 |
| - log.Debug("GetDiffFromMergeBase: %v", err) |
392 |
| - return true, nil |
393 |
| - } |
394 |
| - if err := headGitRepo.GetDiffFromMergeBase(base, newCommitID, diffAfter); err != nil { |
395 |
| - // New commit should be found |
396 |
| - return false, fmt.Errorf("GetDiffFromMergeBase: %w", err) |
| 368 | + // Find the merge-base |
| 369 | + _, base, err := tmpRepo.GetMergeBase("", "base", "tracking") |
| 370 | + if err != nil { |
| 371 | + return false, fmt.Errorf("GetMergeBase: %w", err) |
397 | 372 | }
|
398 | 373 |
|
399 |
| - diffBeforeLines := bufio.NewScanner(diffBefore) |
400 |
| - diffAfterLines := bufio.NewScanner(diffAfter) |
401 |
| - |
402 |
| - for diffBeforeLines.Scan() && diffAfterLines.Scan() { |
403 |
| - if strings.HasPrefix(diffBeforeLines.Text(), "index") && strings.HasPrefix(diffAfterLines.Text(), "index") { |
404 |
| - // file hashes can change without the diff changing |
405 |
| - continue |
406 |
| - } else if strings.HasPrefix(diffBeforeLines.Text(), "@@") && strings.HasPrefix(diffAfterLines.Text(), "@@") { |
407 |
| - // the location of the difference may change |
408 |
| - continue |
409 |
| - } else if !bytes.Equal(diffBeforeLines.Bytes(), diffAfterLines.Bytes()) { |
410 |
| - return true, nil |
411 |
| - } |
412 |
| - } |
| 374 | + cmd := git.NewCommand(ctx, "diff", "--name-only", "-1").AddDynamicArguments(newCommitID, oldCommitID, base) |
| 375 | + stdout, stderr, err := cmd.RunStdString(&git.RunOpts{ |
| 376 | + Dir: tmpBasePath, |
| 377 | + }) |
| 378 | + if err != nil { |
| 379 | + log.Error("Unable to run diff on %s %s %s in tempRepo for PR[%d]%s/%s...%s/%s: stdout %s stderr %s Error: %v", |
| 380 | + newCommitID, oldCommitID, base, |
| 381 | + pr.ID, pr.BaseRepo.FullName(), pr.BaseBranch, pr.HeadRepo.FullName(), pr.HeadBranch, |
| 382 | + stdout, stderr, err) |
413 | 383 |
|
414 |
| - if diffBeforeLines.Scan() || diffAfterLines.Scan() { |
415 |
| - // Diffs not of equal length |
416 |
| - return true, nil |
| 384 | + // New commit should be found |
| 385 | + return false, fmt.Errorf("Unable to run diff on %s %s %s in tempRepo for PR[%d]%s/%s...%s/%s: %w", |
| 386 | + newCommitID, oldCommitID, base, |
| 387 | + pr.ID, pr.BaseRepo.FullName(), pr.BaseBranch, pr.HeadRepo.FullName(), pr.HeadBranch, |
| 388 | + err) |
417 | 389 | }
|
418 | 390 |
|
419 |
| - return false, nil |
| 391 | + return strings.TrimSpace(stdout) == "", nil |
420 | 392 | }
|
421 | 393 |
|
422 | 394 | // PushToBaseRepo pushes commits from branches of head repository to
|
|
0 commit comments