mirror of
https://codeberg.org/davrot/forgejo.git
synced 2025-05-30 18:00:02 +02:00
feat: improved performances when checking for conflicts on pull requests (#7727)
- `testPatch` is a function that is called to test a pull request and determine the state of the pull request. Checking for merge conflicts, check if the diff is empty and if the pull request modifies any protected files. - The checking for merge conflict and if the diff is empty used git commands that relied on a working tree to correctly functions. Forgejo store repositories in a bare format which do not contain a working tree. This means that a temporary copy was created every time a pull request had to be re-checked and for large repositories involving quite some I/O interaction. - This patch adjusts those codepaths to instead use newer Git plumbing commands that work without requiring a work tree and can thus be used directly on the bare repository. The merge conflict is now done via [`git-merge-tree(1)`](https://git-scm.com/docs/git-merge-tree/) and checking if the diff is empty is done via [`git-diff-tree(1)`](https://git-scm.com/docs/git-diff-tree). - If the function is called to test a patch where the head and base repository are not the same, then [Git alternate](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefalternateobjectdatabaseaalternateobjectdatabase) is used to make the head commit available in the base repository, this done on a per git command basis via the `GIT_ALTERNATE_OBJECT_DIRECTORIES` environment. - As far as I can understand the documentation and the existing code, there's no edge case that the new code cannot handle. It also results in a cleaner codepath, as the existing code did a lot of checking and merging in a more traditional approach that required a lot of (parsing) code, while the new code offloads this to git and has a trivial parser of the output. - Resolves forgejo/forgejo#7701 - Added exhaustive integration testing. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7727 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Otto <otto@codeberg.org> Co-authored-by: Gusted <postmaster@gusted.xyz> Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
parent
2ab5b585f6
commit
7c150be23d
13 changed files with 645 additions and 156 deletions
|
@ -46,22 +46,15 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *iss
|
|||
return user_model.ErrBlockedByUser
|
||||
}
|
||||
|
||||
prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
|
||||
testPatchCtx, err := testPatch(ctx, pr)
|
||||
defer testPatchCtx.close()
|
||||
if err != nil {
|
||||
if !git_model.IsErrBranchNotExist(err) {
|
||||
log.Error("CreateTemporaryRepoForPR %-v: %v", pr, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
if err := testPatch(ctx, prCtx, pr); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("testPatch: %w", err)
|
||||
}
|
||||
|
||||
divergence, err := git.GetDivergingCommits(ctx, prCtx.tmpBasePath, baseBranch, trackingBranch)
|
||||
divergence, err := git.GetDivergingCommits(ctx, testPatchCtx.gitRepo.Path, testPatchCtx.baseRev, testPatchCtx.headRev, testPatchCtx.env)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("GetDivergingCommits: %w", err)
|
||||
}
|
||||
pr.CommitsAhead = divergence.Ahead
|
||||
pr.CommitsBehind = divergence.Behind
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue