Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
58 changes: 8 additions & 50 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 @@ -92,23 +83,6 @@ func (c *Command) ProcessState() string {
// 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 +442,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