mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 02:46:04 +01:00 
			
		
		
		
	Refactor getpatch/getdiff functions and remove unnecessary fallback (#32817)
Extract from #32786 `git diff a..b` is equal to `git diff a b` which is different from `git diff a...b`. For pull request, we should always --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		| @@ -233,72 +233,34 @@ func parseDiffStat(stdout string) (numFiles, totalAdditions, totalDeletions int, | ||||
| 	return numFiles, totalAdditions, totalDeletions, err | ||||
| } | ||||
|  | ||||
| // GetDiffOrPatch generates either diff or formatted patch data between given revisions | ||||
| func (repo *Repository) GetDiffOrPatch(base, head string, w io.Writer, patch, binary bool) error { | ||||
| 	if patch { | ||||
| 		return repo.GetPatch(base, head, w) | ||||
| 	} | ||||
| 	if binary { | ||||
| 		return repo.GetDiffBinary(base, head, w) | ||||
| 	} | ||||
| 	return repo.GetDiff(base, head, w) | ||||
| } | ||||
|  | ||||
| // GetDiff generates and returns patch data between given revisions, optimized for human readability | ||||
| func (repo *Repository) GetDiff(base, head string, w io.Writer) error { | ||||
| func (repo *Repository) GetDiff(compareArg string, w io.Writer) error { | ||||
| 	stderr := new(bytes.Buffer) | ||||
| 	err := NewCommand(repo.Ctx, "diff", "-p").AddDynamicArguments(base + "..." + head). | ||||
| 	return NewCommand(repo.Ctx, "diff", "-p").AddDynamicArguments(compareArg). | ||||
| 		Run(&RunOpts{ | ||||
| 			Dir:    repo.Path, | ||||
| 			Stdout: w, | ||||
| 			Stderr: stderr, | ||||
| 		}) | ||||
| 	if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) { | ||||
| 		return NewCommand(repo.Ctx, "diff", "-p").AddDynamicArguments(base, head). | ||||
| 			Run(&RunOpts{ | ||||
| 				Dir:    repo.Path, | ||||
| 				Stdout: w, | ||||
| 			}) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // GetDiffBinary generates and returns patch data between given revisions, including binary diffs. | ||||
| func (repo *Repository) GetDiffBinary(base, head string, w io.Writer) error { | ||||
| 	stderr := new(bytes.Buffer) | ||||
| 	err := NewCommand(repo.Ctx, "diff", "-p", "--binary", "--histogram").AddDynamicArguments(base + "..." + head). | ||||
| 		Run(&RunOpts{ | ||||
| 			Dir:    repo.Path, | ||||
| 			Stdout: w, | ||||
| 			Stderr: stderr, | ||||
| 		}) | ||||
| 	if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) { | ||||
| 		return NewCommand(repo.Ctx, "diff", "-p", "--binary", "--histogram").AddDynamicArguments(base, head). | ||||
| 			Run(&RunOpts{ | ||||
| func (repo *Repository) GetDiffBinary(compareArg string, w io.Writer) error { | ||||
| 	return NewCommand(repo.Ctx, "diff", "-p", "--binary", "--histogram").AddDynamicArguments(compareArg).Run(&RunOpts{ | ||||
| 		Dir:    repo.Path, | ||||
| 		Stdout: w, | ||||
| 	}) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply` | ||||
| func (repo *Repository) GetPatch(base, head string, w io.Writer) error { | ||||
| func (repo *Repository) GetPatch(compareArg string, w io.Writer) error { | ||||
| 	stderr := new(bytes.Buffer) | ||||
| 	err := NewCommand(repo.Ctx, "format-patch", "--binary", "--stdout").AddDynamicArguments(base + "..." + head). | ||||
| 	return NewCommand(repo.Ctx, "format-patch", "--binary", "--stdout").AddDynamicArguments(compareArg). | ||||
| 		Run(&RunOpts{ | ||||
| 			Dir:    repo.Path, | ||||
| 			Stdout: w, | ||||
| 			Stderr: stderr, | ||||
| 		}) | ||||
| 	if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) { | ||||
| 		return NewCommand(repo.Ctx, "format-patch", "--binary", "--stdout").AddDynamicArguments(base, head). | ||||
| 			Run(&RunOpts{ | ||||
| 				Dir:    repo.Path, | ||||
| 				Stdout: w, | ||||
| 			}) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // GetFilesChangedBetween returns a list of all files that have been changed between the given commits | ||||
| @@ -329,21 +291,6 @@ func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, err | ||||
| 	return split, err | ||||
| } | ||||
|  | ||||
| // GetDiffFromMergeBase generates and return patch data from merge base to head | ||||
| func (repo *Repository) GetDiffFromMergeBase(base, head string, w io.Writer) error { | ||||
| 	stderr := new(bytes.Buffer) | ||||
| 	err := NewCommand(repo.Ctx, "diff", "-p", "--binary").AddDynamicArguments(base + "..." + head). | ||||
| 		Run(&RunOpts{ | ||||
| 			Dir:    repo.Path, | ||||
| 			Stdout: w, | ||||
| 			Stderr: stderr, | ||||
| 		}) | ||||
| 	if err != nil && bytes.Contains(stderr.Bytes(), []byte("no merge base")) { | ||||
| 		return repo.GetDiffBinary(base, head, w) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // ReadPatchCommit will check if a diff patch exists and return stats | ||||
| func (repo *Repository) ReadPatchCommit(prID int64) (commitSHA string, err error) { | ||||
| 	// Migrated repositories download patches to "pulls" location | ||||
|   | ||||
| @@ -28,7 +28,7 @@ func TestGetFormatPatch(t *testing.T) { | ||||
| 	defer repo.Close() | ||||
|  | ||||
| 	rd := &bytes.Buffer{} | ||||
| 	err = repo.GetPatch("8d92fc95^", "8d92fc95", rd) | ||||
| 	err = repo.GetPatch("8d92fc95^...8d92fc95", rd) | ||||
| 	if err != nil { | ||||
| 		assert.NoError(t, err) | ||||
| 		return | ||||
|   | ||||
| @@ -41,9 +41,19 @@ func DownloadDiffOrPatch(ctx context.Context, pr *issues_model.PullRequest, w io | ||||
| 	} | ||||
| 	defer closer.Close() | ||||
|  | ||||
| 	if err := gitRepo.GetDiffOrPatch(pr.MergeBase, pr.GetGitRefName(), w, patch, binary); err != nil { | ||||
| 		log.Error("Unable to get patch file from %s to %s in %s Error: %v", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err) | ||||
| 		return fmt.Errorf("Unable to get patch file from %s to %s in %s Error: %w", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err) | ||||
| 	compareArg := pr.MergeBase + "..." + pr.GetGitRefName() | ||||
| 	switch { | ||||
| 	case patch: | ||||
| 		err = gitRepo.GetPatch(compareArg, w) | ||||
| 	case binary: | ||||
| 		err = gitRepo.GetDiffBinary(compareArg, w) | ||||
| 	default: | ||||
| 		err = gitRepo.GetDiff(compareArg, w) | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		log.Error("unable to get patch file from %s to %s in %s Error: %v", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err) | ||||
| 		return fmt.Errorf("unable to get patch file from %s to %s in %s Error: %w", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -354,7 +364,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * | ||||
| 		_ = util.Remove(tmpPatchFile.Name()) | ||||
| 	}() | ||||
|  | ||||
| 	if err := gitRepo.GetDiffBinary(pr.MergeBase, "tracking", tmpPatchFile); err != nil { | ||||
| 	if err := gitRepo.GetDiffBinary(pr.MergeBase+"...tracking", tmpPatchFile); err != nil { | ||||
| 		tmpPatchFile.Close() | ||||
| 		log.Error("Unable to get patch file from %s to %s in %s Error: %v", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err) | ||||
| 		return false, fmt.Errorf("unable to get patch file from %s to %s in %s Error: %w", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.FullName(), err) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user