1
1
mirror of https://github.com/go-gitea/gitea synced 2025-09-10 10:48:28 +00:00

Remove wrong "git.DefaultContext" (#35364)

This commit is contained in:
wxiaoguang
2025-08-28 00:31:21 +08:00
committed by GitHub
parent e837c998b7
commit 60246730b5
71 changed files with 384 additions and 476 deletions

View File

@@ -141,7 +141,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
}
}()
cmd := NewCommandNoGlobals("blame", "--porcelain")
cmd := NewCommand("blame", "--porcelain")
if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore {
ignoreRevsFileName, ignoreRevsFileCleanup, err = tryCreateBlameIgnoreRevsFile(commit)

View File

@@ -16,7 +16,7 @@ import (
func TestBlob_Data(t *testing.T) {
output := "file2\n"
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
repo, err := OpenRepository(t.Context(), bareRepo1Path)
require.NoError(t, err)
defer repo.Close()
@@ -36,7 +36,7 @@ func TestBlob_Data(t *testing.T) {
func Benchmark_Blob_Data(b *testing.B) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
repo, err := OpenRepository(b.Context(), bareRepo1Path)
if err != nil {
b.Fatal(err)
}

View File

@@ -29,25 +29,19 @@ import (
// In most cases, it shouldn't be used. Use AddXxx function instead
type TrustedCmdArgs []internal.CmdArg
var (
// globalCommandArgs global command args for external package setting
globalCommandArgs TrustedCmdArgs
// defaultCommandExecutionTimeout default command execution timeout duration
defaultCommandExecutionTimeout = 360 * time.Second
)
// defaultCommandExecutionTimeout default command execution timeout duration
var defaultCommandExecutionTimeout = 360 * time.Second
// DefaultLocale is the default LC_ALL to run git commands in.
const DefaultLocale = "C"
// Command represents a command with its subcommands or arguments.
type Command struct {
prog string
args []string
globalArgsLength int
brokenArgs []string
cmd *exec.Cmd // for debug purpose only
configArgs []string
prog string
args []string
brokenArgs []string
cmd *exec.Cmd // for debug purpose only
configArgs []string
}
func logArgSanitize(arg string) string {
@@ -72,10 +66,7 @@ func (c *Command) LogString() string {
}
a := make([]string, 0, len(c.args)+1)
a = append(a, debugQuote(c.prog))
if c.globalArgsLength > 0 {
a = append(a, "...global...")
}
for i := c.globalArgsLength; i < len(c.args); i++ {
for i := 0; i < len(c.args); i++ {
a = append(a, debugQuote(logArgSanitize(c.args[i])))
}
return strings.Join(a, " ")
@@ -91,24 +82,6 @@ func (c *Command) ProcessState() string {
// NewCommand creates and returns a new Git Command based on given command and arguments.
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
func NewCommand(args ...internal.CmdArg) *Command {
// Make an explicit copy of globalCommandArgs, otherwise append might overwrite it
cargs := make([]string, 0, len(globalCommandArgs)+len(args))
for _, arg := range globalCommandArgs {
cargs = append(cargs, string(arg))
}
for _, arg := range args {
cargs = append(cargs, string(arg))
}
return &Command{
prog: GitExecutable,
args: cargs,
globalArgsLength: len(globalCommandArgs),
}
}
// NewCommandNoGlobals creates and returns a new Git Command based on given command and arguments only with the specified args and don't use global command args
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
func NewCommandNoGlobals(args ...internal.CmdArg) *Command {
cargs := make([]string, 0, len(args))
for _, arg := range args {
cargs = append(cargs, string(arg))
@@ -468,19 +441,3 @@ func (c *Command) runStdBytes(ctx context.Context, opts *RunOpts) (stdout, stder
// even if there is no err, there could still be some stderr output
return stdoutBuf.Bytes(), stderr, nil
}
// AllowLFSFiltersArgs return globalCommandArgs with lfs filter, it should only be used for tests
func AllowLFSFiltersArgs() TrustedCmdArgs {
// Now here we should explicitly allow lfs filters to run
filteredLFSGlobalArgs := make(TrustedCmdArgs, len(globalCommandArgs))
j := 0
for _, arg := range globalCommandArgs {
if strings.Contains(string(arg), "lfs") {
j--
} else {
filteredLFSGlobalArgs[j] = arg
j++
}
}
return filteredLFSGlobalArgs[:j]
}

View File

@@ -53,9 +53,9 @@ func TestGitArgument(t *testing.T) {
}
func TestCommandString(t *testing.T) {
cmd := NewCommandNoGlobals("a", "-m msg", "it's a test", `say "hello"`)
cmd := NewCommand("a", "-m msg", "it's a test", `say "hello"`)
assert.Equal(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.LogString())
cmd = NewCommandNoGlobals("url: https://a:b@c/", "/root/dir-a/dir-b")
cmd = NewCommand("url: https://a:b@c/", "/root/dir-a/dir-b")
assert.Equal(t, cmd.prog+` "url: https://sanitized-credential@c/" .../dir-a/dir-b`, cmd.LogString())
}

View File

@@ -86,18 +86,13 @@ func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) {
}
// AddChanges marks local changes to be ready for commit.
func AddChanges(repoPath string, all bool, files ...string) error {
return AddChangesWithArgs(repoPath, globalCommandArgs, all, files...)
}
// AddChangesWithArgs marks local changes to be ready for commit.
func AddChangesWithArgs(repoPath string, globalArgs TrustedCmdArgs, all bool, files ...string) error {
cmd := NewCommandNoGlobals(globalArgs...).AddArguments("add")
func AddChanges(ctx context.Context, repoPath string, all bool, files ...string) error {
cmd := NewCommand().AddArguments("add")
if all {
cmd.AddArguments("--all")
}
cmd.AddDashesAndList(files...)
_, _, err := cmd.RunStdString(DefaultContext, &RunOpts{Dir: repoPath})
_, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath})
return err
}
@@ -110,16 +105,8 @@ type CommitChangesOptions struct {
// CommitChanges commits local changes with given committer, author and message.
// If author is nil, it will be the same as committer.
func CommitChanges(repoPath string, opts CommitChangesOptions) error {
cargs := make(TrustedCmdArgs, len(globalCommandArgs))
copy(cargs, globalCommandArgs)
return CommitChangesWithArgs(repoPath, cargs, opts)
}
// CommitChangesWithArgs commits local changes with given committer, author and message.
// If author is nil, it will be the same as committer.
func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChangesOptions) error {
cmd := NewCommandNoGlobals(args...)
func CommitChanges(ctx context.Context, repoPath string, opts CommitChangesOptions) error {
cmd := NewCommand()
if opts.Committer != nil {
cmd.AddOptionValues("-c", "user.name="+opts.Committer.Name)
cmd.AddOptionValues("-c", "user.email="+opts.Committer.Email)
@@ -134,7 +121,7 @@ func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChan
}
cmd.AddOptionFormat("--message=%s", opts.Message)
_, _, err := cmd.RunStdString(DefaultContext, &RunOpts{Dir: repoPath})
_, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath})
// No stderr but exit status 1 means nothing to commit.
if err != nil && err.Error() == "exit status 1" {
return nil

View File

@@ -18,7 +18,7 @@ const (
func cloneRepo(tb testing.TB, url string) (string, error) {
repoDir := tb.TempDir()
if err := Clone(DefaultContext, url, repoDir, CloneRepoOptions{
if err := Clone(tb.Context(), url, repoDir, CloneRepoOptions{
Mirror: false,
Bare: false,
Quiet: true,
@@ -104,7 +104,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
func TestEntries_GetCommitsInfo(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -114,7 +114,7 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
if err != nil {
assert.NoError(t, err)
}
clonedRepo1, err := openRepositoryWithDefaultContext(clonedPath)
clonedRepo1, err := OpenRepository(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
}
@@ -163,7 +163,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
b.Fatal(err)
}
if repo, err = openRepositoryWithDefaultContext(repoPath); err != nil {
if repo, err = OpenRepository(b.Context(), repoPath); err != nil {
b.Fatal(err)
}
defer repo.Close()

View File

@@ -17,7 +17,7 @@ import (
func TestCommitsCountSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
commitsCount, err := CommitsCount(DefaultContext,
commitsCount, err := CommitsCount(t.Context(),
CommitsCountOptions{
RepoPath: bareRepo1Path,
Revision: []string{"f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc"},
@@ -30,7 +30,7 @@ func TestCommitsCountSha256(t *testing.T) {
func TestCommitsCountWithoutBaseSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
commitsCount, err := CommitsCount(DefaultContext,
commitsCount, err := CommitsCount(t.Context(),
CommitsCountOptions{
RepoPath: bareRepo1Path,
Not: "main",
@@ -44,7 +44,7 @@ func TestCommitsCountWithoutBaseSha256(t *testing.T) {
func TestGetFullCommitIDSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "f004f4")
id, err := GetFullCommitID(t.Context(), bareRepo1Path, "f004f4")
assert.NoError(t, err)
assert.Equal(t, "f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc", id)
}
@@ -52,7 +52,7 @@ func TestGetFullCommitIDSha256(t *testing.T) {
func TestGetFullCommitIDErrorSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "unknown")
id, err := GetFullCommitID(t.Context(), bareRepo1Path, "unknown")
assert.Empty(t, id)
if assert.Error(t, err) {
assert.EqualError(t, err, "object does not exist [id: unknown, rel_path: ]")
@@ -87,7 +87,7 @@ signed commit`
0x94, 0x33, 0xb2, 0xa6, 0x2b, 0x96, 0x4c, 0x17, 0xa4, 0x48, 0x5a, 0xe1, 0x80, 0xf4, 0x5f, 0x59,
0x5d, 0x3e, 0x69, 0xd3, 0x1b, 0x78, 0x60, 0x87, 0x77, 0x5e, 0x28, 0xc6, 0xb6, 0x39, 0x9d, 0xf0,
}
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare_sha256"))
gitRepo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare_sha256"))
assert.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
@@ -130,7 +130,7 @@ signed commit`, commitFromReader.Signature.Payload)
func TestHasPreviousCommitSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
repo, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer repo.Close()
@@ -161,7 +161,7 @@ func TestHasPreviousCommitSha256(t *testing.T) {
func TestGetCommitFileStatusMergesSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo6_merge_sha256")
commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1")
commitFileStatus, err := GetCommitFileStatus(t.Context(), bareRepo1Path, "d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1")
assert.NoError(t, err)
expected := CommitFileStatus{
@@ -186,7 +186,7 @@ func TestGetCommitFileStatusMergesSha256(t *testing.T) {
[]string{},
}
commitFileStatus, err = GetCommitFileStatus(DefaultContext, bareRepo1Path, "da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172")
commitFileStatus, err = GetCommitFileStatus(t.Context(), bareRepo1Path, "da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172")
assert.NoError(t, err)
assert.Equal(t, expected.Added, commitFileStatus.Added)

View File

@@ -16,7 +16,7 @@ import (
func TestCommitsCount(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
commitsCount, err := CommitsCount(DefaultContext,
commitsCount, err := CommitsCount(t.Context(),
CommitsCountOptions{
RepoPath: bareRepo1Path,
Revision: []string{"8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"},
@@ -29,7 +29,7 @@ func TestCommitsCount(t *testing.T) {
func TestCommitsCountWithoutBase(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
commitsCount, err := CommitsCount(DefaultContext,
commitsCount, err := CommitsCount(t.Context(),
CommitsCountOptions{
RepoPath: bareRepo1Path,
Not: "master",
@@ -43,7 +43,7 @@ func TestCommitsCountWithoutBase(t *testing.T) {
func TestGetFullCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "8006ff9a")
id, err := GetFullCommitID(t.Context(), bareRepo1Path, "8006ff9a")
assert.NoError(t, err)
assert.Equal(t, "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0", id)
}
@@ -51,7 +51,7 @@ func TestGetFullCommitID(t *testing.T) {
func TestGetFullCommitIDError(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "unknown")
id, err := GetFullCommitID(t.Context(), bareRepo1Path, "unknown")
assert.Empty(t, id)
if assert.Error(t, err) {
assert.EqualError(t, err, "object does not exist [id: unknown, rel_path: ]")
@@ -83,7 +83,7 @@ gpgsig -----BEGIN PGP SIGNATURE-----
empty commit`
sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2}
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
gitRepo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
assert.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
@@ -147,7 +147,7 @@ gpgsig -----BEGIN PGP SIGNATURE-----
ISO-8859-1`
commitString = strings.ReplaceAll(commitString, "<SPACE>", " ")
sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2}
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
gitRepo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
assert.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
@@ -189,7 +189,7 @@ ISO-8859-1`, commitFromReader.Signature.Payload)
func TestHasPreviousCommit(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
repo, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer repo.Close()
@@ -320,7 +320,7 @@ func TestParseCommitFileStatus(t *testing.T) {
func TestGetCommitFileStatusMerges(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo6_merge")
commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "022f4ce6214973e018f02bf363bf8a2e3691f699")
commitFileStatus, err := GetCommitFileStatus(t.Context(), bareRepo1Path, "022f4ce6214973e018f02bf363bf8a2e3691f699")
assert.NoError(t, err)
expected := CommitFileStatus{

View File

@@ -4,6 +4,7 @@
package git
import (
"context"
"fmt"
"os"
"regexp"
@@ -14,7 +15,7 @@ import (
)
// syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem)
func syncGitConfig() (err error) {
func syncGitConfig(ctx context.Context) (err error) {
if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil {
return fmt.Errorf("unable to prepare git home directory %s, err: %w", HomeDir(), err)
}
@@ -22,7 +23,7 @@ func syncGitConfig() (err error) {
// first, write user's git config options to git config file
// user config options could be overwritten by builtin values later, because if a value is builtin, it must have some special purposes
for k, v := range setting.GitConfig.Options {
if err = configSet(strings.ToLower(k), v); err != nil {
if err = configSet(ctx, strings.ToLower(k), v); err != nil {
return err
}
}
@@ -34,41 +35,41 @@ func syncGitConfig() (err error) {
"user.name": "Gitea",
"user.email": "gitea@fake.local",
} {
if err := configSetNonExist(configKey, defaultValue); err != nil {
if err := configSetNonExist(ctx, configKey, defaultValue); err != nil {
return err
}
}
// Set git some configurations - these must be set to these values for gitea to work correctly
if err := configSet("core.quotePath", "false"); err != nil {
if err := configSet(ctx, "core.quotePath", "false"); err != nil {
return err
}
if DefaultFeatures().CheckVersionAtLeast("2.10") {
if err := configSet("receive.advertisePushOptions", "true"); err != nil {
if err := configSet(ctx, "receive.advertisePushOptions", "true"); err != nil {
return err
}
}
if DefaultFeatures().CheckVersionAtLeast("2.18") {
if err := configSet("core.commitGraph", "true"); err != nil {
if err := configSet(ctx, "core.commitGraph", "true"); err != nil {
return err
}
if err := configSet("gc.writeCommitGraph", "true"); err != nil {
if err := configSet(ctx, "gc.writeCommitGraph", "true"); err != nil {
return err
}
if err := configSet("fetch.writeCommitGraph", "true"); err != nil {
if err := configSet(ctx, "fetch.writeCommitGraph", "true"); err != nil {
return err
}
}
if DefaultFeatures().SupportProcReceive {
// set support for AGit flow
if err := configAddNonExist("receive.procReceiveRefs", "refs/for"); err != nil {
if err := configAddNonExist(ctx, "receive.procReceiveRefs", "refs/for"); err != nil {
return err
}
} else {
if err := configUnsetAll("receive.procReceiveRefs", "refs/for"); err != nil {
if err := configUnsetAll(ctx, "receive.procReceiveRefs", "refs/for"); err != nil {
return err
}
}
@@ -81,18 +82,18 @@ func syncGitConfig() (err error) {
// As Gitea now always use its internal git config file, and access to the git repositories is managed through Gitea,
// it is now safe to set "safe.directory=*" for internal usage only.
// Although this setting is only supported by some new git versions, it is also tolerated by earlier versions
if err := configAddNonExist("safe.directory", "*"); err != nil {
if err := configAddNonExist(ctx, "safe.directory", "*"); err != nil {
return err
}
if runtime.GOOS == "windows" {
if err := configSet("core.longpaths", "true"); err != nil {
if err := configSet(ctx, "core.longpaths", "true"); err != nil {
return err
}
if setting.Git.DisableCoreProtectNTFS {
err = configSet("core.protectNTFS", "false")
err = configSet(ctx, "core.protectNTFS", "false")
} else {
err = configUnsetAll("core.protectNTFS", "false")
err = configUnsetAll(ctx, "core.protectNTFS", "false")
}
if err != nil {
return err
@@ -101,22 +102,22 @@ func syncGitConfig() (err error) {
// By default partial clones are disabled, enable them from git v2.22
if !setting.Git.DisablePartialClone && DefaultFeatures().CheckVersionAtLeast("2.22") {
if err = configSet("uploadpack.allowfilter", "true"); err != nil {
if err = configSet(ctx, "uploadpack.allowfilter", "true"); err != nil {
return err
}
err = configSet("uploadpack.allowAnySHA1InWant", "true")
err = configSet(ctx, "uploadpack.allowAnySHA1InWant", "true")
} else {
if err = configUnsetAll("uploadpack.allowfilter", "true"); err != nil {
if err = configUnsetAll(ctx, "uploadpack.allowfilter", "true"); err != nil {
return err
}
err = configUnsetAll("uploadpack.allowAnySHA1InWant", "true")
err = configUnsetAll(ctx, "uploadpack.allowAnySHA1InWant", "true")
}
return err
}
func configSet(key, value string) error {
stdout, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil)
func configSet(ctx context.Context, key, value string) error {
stdout, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil)
if err != nil && !IsErrorExitCode(err, 1) {
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
}
@@ -126,7 +127,7 @@ func configSet(key, value string) error {
return nil
}
_, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil)
_, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil)
if err != nil {
return fmt.Errorf("failed to set git global config %s, err: %w", key, err)
}
@@ -134,15 +135,15 @@ func configSet(key, value string) error {
return nil
}
func configSetNonExist(key, value string) error {
_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil)
func configSetNonExist(ctx context.Context, key, value string) error {
_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil)
if err == nil {
// already exist
return nil
}
if IsErrorExitCode(err, 1) {
// not exist, set new config
_, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil)
_, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil)
if err != nil {
return fmt.Errorf("failed to set git global config %s, err: %w", key, err)
}
@@ -152,15 +153,15 @@ func configSetNonExist(key, value string) error {
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
}
func configAddNonExist(key, value string) error {
_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(DefaultContext, nil)
func configAddNonExist(ctx context.Context, key, value string) error {
_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil)
if err == nil {
// already exist
return nil
}
if IsErrorExitCode(err, 1) {
// not exist, add new config
_, _, err = NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil)
_, _, err = NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(ctx, nil)
if err != nil {
return fmt.Errorf("failed to add git global config %s, err: %w", key, err)
}
@@ -169,11 +170,11 @@ func configAddNonExist(key, value string) error {
return fmt.Errorf("failed to get git config %s, err: %w", key, err)
}
func configUnsetAll(key, value string) error {
_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil)
func configUnsetAll(ctx context.Context, key, value string) error {
_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil)
if err == nil {
// exist, need to remove
_, _, err = NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(DefaultContext, nil)
_, _, err = NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil)
if err != nil {
return fmt.Errorf("failed to unset git global config %s, err: %w", key, err)
}

View File

@@ -21,35 +21,36 @@ func gitConfigContains(sub string) bool {
}
func TestGitConfig(t *testing.T) {
ctx := t.Context()
assert.False(t, gitConfigContains("key-a"))
assert.NoError(t, configSetNonExist("test.key-a", "val-a"))
assert.NoError(t, configSetNonExist(ctx, "test.key-a", "val-a"))
assert.True(t, gitConfigContains("key-a = val-a"))
assert.NoError(t, configSetNonExist("test.key-a", "val-a-changed"))
assert.NoError(t, configSetNonExist(ctx, "test.key-a", "val-a-changed"))
assert.False(t, gitConfigContains("key-a = val-a-changed"))
assert.NoError(t, configSet("test.key-a", "val-a-changed"))
assert.NoError(t, configSet(ctx, "test.key-a", "val-a-changed"))
assert.True(t, gitConfigContains("key-a = val-a-changed"))
assert.NoError(t, configAddNonExist("test.key-b", "val-b"))
assert.NoError(t, configAddNonExist(ctx, "test.key-b", "val-b"))
assert.True(t, gitConfigContains("key-b = val-b"))
assert.NoError(t, configAddNonExist("test.key-b", "val-2b"))
assert.NoError(t, configAddNonExist(ctx, "test.key-b", "val-2b"))
assert.True(t, gitConfigContains("key-b = val-b"))
assert.True(t, gitConfigContains("key-b = val-2b"))
assert.NoError(t, configUnsetAll("test.key-b", "val-b"))
assert.NoError(t, configUnsetAll(ctx, "test.key-b", "val-b"))
assert.False(t, gitConfigContains("key-b = val-b"))
assert.True(t, gitConfigContains("key-b = val-2b"))
assert.NoError(t, configUnsetAll("test.key-b", "val-2b"))
assert.NoError(t, configUnsetAll(ctx, "test.key-b", "val-2b"))
assert.False(t, gitConfigContains("key-b = val-2b"))
assert.NoError(t, configSet("test.key-x", "*"))
assert.NoError(t, configSet(ctx, "test.key-x", "*"))
assert.True(t, gitConfigContains("key-x = *"))
assert.NoError(t, configSetNonExist("test.key-x", "*"))
assert.NoError(t, configUnsetAll("test.key-x", "*"))
assert.NoError(t, configSetNonExist(ctx, "test.key-x", "*"))
assert.NoError(t, configUnsetAll(ctx, "test.key-x", "*"))
assert.False(t, gitConfigContains("key-x = *"))
}
@@ -60,7 +61,7 @@ func TestSyncConfig(t *testing.T) {
}()
setting.GitConfig.Options["sync-test.cfg-key-a"] = "CfgValA"
assert.NoError(t, syncGitConfig())
assert.NoError(t, syncGitConfig(t.Context()))
assert.True(t, gitConfigContains("[sync-test]"))
assert.True(t, gitConfigContains("cfg-key-a = CfgValA"))
}

View File

@@ -34,8 +34,7 @@ type Features struct {
}
var (
GitExecutable = "git" // the command name of git, will be updated to an absolute path during initialization
DefaultContext context.Context // the default context to run git commands in, must be initialized by git.InitXxx
GitExecutable = "git" // the command name of git, will be updated to an absolute path during initialization
defaultFeatures *Features
)
@@ -61,7 +60,7 @@ func DefaultFeatures() *Features {
}
func loadGitVersionFeatures() (*Features, error) {
stdout, _, runErr := NewCommand("version").RunStdString(DefaultContext, nil)
stdout, _, runErr := NewCommand("version").RunStdString(context.Background(), nil)
if runErr != nil {
return nil, runErr
}
@@ -163,14 +162,10 @@ func InitSimple() error {
return errors.New("unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
}
if DefaultContext != nil && (!setting.IsProd || setting.IsInTesting) {
if defaultFeatures != nil && (!setting.IsProd || setting.IsInTesting) {
log.Warn("git module has been initialized already, duplicate init may work but it's better to fix it")
}
// FIXME: git context is used across the application, so it should use the global default context, this design is not right but it's hard to change now.
DefaultContext = context.Background()
globalCommandArgs = nil
if setting.Git.Timeout.Default > 0 {
defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second
}
@@ -202,22 +197,11 @@ func InitFull() (err error) {
return err
}
// Since git wire protocol has been released from git v2.18
if setting.Git.EnableAutoGitWireProtocol && DefaultFeatures().CheckVersionAtLeast("2.18") {
globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
}
// Explicitly disable credential helper, otherwise Git credentials might leak
if DefaultFeatures().CheckVersionAtLeast("2.9") {
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
}
if setting.LFS.StartServer {
if !DefaultFeatures().CheckVersionAtLeast("2.1.2") {
return errors.New("LFS server support requires Git >= 2.1.2")
}
globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=", "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
}
return syncGitConfig()
return syncGitConfig(context.Background())
}

View File

@@ -11,7 +11,7 @@ import (
)
func TestGrepSearch(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "language_stats_repo"))
repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "language_stats_repo"))
assert.NoError(t, err)
defer repo.Close()

View File

@@ -12,7 +12,7 @@ import (
func TestGetNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -25,7 +25,7 @@ func TestGetNotes(t *testing.T) {
func TestGetNestedNotes(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo3_notes")
repo, err := openRepositoryWithDefaultContext(repoPath)
repo, err := OpenRepository(t.Context(), repoPath)
assert.NoError(t, err)
defer repo.Close()
@@ -40,7 +40,7 @@ func TestGetNestedNotes(t *testing.T) {
func TestGetNonExistentNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()

View File

@@ -121,17 +121,12 @@ type CloneRepoOptions struct {
// Clone clones original repository to target path.
func Clone(ctx context.Context, from, to string, opts CloneRepoOptions) error {
return CloneWithArgs(ctx, globalCommandArgs, from, to, opts)
}
// CloneWithArgs original repository to target path.
func CloneWithArgs(ctx context.Context, args TrustedCmdArgs, from, to string, opts CloneRepoOptions) (err error) {
toDir := path.Dir(to)
if err = os.MkdirAll(toDir, os.ModePerm); err != nil {
if err := os.MkdirAll(toDir, os.ModePerm); err != nil {
return err
}
cmd := NewCommandNoGlobals(args...).AddArguments("clone")
cmd := NewCommand().AddArguments("clone")
if opts.SkipTLSVerify {
cmd.AddArguments("-c", "http.sslVerify=false")
}

View File

@@ -39,11 +39,6 @@ type Repository struct {
objectFormat ObjectFormat
}
// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
return OpenRepository(DefaultContext, repoPath)
}
// OpenRepository opens the repository at the given path within the context.Context
func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
repoPath, err := filepath.Abs(repoPath)

View File

@@ -37,11 +37,6 @@ type Repository struct {
objectFormat ObjectFormat
}
// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
return OpenRepository(DefaultContext, repoPath)
}
// OpenRepository opens the repository at the given path with the provided context.
func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
repoPath, err := filepath.Abs(repoPath)

View File

@@ -14,7 +14,7 @@ import (
func TestRepository_GetBlob_Found(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := openRepositoryWithDefaultContext(repoPath)
r, err := OpenRepository(t.Context(), repoPath)
assert.NoError(t, err)
defer r.Close()
@@ -42,7 +42,7 @@ func TestRepository_GetBlob_Found(t *testing.T) {
func TestRepository_GetBlob_NotExist(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := openRepositoryWithDefaultContext(repoPath)
r, err := OpenRepository(t.Context(), repoPath)
assert.NoError(t, err)
defer r.Close()
@@ -56,7 +56,7 @@ func TestRepository_GetBlob_NotExist(t *testing.T) {
func TestRepository_GetBlob_NoId(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := openRepositoryWithDefaultContext(repoPath)
r, err := OpenRepository(t.Context(), repoPath)
assert.NoError(t, err)
defer r.Close()

View File

@@ -13,7 +13,7 @@ import (
func TestRepository_GetBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -41,7 +41,7 @@ func TestRepository_GetBranches(t *testing.T) {
func BenchmarkRepository_GetBranches(b *testing.B) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(b.Context(), bareRepo1Path)
if err != nil {
b.Fatal(err)
}
@@ -57,7 +57,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) {
func TestGetRefsBySha(t *testing.T) {
bareRepo5Path := filepath.Join(testReposDir, "repo5_pulls")
bareRepo5, err := OpenRepository(DefaultContext, bareRepo5Path)
bareRepo5, err := OpenRepository(t.Context(), bareRepo5Path)
if err != nil {
t.Fatal(err)
}
@@ -84,7 +84,7 @@ func TestGetRefsBySha(t *testing.T) {
func BenchmarkGetRefsBySha(b *testing.B) {
bareRepo5Path := filepath.Join(testReposDir, "repo5_pulls")
bareRepo5, err := OpenRepository(DefaultContext, bareRepo5Path)
bareRepo5, err := OpenRepository(b.Context(), bareRepo5Path)
if err != nil {
b.Fatal(err)
}
@@ -97,7 +97,7 @@ func BenchmarkGetRefsBySha(b *testing.B) {
}
func TestRepository_IsObjectExist(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
require.NoError(t, err)
defer repo.Close()
@@ -149,7 +149,7 @@ func TestRepository_IsObjectExist(t *testing.T) {
}
func TestRepository_IsReferenceExist(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
require.NoError(t, err)
defer repo.Close()

View File

@@ -17,7 +17,7 @@ import (
func TestRepository_GetCommitBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -44,7 +44,7 @@ func TestRepository_GetCommitBranches(t *testing.T) {
func TestGetTagCommitWithSignature(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -59,7 +59,7 @@ func TestGetTagCommitWithSignature(t *testing.T) {
func TestGetCommitWithBadCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -71,7 +71,7 @@ func TestGetCommitWithBadCommitID(t *testing.T) {
func TestIsCommitInBranch(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -86,7 +86,7 @@ func TestIsCommitInBranch(t *testing.T) {
func TestRepository_CommitsBetweenIDs(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo4_commitsbetween")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -108,7 +108,7 @@ func TestRepository_CommitsBetweenIDs(t *testing.T) {
func TestGetRefCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -135,7 +135,7 @@ func TestCommitsByFileAndRange(t *testing.T) {
defer test.MockVariableValue(&setting.Git.CommitsRangeSize, 2)()
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
require.NoError(t, err)
defer bareRepo1.Close()

View File

@@ -20,7 +20,7 @@ func TestGetFormatPatch(t *testing.T) {
return
}
repo, err := openRepositoryWithDefaultContext(clonedPath)
repo, err := OpenRepository(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return
@@ -48,7 +48,7 @@ func TestGetFormatPatch(t *testing.T) {
func TestReadPatch(t *testing.T) {
// Ensure we can read the patch files
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
repo, err := OpenRepository(t.Context(), bareRepo1Path)
if err != nil {
assert.NoError(t, err)
return
@@ -86,7 +86,7 @@ func TestReadWritePullHead(t *testing.T) {
return
}
repo, err := openRepositoryWithDefaultContext(clonedPath)
repo, err := OpenRepository(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return
@@ -122,7 +122,7 @@ func TestReadWritePullHead(t *testing.T) {
func TestGetCommitFilesChanged(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
repo, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer repo.Close()

View File

@@ -12,7 +12,7 @@ import (
func TestRepository_GetRefs(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -37,7 +37,7 @@ func TestRepository_GetRefs(t *testing.T) {
func TestRepository_GetRefsFiltered(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()

View File

@@ -13,7 +13,7 @@ import (
func TestRepository_GetCodeActivityStats(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()

View File

@@ -13,7 +13,7 @@ import (
func TestRepository_GetTags(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path)
if err != nil {
assert.NoError(t, err)
return
@@ -44,7 +44,7 @@ func TestRepository_GetTag(t *testing.T) {
return
}
bareRepo1, err := openRepositoryWithDefaultContext(clonedPath)
bareRepo1, err := OpenRepository(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return
@@ -136,7 +136,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
return
}
bareRepo1, err := openRepositoryWithDefaultContext(clonedPath)
bareRepo1, err := OpenRepository(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return

View File

@@ -12,7 +12,7 @@ import (
func TestGetLatestCommitTime(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
lct, err := GetLatestCommitTime(DefaultContext, bareRepo1Path)
lct, err := GetLatestCommitTime(t.Context(), bareRepo1Path)
assert.NoError(t, err)
// Time is Sun Nov 13 16:40:14 2022 +0100
// which is the time of commit
@@ -22,7 +22,7 @@ func TestGetLatestCommitTime(t *testing.T) {
func TestRepoIsEmpty(t *testing.T) {
emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty")
repo, err := openRepositoryWithDefaultContext(emptyRepo2Path)
repo, err := OpenRepository(t.Context(), emptyRepo2Path)
assert.NoError(t, err)
defer repo.Close()
isEmpty, err := repo.IsEmpty()

View File

@@ -14,7 +14,7 @@ import (
func TestGetTemplateSubmoduleCommits(t *testing.T) {
testRepoPath := filepath.Join(testReposDir, "repo4_submodules")
submodules, err := GetTemplateSubmoduleCommits(DefaultContext, testRepoPath)
submodules, err := GetTemplateSubmoduleCommits(t.Context(), testRepoPath)
require.NoError(t, err)
assert.Len(t, submodules, 2)
@@ -39,7 +39,7 @@ func TestAddTemplateSubmoduleIndexes(t *testing.T) {
require.NoError(t, err)
_, _, err = NewCommand("-c", "user.name=a", "-c", "user.email=b", "commit", "-m=test").RunStdString(ctx, &RunOpts{Dir: tmpDir})
require.NoError(t, err)
submodules, err := GetTemplateSubmoduleCommits(DefaultContext, tmpDir)
submodules, err := GetTemplateSubmoduleCommits(t.Context(), tmpDir)
require.NoError(t, err)
assert.Len(t, submodules, 1)
assert.Equal(t, "new-dir", submodules[0].Path)

View File

@@ -13,7 +13,7 @@ import (
)
func TestFollowLink(t *testing.T) {
r, err := openRepositoryWithDefaultContext("tests/repos/repo1_bare")
r, err := OpenRepository(t.Context(), "tests/repos/repo1_bare")
require.NoError(t, err)
defer r.Close()

View File

@@ -11,7 +11,7 @@ import (
)
func TestSubTree_Issue29101(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
assert.NoError(t, err)
defer repo.Close()
@@ -27,7 +27,7 @@ func TestSubTree_Issue29101(t *testing.T) {
}
func Test_GetTreePathLatestCommit(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo6_blame"))
repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo6_blame"))
assert.NoError(t, err)
defer repo.Close()

View File

@@ -50,7 +50,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) {
pushCommits.HeadCommit = &PushCommit{Sha1: "69554a6"}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(git.DefaultContext, repo)
payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(t.Context(), repo)
assert.NoError(t, err)
assert.Len(t, payloadCommits, 3)
assert.NotNil(t, headCommit)