mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-30 22:11:07 +00:00 
			
		
		
		
	- `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>
		
			
				
	
	
		
			62 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			62 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2025 The Forgejo Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: GPL-3.0-or-later
 | |
| 
 | |
| package pull
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"testing"
 | |
| 
 | |
| 	issues_model "forgejo.org/models/issues"
 | |
| 	"forgejo.org/models/unittest"
 | |
| 	"forgejo.org/modules/setting"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| func TestLoadHeadRevision(t *testing.T) {
 | |
| 	require.NoError(t, unittest.PrepareTestDatabase())
 | |
| 
 | |
| 	t.Run("AGit", func(t *testing.T) {
 | |
| 		t.Run("New", func(t *testing.T) {
 | |
| 			ctx := &testPatchContext{}
 | |
| 			require.NoError(t, ctx.LoadHeadRevision(t.Context(), &issues_model.PullRequest{Flow: issues_model.PullRequestFlowAGit, HeadCommitID: "Commit!"}))
 | |
| 
 | |
| 			assert.Empty(t, ctx.env)
 | |
| 			assert.Equal(t, "Commit!", ctx.headRev)
 | |
| 			assert.True(t, ctx.headIsCommitID)
 | |
| 		})
 | |
| 		t.Run("Existing", func(t *testing.T) {
 | |
| 			ctx := &testPatchContext{}
 | |
| 			require.NoError(t, ctx.LoadHeadRevision(t.Context(), &issues_model.PullRequest{Flow: issues_model.PullRequestFlowAGit, Index: 371}))
 | |
| 
 | |
| 			assert.Empty(t, ctx.env)
 | |
| 			assert.Equal(t, "refs/pull/371/head", ctx.headRev)
 | |
| 			assert.False(t, ctx.headIsCommitID)
 | |
| 		})
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Same repository", func(t *testing.T) {
 | |
| 		ctx := &testPatchContext{}
 | |
| 		require.NoError(t, ctx.LoadHeadRevision(t.Context(), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})))
 | |
| 
 | |
| 		assert.Empty(t, ctx.env)
 | |
| 		assert.Equal(t, "refs/heads/branch1", ctx.headRev)
 | |
| 		assert.False(t, ctx.headIsCommitID)
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Across repository", func(t *testing.T) {
 | |
| 		pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3})
 | |
| 		require.NoError(t, pr.LoadHeadRepo(t.Context()))
 | |
| 
 | |
| 		ctx := &testPatchContext{}
 | |
| 		require.NoError(t, ctx.LoadHeadRevision(t.Context(), pr))
 | |
| 
 | |
| 		if assert.NotEmpty(t, ctx.env) {
 | |
| 			assert.Equal(t, fmt.Sprintf("GIT_ALTERNATE_OBJECT_DIRECTORIES=%s/user13/repo11.git/objects", setting.RepoRootPath), ctx.env[len(ctx.env)-1])
 | |
| 		}
 | |
| 		assert.Equal(t, "0abcb056019adb8336cf9db3ad9d9cf80cd4b141", ctx.headRev)
 | |
| 		assert.True(t, ctx.headIsCommitID)
 | |
| 	})
 | |
| }
 |