Files
Gitea/modules/git/commit_info_test.go
T
silverwind ad38b60983 refactor!: remove go-git backend (#39487)
Removes the go-git backend so every build uses the git CLI backend. Its
Windows performance advantage is gone, it lacks SHA-256 support, and it
breaks repositories on Windows.

The performance changes moved to
https://github.com/go-gitea/gitea/pull/39526.

Fixes https://github.com/go-gitea/gitea/issues/38359
Fixes https://github.com/go-gitea/gitea/issues/34694

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-03 10:04:24 +00:00

207 lines
6.9 KiB
Go

// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
import (
"context"
"path/filepath"
"testing"
"time"
"gitea.dev/modules/git/gitrepo"
"gitea.dev/modules/test"
"gitea.dev/modules/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func cloneRepo(tb testing.TB, url string) (string, error) {
repoDir := tb.TempDir()
if err := Clone(tb.Context(), url, repoDir, CloneRepoOptions{
Mirror: false,
Bare: false,
Quiet: true,
Timeout: 5 * time.Minute,
}); err != nil {
return "", err
}
return repoDir, nil
}
func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
type expectedEntryInfo struct {
CommitID string
Size int64
}
// these test case are specific to the repo1 test repo
testCases := []struct {
CommitID string
Path string
ExpectedIDs map[string]expectedEntryInfo
ExpectedTreeCommit string
}{
{"8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", "", map[string]expectedEntryInfo{
"file1.txt": {
CommitID: "95bb4d39648ee7e325106df01a621c530863a653",
Size: 6,
},
"file2.txt": {
CommitID: "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
Size: 6,
},
}, "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2"},
{"2839944139e0de9737a044f78b0e4b40d989a9e3", "", map[string]expectedEntryInfo{
"file1.txt": {
CommitID: "2839944139e0de9737a044f78b0e4b40d989a9e3",
Size: 15,
},
"branch1.txt": {
CommitID: "9c9aef8dd84e02bc7ec12641deb4c930a7c30185",
Size: 8,
},
}, "2839944139e0de9737a044f78b0e4b40d989a9e3"},
{"5c80b0245c1c6f8343fa418ec374b13b5d4ee658", "branch2", map[string]expectedEntryInfo{
"branch2.txt": {
CommitID: "5c80b0245c1c6f8343fa418ec374b13b5d4ee658",
Size: 8,
},
}, "5c80b0245c1c6f8343fa418ec374b13b5d4ee658"},
{"feaf4ba6bc635fec442f46ddd4512416ec43c2c2", "", map[string]expectedEntryInfo{
"file1.txt": {
CommitID: "95bb4d39648ee7e325106df01a621c530863a653",
Size: 6,
},
"file2.txt": {
CommitID: "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
Size: 6,
},
"foo": {
CommitID: "37991dec2c8e592043f47155ce4808d4580f9123",
Size: 0,
},
}, "feaf4ba6bc635fec442f46ddd4512416ec43c2c2"},
}
for _, testCase := range testCases {
commit, err := repo1.GetCommit(t.Context(), testCase.CommitID)
if err != nil {
assert.NoError(t, err, "Unable to get commit: %s from testcase due to error: %v", testCase.CommitID, err)
// no point trying to do anything else for this test.
continue
}
assert.NotNil(t, commit)
assert.NotNil(t, commit.TreeID)
tree, err := commit.SubTree(t.Context(), repo1, testCase.Path)
if err != nil {
assert.NoError(t, err, "Unable to get subtree: %s of commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
// no point trying to do anything else for this test.
continue
}
assert.NotNil(t, tree, "tree is nil for testCase CommitID %s in Path %s", testCase.CommitID, testCase.Path)
entries, err := tree.ListEntries(t.Context(), repo1)
if err != nil {
assert.NoError(t, err, "Unable to get entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
// no point trying to do anything else for this test.
continue
}
commitsInfo, treeCommit, err := entries.GetCommitsInfo(t.Context(), time.Second, "/any/repo-link", repo1, commit, testCase.Path)
assert.NoError(t, err, "Unable to get commit information for entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
if err != nil {
t.FailNow()
}
assert.Equal(t, testCase.ExpectedTreeCommit, treeCommit.ID.String())
assert.Len(t, commitsInfo, len(testCase.ExpectedIDs))
for _, commitInfo := range commitsInfo {
entry := commitInfo.Entry
commit := commitInfo.Commit
expectedInfo, ok := testCase.ExpectedIDs[entry.Name()]
if !assert.True(t, ok) {
continue
}
assert.Equal(t, expectedInfo.CommitID, commit.ID.String())
assert.Equal(t, expectedInfo.Size, entry.GetSize(t.Context(), repo1), entry.Name())
}
}
}
func TestEntries_GetCommitsInfo(t *testing.T) {
bareRepo1Path, _ := filepath.Abs(filepath.Join(testReposDir, "repo1_bare"))
bareRepo1, err := OpenRepository(t.Context(), gitrepo.RepositoryManaged("repo1_bare", bareRepo1Path))
require.NoError(t, err)
defer bareRepo1.Close()
testGetCommitsInfo(t, bareRepo1)
clonedPath, err := cloneRepo(t, bareRepo1Path)
if err != nil {
assert.NoError(t, err)
}
clonedRepo1, err := OpenRepository(t.Context(), gitrepo.RepositoryManaged("repo1_bare-clone", clonedPath))
if err != nil {
assert.NoError(t, err)
}
defer clonedRepo1.Close()
testGetCommitsInfo(t, clonedRepo1)
t.Run("NonExistingSubmoduleAsNil", func(t *testing.T) {
commit, err := bareRepo1.GetCommit(t.Context(), "HEAD")
require.NoError(t, err)
treeEntry, err := commit.GetTreeEntryByPath(t.Context(), bareRepo1, "file1.txt")
require.NoError(t, err)
cisf, err := GetCommitInfoSubmoduleFile(t.Context(), "/any/repo-link", "file1.txt", bareRepo1, commit, treeEntry.ID)
require.NoError(t, err)
assert.Equal(t, &CommitSubmoduleFile{
repoLink: "/any/repo-link",
fullPath: "file1.txt",
refURL: "",
refID: "e2129701f1a4d54dc44f03c93bca0a2aec7c5449",
}, cisf)
// since there is no refURL, it means that the submodule info doesn't exist, so it won't have a web link
assert.Nil(t, cisf.SubmoduleWebLinkTree(t.Context()))
})
}
func TestEntries_GetCommitsInfo_ContextErr(t *testing.T) {
repoPath, _ := filepath.Abs(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepository(t.Context(), gitrepo.RepositoryManaged("dummy", repoPath))
require.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit(t.Context(), "feaf4ba6bc635fec442f46ddd4512416ec43c2c2")
require.NoError(t, err)
entries, err := commit.Tree().ListEntries(t.Context(), repo)
require.NoError(t, err)
countCommitInfosCommit := func(infos []CommitInfo) (nilCommits, nonNilCommits int) {
for _, info := range infos {
nilCommits += util.Iif(info.Commit == nil, 1, 0)
nonNilCommits += util.Iif(info.Commit != nil, 1, 0)
}
return nilCommits, nonNilCommits
}
ctx, cancel := context.WithCancel(t.Context())
defer test.MockVariableValue(&walkGitLogDebugBeforeNext)()
walkGitLogDebugBeforeNext = cancel
commitInfos, _, err := entries.GetCommitsInfo(ctx, time.Second, "/any/repo-link", repo, commit, "")
assert.NoError(t, err)
nilCommits, nonNilCommits := countCommitInfosCommit(commitInfos)
assert.Equal(t, 0, nonNilCommits) // no commit info due to canceled (or deadline-exceeded) context
assert.Equal(t, 3, nilCommits)
walkGitLogDebugBeforeNext = nil
commitInfos, _, err = entries.GetCommitsInfo(t.Context(), time.Second, "/any/repo-link", repo, commit, "")
assert.NoError(t, err)
nilCommits, nonNilCommits = countCommitInfosCommit(commitInfos)
assert.Equal(t, 3, nonNilCommits)
assert.Equal(t, 0, nilCommits)
}