Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions models/git/commit_status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/commitstatus"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -187,7 +186,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) {

repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo2)
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo2)
assert.NoError(t, err)
defer gitRepo.Close()

Expand Down
27 changes: 16 additions & 11 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,24 @@ const minDBVersion = 70 // Gitea 1.5.3
type migration struct {
idNumber int64 // DB version is "the last migration's idNumber" + 1
description string
migrate func(*xorm.Engine) error
migrate func(context.Context, *xorm.Engine) error
}

// newMigration creates a new migration
func newMigration(idNumber int64, desc string, fn func(*xorm.Engine) error) *migration {
return &migration{idNumber, desc, fn}
func newMigration[T func(*xorm.Engine) error | func(context.Context, *xorm.Engine) error](idNumber int64, desc string, fn T) *migration {
m := &migration{idNumber: idNumber, description: desc}
var ok bool
if m.migrate, ok = any(fn).(func(context.Context, *xorm.Engine) error); !ok {
m.migrate = func(ctx context.Context, x *xorm.Engine) error {
return any(fn).(func(*xorm.Engine) error)(x)
}
}
return m
}

// Migrate executes the migration
func (m *migration) Migrate(x *xorm.Engine) error {
return m.migrate(x)
func (m *migration) Migrate(ctx context.Context, x *xorm.Engine) error {
return m.migrate(ctx, x)
}

// Version describes the version table. Should have only one row with id==1
Expand Down Expand Up @@ -456,7 +463,7 @@ func migrationIDNumberToDBVersion(idNumber int64) int64 {
}

// Migrate database to current version
func Migrate(x *xorm.Engine) error {
func Migrate(ctx context.Context, x *xorm.Engine) error {
migrations := prepareMigrationTasks()
maxDBVer := calcDBVersion(migrations)

Expand Down Expand Up @@ -500,18 +507,16 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t
}

// Some migration tasks depend on the git command
if git.DefaultContext == nil {
if err = git.InitSimple(); err != nil {
return err
}
if err = git.InitSimple(); err != nil {
return err
}

// Migrate
for _, m := range getPendingMigrations(curDBVer, migrations) {
log.Info("Migration[%d]: %s", m.idNumber, m.description)
// Reset the mapper between each migration - migrations are not supposed to depend on each other
x.SetMapper(names.GonicMapper{})
if err = m.Migrate(x); err != nil {
if err = m.Migrate(ctx, x); err != nil {
return fmt.Errorf("migration[%d]: %s failed: %w", m.idNumber, m.description, err)
}
currentVersion.Version = migrationIDNumberToDBVersion(m.idNumber)
Expand Down
11 changes: 6 additions & 5 deletions models/migrations/v1_12/v128.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package v1_12

import (
"context"
"fmt"
"math"
"path/filepath"
Expand All @@ -17,7 +18,7 @@ import (
"xorm.io/xorm"
)

func FixMergeBase(x *xorm.Engine) error {
func FixMergeBase(ctx context.Context, x *xorm.Engine) error {
type Repository struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s) index"`
Expand Down Expand Up @@ -82,17 +83,17 @@ func FixMergeBase(x *xorm.Engine) error {

if !pr.HasMerged {
var err error
pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath})
pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
if err != nil {
var err2 error
pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath})
pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
if err2 != nil {
log.Error("Unable to get merge base for PR ID %d, Index %d in %s/%s. Error: %v & %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err, err2)
continue
}
}
} else {
parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath})
parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
if err != nil {
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
Expand All @@ -106,7 +107,7 @@ func FixMergeBase(x *xorm.Engine) error {
refs = append(refs, gitRefName)
cmd := git.NewCommand("merge-base").AddDashesAndList(refs...)

pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath})
pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath})
if err != nil {
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
Expand Down
7 changes: 4 additions & 3 deletions models/migrations/v1_12/v134.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package v1_12

import (
"context"
"fmt"
"math"
"path/filepath"
Expand All @@ -17,7 +18,7 @@ import (
"xorm.io/xorm"
)

func RefixMergeBase(x *xorm.Engine) error {
func RefixMergeBase(ctx context.Context, x *xorm.Engine) error {
type Repository struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s) index"`
Expand Down Expand Up @@ -79,7 +80,7 @@ func RefixMergeBase(x *xorm.Engine) error {

gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)

parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath})
parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
if err != nil {
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
Expand All @@ -94,7 +95,7 @@ func RefixMergeBase(x *xorm.Engine) error {
refs = append(refs, gitRefName)
cmd := git.NewCommand("merge-base").AddDashesAndList(refs...)

pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath})
pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath})
if err != nil {
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
Expand Down
5 changes: 3 additions & 2 deletions models/migrations/v1_14/v156.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package v1_14

import (
"context"
"fmt"
"path/filepath"
"strings"
Expand All @@ -24,7 +25,7 @@ func userPath(userName string) string {
return filepath.Join(setting.RepoRootPath, strings.ToLower(userName))
}

func FixPublisherIDforTagReleases(x *xorm.Engine) error {
func FixPublisherIDforTagReleases(ctx context.Context, x *xorm.Engine) error {
type Release struct {
ID int64
RepoID int64
Expand Down Expand Up @@ -108,7 +109,7 @@ func FixPublisherIDforTagReleases(x *xorm.Engine) error {
return err
}
}
gitRepo, err = git.OpenRepository(git.DefaultContext, repoPath(repo.OwnerName, repo.Name))
gitRepo, err = git.OpenRepository(ctx, repoPath(repo.OwnerName, repo.Name))
if err != nil {
log.Error("Error whilst opening git repo for [%d]%s/%s. Error: %v", repo.ID, repo.OwnerName, repo.Name, err)
return err
Expand Down
5 changes: 3 additions & 2 deletions models/migrations/v1_9/v82.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package v1_9

import (
"context"
"fmt"
"path/filepath"
"strings"
Expand All @@ -14,7 +15,7 @@ import (
"xorm.io/xorm"
)

func FixReleaseSha1OnReleaseTable(x *xorm.Engine) error {
func FixReleaseSha1OnReleaseTable(ctx context.Context, x *xorm.Engine) error {
type Release struct {
ID int64
RepoID int64
Expand Down Expand Up @@ -98,7 +99,7 @@ func FixReleaseSha1OnReleaseTable(x *xorm.Engine) error {
userCache[repo.OwnerID] = user
}

gitRepo, err = git.OpenRepository(git.DefaultContext, RepoPath(user.Name, repo.Name))
gitRepo, err = git.OpenRepository(ctx, RepoPath(user.Name, repo.Name))
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion modules/git/blame.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions modules/git/blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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)
}
Expand Down
59 changes: 8 additions & 51 deletions modules/git/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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, " ")
Expand All @@ -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))
Expand Down Expand Up @@ -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]
}
4 changes: 2 additions & 2 deletions modules/git/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
25 changes: 6 additions & 19 deletions modules/git/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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)
Expand All @@ -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
Expand Down
Loading