Use merge tree to detect conflicts when possible (#36400)

In Git 2.38, the `merge-tree` command introduced the `--write-tree`
option, which works directly on bare repositories. In Git 2.40, a new parameter `--merge-base` introduced so we require Git 2.40 to use the merge tree feature.

This option produces the merged tree object ID, allowing us to perform
diffs between commits without creating a temporary repository. By
avoiding the overhead of setting up and tearing down temporary repos,
this approach delivers a notable performance improvement.

It also fixes a possible situation that conflict files might be empty
but it's a conflict status according to
https://git-scm.com/docs/git-merge-tree#_mistakes_to_avoid

Replace #35542

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Lunny Xiao
2026-01-27 11:57:20 -08:00
committed by GitHub
parent 125257eacf
commit 1463426a27
29 changed files with 607 additions and 126 deletions
+2 -2
View File
@@ -34,7 +34,7 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
WithDir(repo.Path).
WithPipelineFunc(func(ctx gitcmd.Context) error {
err := readAndVerifyCommitsFromShaReader(stdoutReader, repo, env)
return ctx.CancelWithCause(err)
return ctx.CancelPipeline(err)
}).
Run(repo.Ctx)
if err != nil && !isErrUnverifiedCommit(err) {
@@ -70,7 +70,7 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
}
verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
if !verification.Verified {
return ctx.CancelWithCause(&errUnverifiedCommit{commit.ID.String()})
return ctx.CancelPipeline(&errUnverifiedCommit{commit.ID.String()})
}
return nil
}).