mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Remove context from git struct (#33793)
Argument is moved from struct init in command run, which lets us remove context from struct.
This commit is contained in:
		| @@ -316,7 +316,7 @@ func runHookPostReceive(c *cli.Context) error { | |||||||
| 	setup(ctx, c.Bool("debug")) | 	setup(ctx, c.Bool("debug")) | ||||||
|  |  | ||||||
| 	// First of all run update-server-info no matter what | 	// First of all run update-server-info no matter what | ||||||
| 	if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil { | 	if _, _, err := git.NewCommand("update-server-info").RunStdString(ctx, nil); err != nil { | ||||||
| 		return fmt.Errorf("Failed to call 'git update-server-info': %w", err) | 		return fmt.Errorf("Failed to call 'git update-server-info': %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -82,17 +82,17 @@ func FixMergeBase(x *xorm.Engine) error { | |||||||
|  |  | ||||||
| 			if !pr.HasMerged { | 			if !pr.HasMerged { | ||||||
| 				var err error | 				var err error | ||||||
| 				pr.MergeBase, _, err = git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(&git.RunOpts{Dir: repoPath}) | 				pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					var err2 error | 					var err2 error | ||||||
| 					pr.MergeBase, _, err2 = git.NewCommand(git.DefaultContext, "rev-parse").AddDynamicArguments(git.BranchPrefix + pr.BaseBranch).RunStdString(&git.RunOpts{Dir: repoPath}) | 					pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 					if err2 != nil { | 					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) | 						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 | 						continue | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				parentsString, _, err := git.NewCommand(git.DefaultContext, "rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(&git.RunOpts{Dir: repoPath}) | 				parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 				if err != nil { | 				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) | 					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 | 					continue | ||||||
| @@ -104,9 +104,9 @@ func FixMergeBase(x *xorm.Engine) error { | |||||||
|  |  | ||||||
| 				refs := append([]string{}, parents[1:]...) | 				refs := append([]string{}, parents[1:]...) | ||||||
| 				refs = append(refs, gitRefName) | 				refs = append(refs, gitRefName) | ||||||
| 				cmd := git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(refs...) | 				cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) | ||||||
|  |  | ||||||
| 				pr.MergeBase, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) | 				pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 				if err != nil { | 				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) | 					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 | 					continue | ||||||
|   | |||||||
| @@ -79,7 +79,7 @@ func RefixMergeBase(x *xorm.Engine) error { | |||||||
|  |  | ||||||
| 			gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index) | 			gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index) | ||||||
|  |  | ||||||
| 			parentsString, _, err := git.NewCommand(git.DefaultContext, "rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(&git.RunOpts{Dir: repoPath}) | 			parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 			if err != nil { | 			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) | 				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 | 				continue | ||||||
| @@ -92,9 +92,9 @@ func RefixMergeBase(x *xorm.Engine) error { | |||||||
| 			// we should recalculate | 			// we should recalculate | ||||||
| 			refs := append([]string{}, parents[1:]...) | 			refs := append([]string{}, parents[1:]...) | ||||||
| 			refs = append(refs, gitRefName) | 			refs = append(refs, gitRefName) | ||||||
| 			cmd := git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(refs...) | 			cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) | ||||||
|  |  | ||||||
| 			pr.MergeBase, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) | 			pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 			if err != nil { | 			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) | 				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 | 				continue | ||||||
|   | |||||||
| @@ -29,8 +29,8 @@ type WriteCloserError interface { | |||||||
| // This is needed otherwise the git cat-file will hang for invalid repositories. | // This is needed otherwise the git cat-file will hang for invalid repositories. | ||||||
| func ensureValidGitRepository(ctx context.Context, repoPath string) error { | func ensureValidGitRepository(ctx context.Context, repoPath string) error { | ||||||
| 	stderr := strings.Builder{} | 	stderr := strings.Builder{} | ||||||
| 	err := NewCommand(ctx, "rev-parse"). | 	err := NewCommand("rev-parse"). | ||||||
| 		Run(&RunOpts{ | 		Run(ctx, &RunOpts{ | ||||||
| 			Dir:    repoPath, | 			Dir:    repoPath, | ||||||
| 			Stderr: &stderr, | 			Stderr: &stderr, | ||||||
| 		}) | 		}) | ||||||
| @@ -61,8 +61,8 @@ func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, | |||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		stderr := strings.Builder{} | 		stderr := strings.Builder{} | ||||||
| 		err := NewCommand(ctx, "cat-file", "--batch-check"). | 		err := NewCommand("cat-file", "--batch-check"). | ||||||
| 			Run(&RunOpts{ | 			Run(ctx, &RunOpts{ | ||||||
| 				Dir:    repoPath, | 				Dir:    repoPath, | ||||||
| 				Stdin:  batchStdinReader, | 				Stdin:  batchStdinReader, | ||||||
| 				Stdout: batchStdoutWriter, | 				Stdout: batchStdoutWriter, | ||||||
| @@ -109,8 +109,8 @@ func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi | |||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		stderr := strings.Builder{} | 		stderr := strings.Builder{} | ||||||
| 		err := NewCommand(ctx, "cat-file", "--batch"). | 		err := NewCommand("cat-file", "--batch"). | ||||||
| 			Run(&RunOpts{ | 			Run(ctx, &RunOpts{ | ||||||
| 				Dir:    repoPath, | 				Dir:    repoPath, | ||||||
| 				Stdin:  batchStdinReader, | 				Stdin:  batchStdinReader, | ||||||
| 				Stdout: batchStdoutWriter, | 				Stdout: batchStdoutWriter, | ||||||
|   | |||||||
| @@ -135,7 +135,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath | |||||||
| 		ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit) | 		ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := NewCommandContextNoGlobals(ctx, "blame", "--porcelain") | 	cmd := NewCommandNoGlobals("blame", "--porcelain") | ||||||
| 	if ignoreRevsFile != nil { | 	if ignoreRevsFile != nil { | ||||||
| 		// Possible improvement: use --ignore-revs-file /dev/stdin on unix | 		// Possible improvement: use --ignore-revs-file /dev/stdin on unix | ||||||
| 		// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend. | 		// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend. | ||||||
| @@ -155,7 +155,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath | |||||||
| 	go func() { | 	go func() { | ||||||
| 		stderr := bytes.Buffer{} | 		stderr := bytes.Buffer{} | ||||||
| 		// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close" | 		// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close" | ||||||
| 		err := cmd.Run(&RunOpts{ | 		err := cmd.Run(ctx, &RunOpts{ | ||||||
| 			UseContextTimeout: true, | 			UseContextTimeout: true, | ||||||
| 			Dir:               repoPath, | 			Dir:               repoPath, | ||||||
| 			Stdout:            stdout, | 			Stdout:            stdout, | ||||||
|   | |||||||
| @@ -44,7 +44,6 @@ const DefaultLocale = "C" | |||||||
| type Command struct { | type Command struct { | ||||||
| 	prog             string | 	prog             string | ||||||
| 	args             []string | 	args             []string | ||||||
| 	parentContext    context.Context |  | ||||||
| 	globalArgsLength int | 	globalArgsLength int | ||||||
| 	brokenArgs       []string | 	brokenArgs       []string | ||||||
| } | } | ||||||
| @@ -82,7 +81,7 @@ func (c *Command) LogString() string { | |||||||
|  |  | ||||||
| // NewCommand creates and returns a new Git Command based on given command and arguments. | // 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. | // Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead. | ||||||
| func NewCommand(ctx context.Context, args ...internal.CmdArg) *Command { | func NewCommand(args ...internal.CmdArg) *Command { | ||||||
| 	// Make an explicit copy of globalCommandArgs, otherwise append might overwrite it | 	// Make an explicit copy of globalCommandArgs, otherwise append might overwrite it | ||||||
| 	cargs := make([]string, 0, len(globalCommandArgs)+len(args)) | 	cargs := make([]string, 0, len(globalCommandArgs)+len(args)) | ||||||
| 	for _, arg := range globalCommandArgs { | 	for _, arg := range globalCommandArgs { | ||||||
| @@ -94,14 +93,13 @@ func NewCommand(ctx context.Context, args ...internal.CmdArg) *Command { | |||||||
| 	return &Command{ | 	return &Command{ | ||||||
| 		prog:             GitExecutable, | 		prog:             GitExecutable, | ||||||
| 		args:             cargs, | 		args:             cargs, | ||||||
| 		parentContext:    ctx, |  | ||||||
| 		globalArgsLength: len(globalCommandArgs), | 		globalArgsLength: len(globalCommandArgs), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewCommandContextNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args | // 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. | // Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead. | ||||||
| func NewCommandContextNoGlobals(ctx context.Context, args ...internal.CmdArg) *Command { | func NewCommandNoGlobals(args ...internal.CmdArg) *Command { | ||||||
| 	cargs := make([]string, 0, len(args)) | 	cargs := make([]string, 0, len(args)) | ||||||
| 	for _, arg := range args { | 	for _, arg := range args { | ||||||
| 		cargs = append(cargs, string(arg)) | 		cargs = append(cargs, string(arg)) | ||||||
| @@ -109,16 +107,9 @@ func NewCommandContextNoGlobals(ctx context.Context, args ...internal.CmdArg) *C | |||||||
| 	return &Command{ | 	return &Command{ | ||||||
| 		prog: GitExecutable, | 		prog: GitExecutable, | ||||||
| 		args: cargs, | 		args: cargs, | ||||||
| 		parentContext: ctx, |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // SetParentContext sets the parent context for this command |  | ||||||
| func (c *Command) SetParentContext(ctx context.Context) *Command { |  | ||||||
| 	c.parentContext = ctx |  | ||||||
| 	return c |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // isSafeArgumentValue checks if the argument is safe to be used as a value (not an option) | // isSafeArgumentValue checks if the argument is safe to be used as a value (not an option) | ||||||
| func isSafeArgumentValue(s string) bool { | func isSafeArgumentValue(s string) bool { | ||||||
| 	return s == "" || s[0] != '-' | 	return s == "" || s[0] != '-' | ||||||
| @@ -277,11 +268,11 @@ func CommonCmdServEnvs() []string { | |||||||
| var ErrBrokenCommand = errors.New("git command is broken") | var ErrBrokenCommand = errors.New("git command is broken") | ||||||
|  |  | ||||||
| // Run runs the command with the RunOpts | // Run runs the command with the RunOpts | ||||||
| func (c *Command) Run(opts *RunOpts) error { | func (c *Command) Run(ctx context.Context, opts *RunOpts) error { | ||||||
| 	return c.run(1, opts) | 	return c.run(ctx, 1, opts) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Command) run(skip int, opts *RunOpts) error { | func (c *Command) run(ctx context.Context, skip int, opts *RunOpts) error { | ||||||
| 	if len(c.brokenArgs) != 0 { | 	if len(c.brokenArgs) != 0 { | ||||||
| 		log.Error("git command is broken: %s, broken args: %s", c.LogString(), strings.Join(c.brokenArgs, " ")) | 		log.Error("git command is broken: %s, broken args: %s", c.LogString(), strings.Join(c.brokenArgs, " ")) | ||||||
| 		return ErrBrokenCommand | 		return ErrBrokenCommand | ||||||
| @@ -305,19 +296,18 @@ func (c *Command) run(skip int, opts *RunOpts) error { | |||||||
| 	desc := fmt.Sprintf("git.Run(by:%s, repo:%s): %s", callerInfo, logArgSanitize(opts.Dir), cmdLogString) | 	desc := fmt.Sprintf("git.Run(by:%s, repo:%s): %s", callerInfo, logArgSanitize(opts.Dir), cmdLogString) | ||||||
| 	log.Debug("git.Command: %s", desc) | 	log.Debug("git.Command: %s", desc) | ||||||
|  |  | ||||||
| 	_, span := gtprof.GetTracer().Start(c.parentContext, gtprof.TraceSpanGitRun) | 	_, span := gtprof.GetTracer().Start(ctx, gtprof.TraceSpanGitRun) | ||||||
| 	defer span.End() | 	defer span.End() | ||||||
| 	span.SetAttributeString(gtprof.TraceAttrFuncCaller, callerInfo) | 	span.SetAttributeString(gtprof.TraceAttrFuncCaller, callerInfo) | ||||||
| 	span.SetAttributeString(gtprof.TraceAttrGitCommand, cmdLogString) | 	span.SetAttributeString(gtprof.TraceAttrGitCommand, cmdLogString) | ||||||
|  |  | ||||||
| 	var ctx context.Context |  | ||||||
| 	var cancel context.CancelFunc | 	var cancel context.CancelFunc | ||||||
| 	var finished context.CancelFunc | 	var finished context.CancelFunc | ||||||
|  |  | ||||||
| 	if opts.UseContextTimeout { | 	if opts.UseContextTimeout { | ||||||
| 		ctx, cancel, finished = process.GetManager().AddContext(c.parentContext, desc) | 		ctx, cancel, finished = process.GetManager().AddContext(ctx, desc) | ||||||
| 	} else { | 	} else { | ||||||
| 		ctx, cancel, finished = process.GetManager().AddContextTimeout(c.parentContext, timeout, desc) | 		ctx, cancel, finished = process.GetManager().AddContextTimeout(ctx, timeout, desc) | ||||||
| 	} | 	} | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| @@ -410,8 +400,8 @@ func IsErrorExitCode(err error, code int) bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| // RunStdString runs the command with options and returns stdout/stderr as string. and store stderr to returned error (err combined with stderr). | // RunStdString runs the command with options and returns stdout/stderr as string. and store stderr to returned error (err combined with stderr). | ||||||
| func (c *Command) RunStdString(opts *RunOpts) (stdout, stderr string, runErr RunStdError) { | func (c *Command) RunStdString(ctx context.Context, opts *RunOpts) (stdout, stderr string, runErr RunStdError) { | ||||||
| 	stdoutBytes, stderrBytes, err := c.runStdBytes(opts) | 	stdoutBytes, stderrBytes, err := c.runStdBytes(ctx, opts) | ||||||
| 	stdout = util.UnsafeBytesToString(stdoutBytes) | 	stdout = util.UnsafeBytesToString(stdoutBytes) | ||||||
| 	stderr = util.UnsafeBytesToString(stderrBytes) | 	stderr = util.UnsafeBytesToString(stderrBytes) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -422,11 +412,11 @@ func (c *Command) RunStdString(opts *RunOpts) (stdout, stderr string, runErr Run | |||||||
| } | } | ||||||
|  |  | ||||||
| // RunStdBytes runs the command with options and returns stdout/stderr as bytes. and store stderr to returned error (err combined with stderr). | // RunStdBytes runs the command with options and returns stdout/stderr as bytes. and store stderr to returned error (err combined with stderr). | ||||||
| func (c *Command) RunStdBytes(opts *RunOpts) (stdout, stderr []byte, runErr RunStdError) { | func (c *Command) RunStdBytes(ctx context.Context, opts *RunOpts) (stdout, stderr []byte, runErr RunStdError) { | ||||||
| 	return c.runStdBytes(opts) | 	return c.runStdBytes(ctx, opts) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Command) runStdBytes(opts *RunOpts) (stdout, stderr []byte, runErr RunStdError) { | func (c *Command) runStdBytes(ctx context.Context, opts *RunOpts) (stdout, stderr []byte, runErr RunStdError) { | ||||||
| 	if opts == nil { | 	if opts == nil { | ||||||
| 		opts = &RunOpts{} | 		opts = &RunOpts{} | ||||||
| 	} | 	} | ||||||
| @@ -449,7 +439,7 @@ func (c *Command) runStdBytes(opts *RunOpts) (stdout, stderr []byte, runErr RunS | |||||||
| 		PipelineFunc:      opts.PipelineFunc, | 		PipelineFunc:      opts.PipelineFunc, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err := c.run(2, newOpts) | 	err := c.run(ctx, 2, newOpts) | ||||||
| 	stderr = stderrBuf.Bytes() | 	stderr = stderrBuf.Bytes() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, stderr, &runStdError{err: err, stderr: util.UnsafeBytesToString(stderr)} | 		return nil, stderr, &runStdError{err: err, stderr: util.UnsafeBytesToString(stderr)} | ||||||
|   | |||||||
| @@ -15,9 +15,9 @@ func TestRunWithContextNoTimeout(t *testing.T) { | |||||||
| 	maxLoops := 10 | 	maxLoops := 10 | ||||||
|  |  | ||||||
| 	// 'git --version' does not block so it must be finished before the timeout triggered. | 	// 'git --version' does not block so it must be finished before the timeout triggered. | ||||||
| 	cmd := NewCommand(t.Context(), "--version") | 	cmd := NewCommand("--version") | ||||||
| 	for i := 0; i < maxLoops; i++ { | 	for i := 0; i < maxLoops; i++ { | ||||||
| 		if err := cmd.Run(&RunOpts{}); err != nil { | 		if err := cmd.Run(t.Context(), &RunOpts{}); err != nil { | ||||||
| 			t.Fatal(err) | 			t.Fatal(err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -27,9 +27,9 @@ func TestRunWithContextTimeout(t *testing.T) { | |||||||
| 	maxLoops := 10 | 	maxLoops := 10 | ||||||
|  |  | ||||||
| 	// 'git hash-object --stdin' blocks on stdin so we can have the timeout triggered. | 	// 'git hash-object --stdin' blocks on stdin so we can have the timeout triggered. | ||||||
| 	cmd := NewCommand(t.Context(), "hash-object", "--stdin") | 	cmd := NewCommand("hash-object", "--stdin") | ||||||
| 	for i := 0; i < maxLoops; i++ { | 	for i := 0; i < maxLoops; i++ { | ||||||
| 		if err := cmd.Run(&RunOpts{Timeout: 1 * time.Millisecond}); err != nil { | 		if err := cmd.Run(t.Context(), &RunOpts{Timeout: 1 * time.Millisecond}); err != nil { | ||||||
| 			if err != context.DeadlineExceeded { | 			if err != context.DeadlineExceeded { | ||||||
| 				t.Fatalf("Testing %d/%d: %v", i, maxLoops, err) | 				t.Fatalf("Testing %d/%d: %v", i, maxLoops, err) | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -10,14 +10,14 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestRunWithContextStd(t *testing.T) { | func TestRunWithContextStd(t *testing.T) { | ||||||
| 	cmd := NewCommand(t.Context(), "--version") | 	cmd := NewCommand("--version") | ||||||
| 	stdout, stderr, err := cmd.RunStdString(&RunOpts{}) | 	stdout, stderr, err := cmd.RunStdString(t.Context(), &RunOpts{}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Empty(t, stderr) | 	assert.Empty(t, stderr) | ||||||
| 	assert.Contains(t, stdout, "git version") | 	assert.Contains(t, stdout, "git version") | ||||||
|  |  | ||||||
| 	cmd = NewCommand(t.Context(), "--no-such-arg") | 	cmd = NewCommand("--no-such-arg") | ||||||
| 	stdout, stderr, err = cmd.RunStdString(&RunOpts{}) | 	stdout, stderr, err = cmd.RunStdString(t.Context(), &RunOpts{}) | ||||||
| 	if assert.Error(t, err) { | 	if assert.Error(t, err) { | ||||||
| 		assert.Equal(t, stderr, err.Stderr()) | 		assert.Equal(t, stderr, err.Stderr()) | ||||||
| 		assert.Contains(t, err.Stderr(), "unknown option:") | 		assert.Contains(t, err.Stderr(), "unknown option:") | ||||||
| @@ -25,17 +25,17 @@ func TestRunWithContextStd(t *testing.T) { | |||||||
| 		assert.Empty(t, stdout) | 		assert.Empty(t, stdout) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd = NewCommand(t.Context()) | 	cmd = NewCommand() | ||||||
| 	cmd.AddDynamicArguments("-test") | 	cmd.AddDynamicArguments("-test") | ||||||
| 	assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand) | 	assert.ErrorIs(t, cmd.Run(t.Context(), &RunOpts{}), ErrBrokenCommand) | ||||||
|  |  | ||||||
| 	cmd = NewCommand(t.Context()) | 	cmd = NewCommand() | ||||||
| 	cmd.AddDynamicArguments("--test") | 	cmd.AddDynamicArguments("--test") | ||||||
| 	assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand) | 	assert.ErrorIs(t, cmd.Run(t.Context(), &RunOpts{}), ErrBrokenCommand) | ||||||
|  |  | ||||||
| 	subCmd := "version" | 	subCmd := "version" | ||||||
| 	cmd = NewCommand(t.Context()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production | 	cmd = NewCommand().AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production | ||||||
| 	stdout, stderr, err = cmd.RunStdString(&RunOpts{}) | 	stdout, stderr, err = cmd.RunStdString(t.Context(), &RunOpts{}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Empty(t, stderr) | 	assert.Empty(t, stderr) | ||||||
| 	assert.Contains(t, stdout, "git version") | 	assert.Contains(t, stdout, "git version") | ||||||
| @@ -53,9 +53,9 @@ func TestGitArgument(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestCommandString(t *testing.T) { | func TestCommandString(t *testing.T) { | ||||||
| 	cmd := NewCommandContextNoGlobals(t.Context(), "a", "-m msg", "it's a test", `say "hello"`) | 	cmd := NewCommandNoGlobals("a", "-m msg", "it's a test", `say "hello"`) | ||||||
| 	assert.EqualValues(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.LogString()) | 	assert.EqualValues(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.LogString()) | ||||||
|  |  | ||||||
| 	cmd = NewCommandContextNoGlobals(t.Context(), "url: https://a:b@c/", "/root/dir-a/dir-b") | 	cmd = NewCommandNoGlobals("url: https://a:b@c/", "/root/dir-a/dir-b") | ||||||
| 	assert.EqualValues(t, cmd.prog+` "url: https://sanitized-credential@c/" .../dir-a/dir-b`, cmd.LogString()) | 	assert.EqualValues(t, cmd.prog+` "url: https://sanitized-credential@c/" .../dir-a/dir-b`, cmd.LogString()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -91,12 +91,12 @@ func AddChanges(repoPath string, all bool, files ...string) error { | |||||||
|  |  | ||||||
| // AddChangesWithArgs marks local changes to be ready for commit. | // AddChangesWithArgs marks local changes to be ready for commit. | ||||||
| func AddChangesWithArgs(repoPath string, globalArgs TrustedCmdArgs, all bool, files ...string) error { | func AddChangesWithArgs(repoPath string, globalArgs TrustedCmdArgs, all bool, files ...string) error { | ||||||
| 	cmd := NewCommandContextNoGlobals(DefaultContext, globalArgs...).AddArguments("add") | 	cmd := NewCommandNoGlobals(globalArgs...).AddArguments("add") | ||||||
| 	if all { | 	if all { | ||||||
| 		cmd.AddArguments("--all") | 		cmd.AddArguments("--all") | ||||||
| 	} | 	} | ||||||
| 	cmd.AddDashesAndList(files...) | 	cmd.AddDashesAndList(files...) | ||||||
| 	_, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	_, _, err := cmd.RunStdString(DefaultContext, &RunOpts{Dir: repoPath}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -118,7 +118,7 @@ func CommitChanges(repoPath string, opts CommitChangesOptions) error { | |||||||
| // CommitChangesWithArgs commits local changes with given committer, author and message. | // CommitChangesWithArgs commits local changes with given committer, author and message. | ||||||
| // If author is nil, it will be the same as committer. | // If author is nil, it will be the same as committer. | ||||||
| func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChangesOptions) error { | func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChangesOptions) error { | ||||||
| 	cmd := NewCommandContextNoGlobals(DefaultContext, args...) | 	cmd := NewCommandNoGlobals(args...) | ||||||
| 	if opts.Committer != nil { | 	if opts.Committer != nil { | ||||||
| 		cmd.AddOptionValues("-c", "user.name="+opts.Committer.Name) | 		cmd.AddOptionValues("-c", "user.name="+opts.Committer.Name) | ||||||
| 		cmd.AddOptionValues("-c", "user.email="+opts.Committer.Email) | 		cmd.AddOptionValues("-c", "user.email="+opts.Committer.Email) | ||||||
| @@ -133,7 +133,7 @@ func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChan | |||||||
| 	} | 	} | ||||||
| 	cmd.AddOptionFormat("--message=%s", opts.Message) | 	cmd.AddOptionFormat("--message=%s", opts.Message) | ||||||
|  |  | ||||||
| 	_, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	_, _, err := cmd.RunStdString(DefaultContext, &RunOpts{Dir: repoPath}) | ||||||
| 	// No stderr but exit status 1 means nothing to commit. | 	// No stderr but exit status 1 means nothing to commit. | ||||||
| 	if err != nil && err.Error() == "exit status 1" { | 	if err != nil && err.Error() == "exit status 1" { | ||||||
| 		return nil | 		return nil | ||||||
| @@ -143,7 +143,7 @@ func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChan | |||||||
|  |  | ||||||
| // AllCommitsCount returns count of all commits in repository | // AllCommitsCount returns count of all commits in repository | ||||||
| func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, files ...string) (int64, error) { | func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, files ...string) (int64, error) { | ||||||
| 	cmd := NewCommand(ctx, "rev-list") | 	cmd := NewCommand("rev-list") | ||||||
| 	if hidePRRefs { | 	if hidePRRefs { | ||||||
| 		cmd.AddArguments("--exclude=" + PullPrefix + "*") | 		cmd.AddArguments("--exclude=" + PullPrefix + "*") | ||||||
| 	} | 	} | ||||||
| @@ -152,7 +152,7 @@ func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, file | |||||||
| 		cmd.AddDashesAndList(files...) | 		cmd.AddDashesAndList(files...) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, err | 		return 0, err | ||||||
| 	} | 	} | ||||||
| @@ -170,7 +170,7 @@ type CommitsCountOptions struct { | |||||||
|  |  | ||||||
| // CommitsCount returns number of total commits of until given revision. | // CommitsCount returns number of total commits of until given revision. | ||||||
| func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error) { | func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error) { | ||||||
| 	cmd := NewCommand(ctx, "rev-list", "--count") | 	cmd := NewCommand("rev-list", "--count") | ||||||
|  |  | ||||||
| 	cmd.AddDynamicArguments(opts.Revision...) | 	cmd.AddDynamicArguments(opts.Revision...) | ||||||
|  |  | ||||||
| @@ -182,7 +182,7 @@ func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error) | |||||||
| 		cmd.AddDashesAndList(opts.RelPath...) | 		cmd.AddDashesAndList(opts.RelPath...) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, err := cmd.RunStdString(&RunOpts{Dir: opts.RepoPath}) | 	stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: opts.RepoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, err | 		return 0, err | ||||||
| 	} | 	} | ||||||
| @@ -217,7 +217,7 @@ func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) { | |||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, _, err := NewCommand(c.repo.Ctx, "merge-base", "--is-ancestor").AddDynamicArguments(that, this).RunStdString(&RunOpts{Dir: c.repo.Path}) | 	_, _, err := NewCommand("merge-base", "--is-ancestor").AddDynamicArguments(that, this).RunStdString(c.repo.Ctx, &RunOpts{Dir: c.repo.Path}) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		return true, nil | 		return true, nil | ||||||
| 	} | 	} | ||||||
| @@ -358,12 +358,12 @@ func (c *Commit) GetFileContent(filename string, limit int) (string, error) { | |||||||
|  |  | ||||||
| // GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only') | // GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only') | ||||||
| func (c *Commit) GetBranchName() (string, error) { | func (c *Commit) GetBranchName() (string, error) { | ||||||
| 	cmd := NewCommand(c.repo.Ctx, "name-rev") | 	cmd := NewCommand("name-rev") | ||||||
| 	if DefaultFeatures().CheckVersionAtLeast("2.13.0") { | 	if DefaultFeatures().CheckVersionAtLeast("2.13.0") { | ||||||
| 		cmd.AddArguments("--exclude", "refs/tags/*") | 		cmd.AddArguments("--exclude", "refs/tags/*") | ||||||
| 	} | 	} | ||||||
| 	cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String()) | 	cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String()) | ||||||
| 	data, _, err := cmd.RunStdString(&RunOpts{Dir: c.repo.Path}) | 	data, _, err := cmd.RunStdString(c.repo.Ctx, &RunOpts{Dir: c.repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		// handle special case where git can not describe commit | 		// handle special case where git can not describe commit | ||||||
| 		if strings.Contains(err.Error(), "cannot describe") { | 		if strings.Contains(err.Error(), "cannot describe") { | ||||||
| @@ -441,7 +441,7 @@ func GetCommitFileStatus(ctx context.Context, repoPath, commitID string) (*Commi | |||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	err := NewCommand(ctx, "log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1").AddDynamicArguments(commitID).Run(&RunOpts{ | 	err := NewCommand("log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1").AddDynamicArguments(commitID).Run(ctx, &RunOpts{ | ||||||
| 		Dir:    repoPath, | 		Dir:    repoPath, | ||||||
| 		Stdout: w, | 		Stdout: w, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
| @@ -457,7 +457,7 @@ func GetCommitFileStatus(ctx context.Context, repoPath, commitID string) (*Commi | |||||||
|  |  | ||||||
| // GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository. | // GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository. | ||||||
| func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) { | func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) { | ||||||
| 	commitID, _, err := NewCommand(ctx, "rev-parse").AddDynamicArguments(shortID).RunStdString(&RunOpts{Dir: repoPath}) | 	commitID, _, err := NewCommand("rev-parse").AddDynamicArguments(shortID).RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if strings.Contains(err.Error(), "exit status 128") { | 		if strings.Contains(err.Error(), "exit status 128") { | ||||||
| 			return "", ErrNotExist{shortID, ""} | 			return "", ErrNotExist{shortID, ""} | ||||||
|   | |||||||
| @@ -116,7 +116,7 @@ func syncGitConfig() (err error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func configSet(key, value string) error { | func configSet(key, value string) error { | ||||||
| 	stdout, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil) | 	stdout, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil) | ||||||
| 	if err != nil && !IsErrorExitCode(err, 1) { | 	if err != nil && !IsErrorExitCode(err, 1) { | ||||||
| 		return fmt.Errorf("failed to get git config %s, err: %w", key, err) | 		return fmt.Errorf("failed to get git config %s, err: %w", key, err) | ||||||
| 	} | 	} | ||||||
| @@ -126,7 +126,7 @@ func configSet(key, value string) error { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, _, err = NewCommand(DefaultContext, "config", "--global").AddDynamicArguments(key, value).RunStdString(nil) | 	_, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("failed to set git global config %s, err: %w", key, err) | 		return fmt.Errorf("failed to set git global config %s, err: %w", key, err) | ||||||
| 	} | 	} | ||||||
| @@ -135,14 +135,14 @@ func configSet(key, value string) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func configSetNonExist(key, value string) error { | func configSetNonExist(key, value string) error { | ||||||
| 	_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil) | 	_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		// already exist | 		// already exist | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	if IsErrorExitCode(err, 1) { | 	if IsErrorExitCode(err, 1) { | ||||||
| 		// not exist, set new config | 		// not exist, set new config | ||||||
| 		_, _, err = NewCommand(DefaultContext, "config", "--global").AddDynamicArguments(key, value).RunStdString(nil) | 		_, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("failed to set git global config %s, err: %w", key, err) | 			return fmt.Errorf("failed to set git global config %s, err: %w", key, err) | ||||||
| 		} | 		} | ||||||
| @@ -153,14 +153,14 @@ func configSetNonExist(key, value string) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func configAddNonExist(key, value string) error { | func configAddNonExist(key, value string) error { | ||||||
| 	_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil) | 	_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(DefaultContext, nil) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		// already exist | 		// already exist | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	if IsErrorExitCode(err, 1) { | 	if IsErrorExitCode(err, 1) { | ||||||
| 		// not exist, add new config | 		// not exist, add new config | ||||||
| 		_, _, err = NewCommand(DefaultContext, "config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(nil) | 		_, _, err = NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("failed to add git global config %s, err: %w", key, err) | 			return fmt.Errorf("failed to add git global config %s, err: %w", key, err) | ||||||
| 		} | 		} | ||||||
| @@ -170,10 +170,10 @@ func configAddNonExist(key, value string) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func configUnsetAll(key, value string) error { | func configUnsetAll(key, value string) error { | ||||||
| 	_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil) | 	_, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		// exist, need to remove | 		// exist, need to remove | ||||||
| 		_, _, err = NewCommand(DefaultContext, "config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil) | 		_, _, err = NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(DefaultContext, nil) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("failed to unset git global config %s, err: %w", key, err) | 			return fmt.Errorf("failed to unset git global config %s, err: %w", key, err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -34,8 +34,8 @@ func GetRawDiff(repo *Repository, commitID string, diffType RawDiffType, writer | |||||||
| // GetReverseRawDiff dumps the reverse diff results of repository in given commit ID to io.Writer. | // GetReverseRawDiff dumps the reverse diff results of repository in given commit ID to io.Writer. | ||||||
| func GetReverseRawDiff(ctx context.Context, repoPath, commitID string, writer io.Writer) error { | func GetReverseRawDiff(ctx context.Context, repoPath, commitID string, writer io.Writer) error { | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	cmd := NewCommand(ctx, "show", "--pretty=format:revert %H%n", "-R").AddDynamicArguments(commitID) | 	cmd := NewCommand("show", "--pretty=format:revert %H%n", "-R").AddDynamicArguments(commitID) | ||||||
| 	if err := cmd.Run(&RunOpts{ | 	if err := cmd.Run(ctx, &RunOpts{ | ||||||
| 		Dir:    repoPath, | 		Dir:    repoPath, | ||||||
| 		Stdout: writer, | 		Stdout: writer, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
| @@ -56,7 +56,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff | |||||||
| 		files = append(files, file) | 		files = append(files, file) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := NewCommand(repo.Ctx) | 	cmd := NewCommand() | ||||||
| 	switch diffType { | 	switch diffType { | ||||||
| 	case RawDiffNormal: | 	case RawDiffNormal: | ||||||
| 		if len(startCommit) != 0 { | 		if len(startCommit) != 0 { | ||||||
| @@ -89,7 +89,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	if err = cmd.Run(&RunOpts{ | 	if err = cmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: writer, | 		Stdout: writer, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
| @@ -301,8 +301,8 @@ func GetAffectedFiles(repo *Repository, branchName, oldCommitID, newCommitID str | |||||||
| 	affectedFiles := make([]string, 0, 32) | 	affectedFiles := make([]string, 0, 32) | ||||||
|  |  | ||||||
| 	// Run `git diff --name-only` to get the names of the changed files | 	// Run `git diff --name-only` to get the names of the changed files | ||||||
| 	err = NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID). | 	err = NewCommand("diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID). | ||||||
| 		Run(&RunOpts{ | 		Run(repo.Ctx, &RunOpts{ | ||||||
| 			Env:    env, | 			Env:    env, | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: stdoutWriter, | 			Stdout: stdoutWriter, | ||||||
|   | |||||||
| @@ -10,5 +10,5 @@ import ( | |||||||
|  |  | ||||||
| // Fsck verifies the connectivity and validity of the objects in the database | // Fsck verifies the connectivity and validity of the objects in the database | ||||||
| func Fsck(ctx context.Context, repoPath string, timeout time.Duration, args TrustedCmdArgs) error { | func Fsck(ctx context.Context, repoPath string, timeout time.Duration, args TrustedCmdArgs) error { | ||||||
| 	return NewCommand(ctx, "fsck").AddArguments(args...).Run(&RunOpts{Timeout: timeout, Dir: repoPath}) | 	return NewCommand("fsck").AddArguments(args...).Run(ctx, &RunOpts{Timeout: timeout, Dir: repoPath}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -60,7 +60,7 @@ func DefaultFeatures() *Features { | |||||||
| } | } | ||||||
|  |  | ||||||
| func loadGitVersionFeatures() (*Features, error) { | func loadGitVersionFeatures() (*Features, error) { | ||||||
| 	stdout, _, runErr := NewCommand(DefaultContext, "version").RunStdString(nil) | 	stdout, _, runErr := NewCommand("version").RunStdString(DefaultContext, nil) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO | |||||||
| 	 2^@repo: go-gitea/gitea | 	 2^@repo: go-gitea/gitea | ||||||
| 	*/ | 	*/ | ||||||
| 	var results []*GrepResult | 	var results []*GrepResult | ||||||
| 	cmd := NewCommand(ctx, "grep", "--null", "--break", "--heading", "--fixed-strings", "--line-number", "--ignore-case", "--full-name") | 	cmd := NewCommand("grep", "--null", "--break", "--heading", "--fixed-strings", "--line-number", "--ignore-case", "--full-name") | ||||||
| 	cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber)) | 	cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber)) | ||||||
| 	if opts.IsFuzzy { | 	if opts.IsFuzzy { | ||||||
| 		words := strings.Fields(search) | 		words := strings.Fields(search) | ||||||
| @@ -66,7 +66,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO | |||||||
| 	cmd.AddDashesAndList(opts.PathspecList...) | 	cmd.AddDashesAndList(opts.PathspecList...) | ||||||
| 	opts.MaxResultLimit = util.IfZero(opts.MaxResultLimit, 50) | 	opts.MaxResultLimit = util.IfZero(opts.MaxResultLimit, 50) | ||||||
| 	stderr := bytes.Buffer{} | 	stderr := bytes.Buffer{} | ||||||
| 	err = cmd.Run(&RunOpts{ | 	err = cmd.Run(ctx, &RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: stdoutWriter, | 		Stdout: stdoutWriter, | ||||||
| 		Stderr: &stderr, | 		Stderr: &stderr, | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ func LogNameStatusRepo(ctx context.Context, repository, head, treepath string, p | |||||||
| 		_ = stdoutWriter.Close() | 		_ = stdoutWriter.Close() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := NewCommand(ctx) | 	cmd := NewCommand() | ||||||
| 	cmd.AddArguments("log", "--name-status", "-c", "--format=commit%x00%H %P%x00", "--parents", "--no-renames", "-t", "-z").AddDynamicArguments(head) | 	cmd.AddArguments("log", "--name-status", "-c", "--format=commit%x00%H %P%x00", "--parents", "--no-renames", "-t", "-z").AddDynamicArguments(head) | ||||||
|  |  | ||||||
| 	var files []string | 	var files []string | ||||||
| @@ -64,7 +64,7 @@ func LogNameStatusRepo(ctx context.Context, repository, head, treepath string, p | |||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		stderr := strings.Builder{} | 		stderr := strings.Builder{} | ||||||
| 		err := cmd.Run(&RunOpts{ | 		err := cmd.Run(ctx, &RunOpts{ | ||||||
| 			Dir:    repository, | 			Dir:    repository, | ||||||
| 			Stdout: stdoutWriter, | 			Stdout: stdoutWriter, | ||||||
| 			Stderr: &stderr, | 			Stderr: &stderr, | ||||||
|   | |||||||
| @@ -25,8 +25,8 @@ func CatFileBatchCheck(ctx context.Context, shasToCheckReader *io.PipeReader, ca | |||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	var errbuf strings.Builder | 	var errbuf strings.Builder | ||||||
| 	cmd := git.NewCommand(ctx, "cat-file", "--batch-check") | 	cmd := git.NewCommand("cat-file", "--batch-check") | ||||||
| 	if err := cmd.Run(&git.RunOpts{ | 	if err := cmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    tmpBasePath, | 		Dir:    tmpBasePath, | ||||||
| 		Stdin:  shasToCheckReader, | 		Stdin:  shasToCheckReader, | ||||||
| 		Stdout: catFileCheckWriter, | 		Stdout: catFileCheckWriter, | ||||||
| @@ -43,8 +43,8 @@ func CatFileBatchCheckAllObjects(ctx context.Context, catFileCheckWriter *io.Pip | |||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	var errbuf strings.Builder | 	var errbuf strings.Builder | ||||||
| 	cmd := git.NewCommand(ctx, "cat-file", "--batch-check", "--batch-all-objects") | 	cmd := git.NewCommand("cat-file", "--batch-check", "--batch-all-objects") | ||||||
| 	if err := cmd.Run(&git.RunOpts{ | 	if err := cmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    tmpBasePath, | 		Dir:    tmpBasePath, | ||||||
| 		Stdout: catFileCheckWriter, | 		Stdout: catFileCheckWriter, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
| @@ -64,7 +64,7 @@ func CatFileBatch(ctx context.Context, shasToBatchReader *io.PipeReader, catFile | |||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	var errbuf strings.Builder | 	var errbuf strings.Builder | ||||||
| 	if err := git.NewCommand(ctx, "cat-file", "--batch").Run(&git.RunOpts{ | 	if err := git.NewCommand("cat-file", "--batch").Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    tmpBasePath, | 		Dir:    tmpBasePath, | ||||||
| 		Stdout: catFileBatchWriter, | 		Stdout: catFileBatchWriter, | ||||||
| 		Stdin:  shasToBatchReader, | 		Stdin:  shasToBatchReader, | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err | |||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		stderr := strings.Builder{} | 		stderr := strings.Builder{} | ||||||
| 		err := git.NewCommand(repo.Ctx, "rev-list", "--all").Run(&git.RunOpts{ | 		err := git.NewCommand("rev-list", "--all").Run(repo.Ctx, &git.RunOpts{ | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: revListWriter, | 			Stdout: revListWriter, | ||||||
| 			Stderr: &stderr, | 			Stderr: &stderr, | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ func NameRevStdin(ctx context.Context, shasToNameReader *io.PipeReader, nameRevS | |||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	var errbuf strings.Builder | 	var errbuf strings.Builder | ||||||
| 	if err := git.NewCommand(ctx, "name-rev", "--stdin", "--name-only", "--always").Run(&git.RunOpts{ | 	if err := git.NewCommand("name-rev", "--stdin", "--name-only", "--always").Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    tmpBasePath, | 		Dir:    tmpBasePath, | ||||||
| 		Stdout: nameRevStdinWriter, | 		Stdout: nameRevStdinWriter, | ||||||
| 		Stdin:  shasToNameReader, | 		Stdin:  shasToNameReader, | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ func RevListAllObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sy | |||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	var errbuf strings.Builder | 	var errbuf strings.Builder | ||||||
| 	cmd := git.NewCommand(ctx, "rev-list", "--objects", "--all") | 	cmd := git.NewCommand("rev-list", "--objects", "--all") | ||||||
| 	if err := cmd.Run(&git.RunOpts{ | 	if err := cmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    basePath, | 		Dir:    basePath, | ||||||
| 		Stdout: revListWriter, | 		Stdout: revListWriter, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
| @@ -42,11 +42,11 @@ func RevListObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync. | |||||||
| 	defer revListWriter.Close() | 	defer revListWriter.Close() | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	var errbuf strings.Builder | 	var errbuf strings.Builder | ||||||
| 	cmd := git.NewCommand(ctx, "rev-list", "--objects").AddDynamicArguments(headSHA) | 	cmd := git.NewCommand("rev-list", "--objects").AddDynamicArguments(headSHA) | ||||||
| 	if baseSHA != "" { | 	if baseSHA != "" { | ||||||
| 		cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA) | 		cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA) | ||||||
| 	} | 	} | ||||||
| 	if err := cmd.Run(&git.RunOpts{ | 	if err := cmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    tmpBasePath, | 		Dir:    tmpBasePath, | ||||||
| 		Stdout: revListWriter, | 		Stdout: revListWriter, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
|   | |||||||
| @@ -17,12 +17,12 @@ import ( | |||||||
| func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, error) { | func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, error) { | ||||||
| 	var cmd *Command | 	var cmd *Command | ||||||
| 	if DefaultFeatures().CheckVersionAtLeast("2.7") { | 	if DefaultFeatures().CheckVersionAtLeast("2.7") { | ||||||
| 		cmd = NewCommand(ctx, "remote", "get-url").AddDynamicArguments(remoteName) | 		cmd = NewCommand("remote", "get-url").AddDynamicArguments(remoteName) | ||||||
| 	} else { | 	} else { | ||||||
| 		cmd = NewCommand(ctx, "config", "--get").AddDynamicArguments("remote." + remoteName + ".url") | 		cmd = NewCommand("config", "--get").AddDynamicArguments("remote." + remoteName + ".url") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	result, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ func (repo *Repository) parsePrettyFormatLogToList(logs []byte) ([]*Commit, erro | |||||||
|  |  | ||||||
| // IsRepoURLAccessible checks if given repository URL is accessible. | // IsRepoURLAccessible checks if given repository URL is accessible. | ||||||
| func IsRepoURLAccessible(ctx context.Context, url string) bool { | func IsRepoURLAccessible(ctx context.Context, url string) bool { | ||||||
| 	_, _, err := NewCommand(ctx, "ls-remote", "-q", "-h").AddDynamicArguments(url, "HEAD").RunStdString(nil) | 	_, _, err := NewCommand("ls-remote", "-q", "-h").AddDynamicArguments(url, "HEAD").RunStdString(ctx, nil) | ||||||
| 	return err == nil | 	return err == nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -68,7 +68,7 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := NewCommand(ctx, "init") | 	cmd := NewCommand("init") | ||||||
|  |  | ||||||
| 	if !IsValidObjectFormat(objectFormatName) { | 	if !IsValidObjectFormat(objectFormatName) { | ||||||
| 		return fmt.Errorf("invalid object format: %s", objectFormatName) | 		return fmt.Errorf("invalid object format: %s", objectFormatName) | ||||||
| @@ -80,15 +80,15 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma | |||||||
| 	if bare { | 	if bare { | ||||||
| 		cmd.AddArguments("--bare") | 		cmd.AddArguments("--bare") | ||||||
| 	} | 	} | ||||||
| 	_, _, err = cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	_, _, err = cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // IsEmpty Check if repository is empty. | // IsEmpty Check if repository is empty. | ||||||
| func (repo *Repository) IsEmpty() (bool, error) { | func (repo *Repository) IsEmpty() (bool, error) { | ||||||
| 	var errbuf, output strings.Builder | 	var errbuf, output strings.Builder | ||||||
| 	if err := NewCommand(repo.Ctx).AddOptionFormat("--git-dir=%s", repo.Path).AddArguments("rev-list", "-n", "1", "--all"). | 	if err := NewCommand().AddOptionFormat("--git-dir=%s", repo.Path).AddArguments("rev-list", "-n", "1", "--all"). | ||||||
| 		Run(&RunOpts{ | 		Run(repo.Ctx, &RunOpts{ | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: &output, | 			Stdout: &output, | ||||||
| 			Stderr: &errbuf, | 			Stderr: &errbuf, | ||||||
| @@ -129,7 +129,7 @@ func CloneWithArgs(ctx context.Context, args TrustedCmdArgs, from, to string, op | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := NewCommandContextNoGlobals(ctx, args...).AddArguments("clone") | 	cmd := NewCommandNoGlobals(args...).AddArguments("clone") | ||||||
| 	if opts.SkipTLSVerify { | 	if opts.SkipTLSVerify { | ||||||
| 		cmd.AddArguments("-c", "http.sslVerify=false") | 		cmd.AddArguments("-c", "http.sslVerify=false") | ||||||
| 	} | 	} | ||||||
| @@ -170,7 +170,7 @@ func CloneWithArgs(ctx context.Context, args TrustedCmdArgs, from, to string, op | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	if err = cmd.Run(&RunOpts{ | 	if err = cmd.Run(ctx, &RunOpts{ | ||||||
| 		Timeout: opts.Timeout, | 		Timeout: opts.Timeout, | ||||||
| 		Env:     envs, | 		Env:     envs, | ||||||
| 		Stdout:  io.Discard, | 		Stdout:  io.Discard, | ||||||
| @@ -193,7 +193,7 @@ type PushOptions struct { | |||||||
|  |  | ||||||
| // Push pushs local commits to given remote branch. | // Push pushs local commits to given remote branch. | ||||||
| func Push(ctx context.Context, repoPath string, opts PushOptions) error { | func Push(ctx context.Context, repoPath string, opts PushOptions) error { | ||||||
| 	cmd := NewCommand(ctx, "push") | 	cmd := NewCommand("push") | ||||||
| 	if opts.Force { | 	if opts.Force { | ||||||
| 		cmd.AddArguments("-f") | 		cmd.AddArguments("-f") | ||||||
| 	} | 	} | ||||||
| @@ -206,7 +206,7 @@ func Push(ctx context.Context, repoPath string, opts PushOptions) error { | |||||||
| 	} | 	} | ||||||
| 	cmd.AddDashesAndList(remoteBranchArgs...) | 	cmd.AddDashesAndList(remoteBranchArgs...) | ||||||
|  |  | ||||||
| 	stdout, stderr, err := cmd.RunStdString(&RunOpts{Env: opts.Env, Timeout: opts.Timeout, Dir: repoPath}) | 	stdout, stderr, err := cmd.RunStdString(ctx, &RunOpts{Env: opts.Env, Timeout: opts.Timeout, Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if strings.Contains(stderr, "non-fast-forward") { | 		if strings.Contains(stderr, "non-fast-forward") { | ||||||
| 			return &ErrPushOutOfDate{StdOut: stdout, StdErr: stderr, Err: err} | 			return &ErrPushOutOfDate{StdOut: stdout, StdErr: stderr, Err: err} | ||||||
| @@ -225,8 +225,8 @@ func Push(ctx context.Context, repoPath string, opts PushOptions) error { | |||||||
|  |  | ||||||
| // GetLatestCommitTime returns time for latest commit in repository (across all branches) | // GetLatestCommitTime returns time for latest commit in repository (across all branches) | ||||||
| func GetLatestCommitTime(ctx context.Context, repoPath string) (time.Time, error) { | func GetLatestCommitTime(ctx context.Context, repoPath string) (time.Time, error) { | ||||||
| 	cmd := NewCommand(ctx, "for-each-ref", "--sort=-committerdate", BranchPrefix, "--count", "1", "--format=%(committerdate)") | 	cmd := NewCommand("for-each-ref", "--sort=-committerdate", BranchPrefix, "--count", "1", "--format=%(committerdate)") | ||||||
| 	stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return time.Time{}, err | 		return time.Time{}, err | ||||||
| 	} | 	} | ||||||
| @@ -242,9 +242,9 @@ type DivergeObject struct { | |||||||
|  |  | ||||||
| // GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch | // GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch | ||||||
| func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch string) (do DivergeObject, err error) { | func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch string) (do DivergeObject, err error) { | ||||||
| 	cmd := NewCommand(ctx, "rev-list", "--count", "--left-right"). | 	cmd := NewCommand("rev-list", "--count", "--left-right"). | ||||||
| 		AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--") | 		AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--") | ||||||
| 	stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return do, err | 		return do, err | ||||||
| 	} | 	} | ||||||
| @@ -273,23 +273,23 @@ func (repo *Repository) CreateBundle(ctx context.Context, commit string, out io. | |||||||
| 	defer os.RemoveAll(tmp) | 	defer os.RemoveAll(tmp) | ||||||
|  |  | ||||||
| 	env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repo.Path, "objects")) | 	env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repo.Path, "objects")) | ||||||
| 	_, _, err = NewCommand(ctx, "init", "--bare").RunStdString(&RunOpts{Dir: tmp, Env: env}) | 	_, _, err = NewCommand("init", "--bare").RunStdString(ctx, &RunOpts{Dir: tmp, Env: env}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, _, err = NewCommand(ctx, "reset", "--soft").AddDynamicArguments(commit).RunStdString(&RunOpts{Dir: tmp, Env: env}) | 	_, _, err = NewCommand("reset", "--soft").AddDynamicArguments(commit).RunStdString(ctx, &RunOpts{Dir: tmp, Env: env}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, _, err = NewCommand(ctx, "branch", "-m", "bundle").RunStdString(&RunOpts{Dir: tmp, Env: env}) | 	_, _, err = NewCommand("branch", "-m", "bundle").RunStdString(ctx, &RunOpts{Dir: tmp, Env: env}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tmpFile := filepath.Join(tmp, "bundle") | 	tmpFile := filepath.Join(tmp, "bundle") | ||||||
| 	_, _, err = NewCommand(ctx, "bundle", "create").AddDynamicArguments(tmpFile, "bundle", "HEAD").RunStdString(&RunOpts{Dir: tmp, Env: env}) | 	_, _, err = NewCommand("bundle", "create").AddDynamicArguments(tmpFile, "bundle", "HEAD").RunStdString(ctx, &RunOpts{Dir: tmp, Env: env}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ func (repo *Repository) CreateArchive(ctx context.Context, format ArchiveType, t | |||||||
| 		return fmt.Errorf("unknown format: %v", format) | 		return fmt.Errorf("unknown format: %v", format) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := NewCommand(ctx, "archive") | 	cmd := NewCommand("archive") | ||||||
| 	if usePrefix { | 	if usePrefix { | ||||||
| 		cmd.AddOptionFormat("--prefix=%s", filepath.Base(strings.TrimSuffix(repo.Path, ".git"))+"/") | 		cmd.AddOptionFormat("--prefix=%s", filepath.Base(strings.TrimSuffix(repo.Path, ".git"))+"/") | ||||||
| 	} | 	} | ||||||
| @@ -61,7 +61,7 @@ func (repo *Repository) CreateArchive(ctx context.Context, format ArchiveType, t | |||||||
| 	cmd.AddDynamicArguments(commitID) | 	cmd.AddDynamicArguments(commitID) | ||||||
|  |  | ||||||
| 	var stderr strings.Builder | 	var stderr strings.Builder | ||||||
| 	err := cmd.Run(&RunOpts{ | 	err := cmd.Run(ctx, &RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: target, | 		Stdout: target, | ||||||
| 		Stderr: &stderr, | 		Stderr: &stderr, | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[ | |||||||
| 	stdOut := new(bytes.Buffer) | 	stdOut := new(bytes.Buffer) | ||||||
| 	stdErr := new(bytes.Buffer) | 	stdErr := new(bytes.Buffer) | ||||||
|  |  | ||||||
| 	cmd := NewCommand(repo.Ctx, "check-attr", "-z") | 	cmd := NewCommand("check-attr", "-z") | ||||||
|  |  | ||||||
| 	if opts.AllAttributes { | 	if opts.AllAttributes { | ||||||
| 		cmd.AddArguments("-a") | 		cmd.AddArguments("-a") | ||||||
| @@ -59,7 +59,7 @@ func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[ | |||||||
|  |  | ||||||
| 	cmd.AddDashesAndList(opts.Filenames...) | 	cmd.AddDashesAndList(opts.Filenames...) | ||||||
|  |  | ||||||
| 	if err := cmd.Run(&RunOpts{ | 	if err := cmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 		Env:    env, | 		Env:    env, | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: stdOut, | 		Stdout: stdOut, | ||||||
| @@ -122,7 +122,7 @@ func (c *CheckAttributeReader) Init(ctx context.Context) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	c.ctx, c.cancel = context.WithCancel(ctx) | 	c.ctx, c.cancel = context.WithCancel(ctx) | ||||||
| 	c.cmd = NewCommand(c.ctx, "check-attr", "--stdin", "-z") | 	c.cmd = NewCommand("check-attr", "--stdin", "-z") | ||||||
|  |  | ||||||
| 	if len(c.IndexFile) > 0 { | 	if len(c.IndexFile) > 0 { | ||||||
| 		c.cmd.AddArguments("--cached") | 		c.cmd.AddArguments("--cached") | ||||||
| @@ -159,7 +159,7 @@ func (c *CheckAttributeReader) Run() error { | |||||||
| 		_ = c.stdOut.Close() | 		_ = c.stdOut.Close() | ||||||
| 	}() | 	}() | ||||||
| 	stdErr := new(bytes.Buffer) | 	stdErr := new(bytes.Buffer) | ||||||
| 	err := c.cmd.Run(&RunOpts{ | 	err := c.cmd.Run(c.ctx, &RunOpts{ | ||||||
| 		Env:    c.env, | 		Env:    c.env, | ||||||
| 		Dir:    c.Repo.Path, | 		Dir:    c.Repo.Path, | ||||||
| 		Stdin:  c.stdinReader, | 		Stdin:  c.stdinReader, | ||||||
|   | |||||||
| @@ -9,10 +9,10 @@ import ( | |||||||
|  |  | ||||||
| // LineBlame returns the latest commit at the given line | // LineBlame returns the latest commit at the given line | ||||||
| func (repo *Repository) LineBlame(revision, path, file string, line uint) (*Commit, error) { | func (repo *Repository) LineBlame(revision, path, file string, line uint) (*Commit, error) { | ||||||
| 	res, _, err := NewCommand(repo.Ctx, "blame"). | 	res, _, err := NewCommand("blame"). | ||||||
| 		AddOptionFormat("-L %d,%d", line, line). | 		AddOptionFormat("-L %d,%d", line, line). | ||||||
| 		AddOptionValues("-p", revision). | 		AddOptionValues("-p", revision). | ||||||
| 		AddDashesAndList(file).RunStdString(&RunOpts{Dir: path}) | 		AddDashesAndList(file).RunStdString(repo.Ctx, &RunOpts{Dir: path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ const BranchPrefix = "refs/heads/" | |||||||
|  |  | ||||||
| // IsReferenceExist returns true if given reference exists in the repository. | // IsReferenceExist returns true if given reference exists in the repository. | ||||||
| func IsReferenceExist(ctx context.Context, repoPath, name string) bool { | func IsReferenceExist(ctx context.Context, repoPath, name string) bool { | ||||||
| 	_, _, err := NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repoPath}) | 	_, _, err := NewCommand("show-ref", "--verify").AddDashesAndList(name).RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	return err == nil | 	return err == nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -38,7 +38,7 @@ func (repo *Repository) GetHEADBranch() (*Branch, error) { | |||||||
| 	if repo == nil { | 	if repo == nil { | ||||||
| 		return nil, fmt.Errorf("nil repo") | 		return nil, fmt.Errorf("nil repo") | ||||||
| 	} | 	} | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "symbolic-ref", "HEAD").RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("symbolic-ref", "HEAD").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -56,7 +56,7 @@ func (repo *Repository) GetHEADBranch() (*Branch, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func GetDefaultBranch(ctx context.Context, repoPath string) (string, error) { | func GetDefaultBranch(ctx context.Context, repoPath string) (string, error) { | ||||||
| 	stdout, _, err := NewCommand(ctx, "symbolic-ref", "HEAD").RunStdString(&RunOpts{Dir: repoPath}) | 	stdout, _, err := NewCommand("symbolic-ref", "HEAD").RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -105,7 +105,7 @@ type DeleteBranchOptions struct { | |||||||
|  |  | ||||||
| // DeleteBranch delete a branch by name on repository. | // DeleteBranch delete a branch by name on repository. | ||||||
| func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) error { | func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) error { | ||||||
| 	cmd := NewCommand(repo.Ctx, "branch") | 	cmd := NewCommand("branch") | ||||||
|  |  | ||||||
| 	if opts.Force { | 	if opts.Force { | ||||||
| 		cmd.AddArguments("-D") | 		cmd.AddArguments("-D") | ||||||
| @@ -114,36 +114,36 @@ func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) erro | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd.AddDashesAndList(name) | 	cmd.AddDashesAndList(name) | ||||||
| 	_, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := cmd.RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
|  |  | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // CreateBranch create a new branch | // CreateBranch create a new branch | ||||||
| func (repo *Repository) CreateBranch(branch, oldbranchOrCommit string) error { | func (repo *Repository) CreateBranch(branch, oldbranchOrCommit string) error { | ||||||
| 	cmd := NewCommand(repo.Ctx, "branch") | 	cmd := NewCommand("branch") | ||||||
| 	cmd.AddDashesAndList(branch, oldbranchOrCommit) | 	cmd.AddDashesAndList(branch, oldbranchOrCommit) | ||||||
|  |  | ||||||
| 	_, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := cmd.RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
|  |  | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddRemote adds a new remote to repository. | // AddRemote adds a new remote to repository. | ||||||
| func (repo *Repository) AddRemote(name, url string, fetch bool) error { | func (repo *Repository) AddRemote(name, url string, fetch bool) error { | ||||||
| 	cmd := NewCommand(repo.Ctx, "remote", "add") | 	cmd := NewCommand("remote", "add") | ||||||
| 	if fetch { | 	if fetch { | ||||||
| 		cmd.AddArguments("-f") | 		cmd.AddArguments("-f") | ||||||
| 	} | 	} | ||||||
| 	cmd.AddDynamicArguments(name, url) | 	cmd.AddDynamicArguments(name, url) | ||||||
|  |  | ||||||
| 	_, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := cmd.RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // RemoveRemote removes a remote from repository. | // RemoveRemote removes a remote from repository. | ||||||
| func (repo *Repository) RemoveRemote(name string) error { | func (repo *Repository) RemoveRemote(name string) error { | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "remote", "rm").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("remote", "rm").AddDynamicArguments(name).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -154,6 +154,6 @@ func (branch *Branch) GetCommit() (*Commit, error) { | |||||||
|  |  | ||||||
| // RenameBranch rename a branch | // RenameBranch rename a branch | ||||||
| func (repo *Repository) RenameBranch(from, to string) error { | func (repo *Repository) RenameBranch(from, to string) error { | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "branch", "-m").AddDynamicArguments(from, to).RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("branch", "-m").AddDynamicArguments(from, to).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|   | |||||||
| @@ -109,7 +109,7 @@ func WalkShowRef(ctx context.Context, repoPath string, extraArgs TrustedCmdArgs, | |||||||
| 		stderrBuilder := &strings.Builder{} | 		stderrBuilder := &strings.Builder{} | ||||||
| 		args := TrustedCmdArgs{"for-each-ref", "--format=%(objectname) %(refname)"} | 		args := TrustedCmdArgs{"for-each-ref", "--format=%(objectname) %(refname)"} | ||||||
| 		args = append(args, extraArgs...) | 		args = append(args, extraArgs...) | ||||||
| 		err := NewCommand(ctx, args...).Run(&RunOpts{ | 		err := NewCommand(args...).Run(ctx, &RunOpts{ | ||||||
| 			Dir:    repoPath, | 			Dir:    repoPath, | ||||||
| 			Stdout: stdoutWriter, | 			Stdout: stdoutWriter, | ||||||
| 			Stderr: stderrBuilder, | 			Stderr: stderrBuilder, | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com | |||||||
| 		relpath = `\` + relpath | 		relpath = `\` + relpath | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, runErr := NewCommand(repo.Ctx, "log", "-1", prettyLogFormat).AddDynamicArguments(id.String()).AddDashesAndList(relpath).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, runErr := NewCommand("log", "-1", prettyLogFormat).AddDynamicArguments(id.String()).AddDashesAndList(relpath).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
| @@ -74,7 +74,7 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com | |||||||
|  |  | ||||||
| // GetCommitByPath returns the last commit of relative path. | // GetCommitByPath returns the last commit of relative path. | ||||||
| func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) { | func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) { | ||||||
| 	stdout, _, runErr := NewCommand(repo.Ctx, "log", "-1", prettyLogFormat).AddDashesAndList(relpath).RunStdBytes(&RunOpts{Dir: repo.Path}) | 	stdout, _, runErr := NewCommand("log", "-1", prettyLogFormat).AddDashesAndList(relpath).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
| @@ -90,7 +90,7 @@ func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (repo *Repository) commitsByRange(id ObjectID, page, pageSize int, not string) ([]*Commit, error) { | func (repo *Repository) commitsByRange(id ObjectID, page, pageSize int, not string) ([]*Commit, error) { | ||||||
| 	cmd := NewCommand(repo.Ctx, "log"). | 	cmd := NewCommand("log"). | ||||||
| 		AddOptionFormat("--skip=%d", (page-1)*pageSize). | 		AddOptionFormat("--skip=%d", (page-1)*pageSize). | ||||||
| 		AddOptionFormat("--max-count=%d", pageSize). | 		AddOptionFormat("--max-count=%d", pageSize). | ||||||
| 		AddArguments(prettyLogFormat). | 		AddArguments(prettyLogFormat). | ||||||
| @@ -100,7 +100,7 @@ func (repo *Repository) commitsByRange(id ObjectID, page, pageSize int, not stri | |||||||
| 		cmd.AddOptionValues("--not", not) | 		cmd.AddOptionValues("--not", not) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, err := cmd.RunStdBytes(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := cmd.RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -134,7 +134,7 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// create new git log command with limit of 100 commits | 	// create new git log command with limit of 100 commits | ||||||
| 	cmd := NewCommand(repo.Ctx, "log", "-100", prettyLogFormat).AddDynamicArguments(id.String()) | 	cmd := NewCommand("log", "-100", prettyLogFormat).AddDynamicArguments(id.String()) | ||||||
|  |  | ||||||
| 	// pretend that all refs along with HEAD were listed on command line as <commis> | 	// pretend that all refs along with HEAD were listed on command line as <commis> | ||||||
| 	// https://git-scm.com/docs/git-log#Documentation/git-log.txt---all | 	// https://git-scm.com/docs/git-log#Documentation/git-log.txt---all | ||||||
| @@ -154,7 +154,7 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([ | |||||||
|  |  | ||||||
| 	// search for commits matching given constraints and keywords in commit msg | 	// search for commits matching given constraints and keywords in commit msg | ||||||
| 	addCommonSearchArgs(cmd) | 	addCommonSearchArgs(cmd) | ||||||
| 	stdout, _, err := cmd.RunStdBytes(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := cmd.RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -168,14 +168,14 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([ | |||||||
| 		// ignore anything not matching a valid sha pattern | 		// ignore anything not matching a valid sha pattern | ||||||
| 		if id.Type().IsValid(v) { | 		if id.Type().IsValid(v) { | ||||||
| 			// create new git log command with 1 commit limit | 			// create new git log command with 1 commit limit | ||||||
| 			hashCmd := NewCommand(repo.Ctx, "log", "-1", prettyLogFormat) | 			hashCmd := NewCommand("log", "-1", prettyLogFormat) | ||||||
| 			// add previous arguments except for --grep and --all | 			// add previous arguments except for --grep and --all | ||||||
| 			addCommonSearchArgs(hashCmd) | 			addCommonSearchArgs(hashCmd) | ||||||
| 			// add keyword as <commit> | 			// add keyword as <commit> | ||||||
| 			hashCmd.AddDynamicArguments(v) | 			hashCmd.AddDynamicArguments(v) | ||||||
|  |  | ||||||
| 			// search with given constraints for commit matching sha hash of v | 			// search with given constraints for commit matching sha hash of v | ||||||
| 			hashMatching, _, err := hashCmd.RunStdBytes(&RunOpts{Dir: repo.Path}) | 			hashMatching, _, err := hashCmd.RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 			if err != nil || bytes.Contains(stdout, hashMatching) { | 			if err != nil || bytes.Contains(stdout, hashMatching) { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| @@ -190,7 +190,7 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([ | |||||||
| // FileChangedBetweenCommits Returns true if the file changed between commit IDs id1 and id2 | // FileChangedBetweenCommits Returns true if the file changed between commit IDs id1 and id2 | ||||||
| // You must ensure that id1 and id2 are valid commit ids. | // You must ensure that id1 and id2 are valid commit ids. | ||||||
| func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bool, error) { | func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bool, error) { | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(id1, id2).AddDashesAndList(filename).RunStdBytes(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("diff", "--name-only", "-z").AddDynamicArguments(id1, id2).AddDashesAndList(filename).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
| @@ -223,7 +223,7 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions) | |||||||
| 	}() | 	}() | ||||||
| 	go func() { | 	go func() { | ||||||
| 		stderr := strings.Builder{} | 		stderr := strings.Builder{} | ||||||
| 		gitCmd := NewCommand(repo.Ctx, "rev-list"). | 		gitCmd := NewCommand("rev-list"). | ||||||
| 			AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize). | 			AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize). | ||||||
| 			AddOptionFormat("--skip=%d", (opts.Page-1)*setting.Git.CommitsRangeSize) | 			AddOptionFormat("--skip=%d", (opts.Page-1)*setting.Git.CommitsRangeSize) | ||||||
| 		gitCmd.AddDynamicArguments(opts.Revision) | 		gitCmd.AddDynamicArguments(opts.Revision) | ||||||
| @@ -233,7 +233,7 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		gitCmd.AddDashesAndList(opts.File) | 		gitCmd.AddDashesAndList(opts.File) | ||||||
| 		err := gitCmd.Run(&RunOpts{ | 		err := gitCmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: stdoutWriter, | 			Stdout: stdoutWriter, | ||||||
| 			Stderr: &stderr, | 			Stderr: &stderr, | ||||||
| @@ -275,11 +275,11 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions) | |||||||
|  |  | ||||||
| // FilesCountBetween return the number of files changed between two commits | // FilesCountBetween return the number of files changed between two commits | ||||||
| func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) { | func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) { | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(startCommitID + "..." + endCommitID).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("diff", "--name-only").AddDynamicArguments(startCommitID+"..."+endCommitID).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil && strings.Contains(err.Error(), "no merge base") { | 	if err != nil && strings.Contains(err.Error(), "no merge base") { | ||||||
| 		// git >= 2.28 now returns an error if startCommitID and endCommitID have become unrelated. | 		// git >= 2.28 now returns an error if startCommitID and endCommitID have become unrelated. | ||||||
| 		// previously it would return the results of git diff --name-only startCommitID endCommitID so let's try that... | 		// previously it would return the results of git diff --name-only startCommitID endCommitID so let's try that... | ||||||
| 		stdout, _, err = NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(startCommitID, endCommitID).RunStdString(&RunOpts{Dir: repo.Path}) | 		stdout, _, err = NewCommand("diff", "--name-only").AddDynamicArguments(startCommitID, endCommitID).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, err | 		return 0, err | ||||||
| @@ -293,13 +293,13 @@ func (repo *Repository) CommitsBetween(last, before *Commit) ([]*Commit, error) | |||||||
| 	var stdout []byte | 	var stdout []byte | ||||||
| 	var err error | 	var err error | ||||||
| 	if before == nil { | 	if before == nil { | ||||||
| 		stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(last.ID.String()).RunStdBytes(&RunOpts{Dir: repo.Path}) | 		stdout, _, err = NewCommand("rev-list").AddDynamicArguments(last.ID.String()).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	} else { | 	} else { | ||||||
| 		stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(before.ID.String() + ".." + last.ID.String()).RunStdBytes(&RunOpts{Dir: repo.Path}) | 		stdout, _, err = NewCommand("rev-list").AddDynamicArguments(before.ID.String()+".."+last.ID.String()).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		if err != nil && strings.Contains(err.Error(), "no merge base") { | 		if err != nil && strings.Contains(err.Error(), "no merge base") { | ||||||
| 			// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated. | 			// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated. | ||||||
| 			// previously it would return the results of git rev-list before last so let's try that... | 			// previously it would return the results of git rev-list before last so let's try that... | ||||||
| 			stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(before.ID.String(), last.ID.String()).RunStdBytes(&RunOpts{Dir: repo.Path}) | 			stdout, _, err = NewCommand("rev-list").AddDynamicArguments(before.ID.String(), last.ID.String()).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -313,22 +313,22 @@ func (repo *Repository) CommitsBetweenLimit(last, before *Commit, limit, skip in | |||||||
| 	var stdout []byte | 	var stdout []byte | ||||||
| 	var err error | 	var err error | ||||||
| 	if before == nil { | 	if before == nil { | ||||||
| 		stdout, _, err = NewCommand(repo.Ctx, "rev-list"). | 		stdout, _, err = NewCommand("rev-list"). | ||||||
| 			AddOptionValues("--max-count", strconv.Itoa(limit)). | 			AddOptionValues("--max-count", strconv.Itoa(limit)). | ||||||
| 			AddOptionValues("--skip", strconv.Itoa(skip)). | 			AddOptionValues("--skip", strconv.Itoa(skip)). | ||||||
| 			AddDynamicArguments(last.ID.String()).RunStdBytes(&RunOpts{Dir: repo.Path}) | 			AddDynamicArguments(last.ID.String()).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	} else { | 	} else { | ||||||
| 		stdout, _, err = NewCommand(repo.Ctx, "rev-list"). | 		stdout, _, err = NewCommand("rev-list"). | ||||||
| 			AddOptionValues("--max-count", strconv.Itoa(limit)). | 			AddOptionValues("--max-count", strconv.Itoa(limit)). | ||||||
| 			AddOptionValues("--skip", strconv.Itoa(skip)). | 			AddOptionValues("--skip", strconv.Itoa(skip)). | ||||||
| 			AddDynamicArguments(before.ID.String() + ".." + last.ID.String()).RunStdBytes(&RunOpts{Dir: repo.Path}) | 			AddDynamicArguments(before.ID.String()+".."+last.ID.String()).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		if err != nil && strings.Contains(err.Error(), "no merge base") { | 		if err != nil && strings.Contains(err.Error(), "no merge base") { | ||||||
| 			// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated. | 			// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated. | ||||||
| 			// previously it would return the results of git rev-list --max-count n before last so let's try that... | 			// previously it would return the results of git rev-list --max-count n before last so let's try that... | ||||||
| 			stdout, _, err = NewCommand(repo.Ctx, "rev-list"). | 			stdout, _, err = NewCommand("rev-list"). | ||||||
| 				AddOptionValues("--max-count", strconv.Itoa(limit)). | 				AddOptionValues("--max-count", strconv.Itoa(limit)). | ||||||
| 				AddOptionValues("--skip", strconv.Itoa(skip)). | 				AddOptionValues("--skip", strconv.Itoa(skip)). | ||||||
| 				AddDynamicArguments(before.ID.String(), last.ID.String()).RunStdBytes(&RunOpts{Dir: repo.Path}) | 				AddDynamicArguments(before.ID.String(), last.ID.String()).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -343,13 +343,13 @@ func (repo *Repository) CommitsBetweenNotBase(last, before *Commit, baseBranch s | |||||||
| 	var stdout []byte | 	var stdout []byte | ||||||
| 	var err error | 	var err error | ||||||
| 	if before == nil { | 	if before == nil { | ||||||
| 		stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(&RunOpts{Dir: repo.Path}) | 		stdout, _, err = NewCommand("rev-list").AddDynamicArguments(last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	} else { | 	} else { | ||||||
| 		stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(before.ID.String()+".."+last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(&RunOpts{Dir: repo.Path}) | 		stdout, _, err = NewCommand("rev-list").AddDynamicArguments(before.ID.String()+".."+last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		if err != nil && strings.Contains(err.Error(), "no merge base") { | 		if err != nil && strings.Contains(err.Error(), "no merge base") { | ||||||
| 			// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated. | 			// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated. | ||||||
| 			// previously it would return the results of git rev-list before last so let's try that... | 			// previously it would return the results of git rev-list before last so let's try that... | ||||||
| 			stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(before.ID.String(), last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(&RunOpts{Dir: repo.Path}) | 			stdout, _, err = NewCommand("rev-list").AddDynamicArguments(before.ID.String(), last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -395,13 +395,13 @@ func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) { | |||||||
|  |  | ||||||
| // commitsBefore the limit is depth, not total number of returned commits. | // commitsBefore the limit is depth, not total number of returned commits. | ||||||
| func (repo *Repository) commitsBefore(id ObjectID, limit int) ([]*Commit, error) { | func (repo *Repository) commitsBefore(id ObjectID, limit int) ([]*Commit, error) { | ||||||
| 	cmd := NewCommand(repo.Ctx, "log", prettyLogFormat) | 	cmd := NewCommand("log", prettyLogFormat) | ||||||
| 	if limit > 0 { | 	if limit > 0 { | ||||||
| 		cmd.AddOptionFormat("-%d", limit) | 		cmd.AddOptionFormat("-%d", limit) | ||||||
| 	} | 	} | ||||||
| 	cmd.AddDynamicArguments(id.String()) | 	cmd.AddDynamicArguments(id.String()) | ||||||
|  |  | ||||||
| 	stdout, _, runErr := cmd.RunStdBytes(&RunOpts{Dir: repo.Path}) | 	stdout, _, runErr := cmd.RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
| @@ -438,10 +438,10 @@ func (repo *Repository) getCommitsBeforeLimit(id ObjectID, num int) ([]*Commit, | |||||||
|  |  | ||||||
| func (repo *Repository) getBranches(env []string, commitID string, limit int) ([]string, error) { | func (repo *Repository) getBranches(env []string, commitID string, limit int) ([]string, error) { | ||||||
| 	if DefaultFeatures().CheckVersionAtLeast("2.7.0") { | 	if DefaultFeatures().CheckVersionAtLeast("2.7.0") { | ||||||
| 		stdout, _, err := NewCommand(repo.Ctx, "for-each-ref", "--format=%(refname:strip=2)"). | 		stdout, _, err := NewCommand("for-each-ref", "--format=%(refname:strip=2)"). | ||||||
| 			AddOptionFormat("--count=%d", limit). | 			AddOptionFormat("--count=%d", limit). | ||||||
| 			AddOptionValues("--contains", commitID, BranchPrefix). | 			AddOptionValues("--contains", commitID, BranchPrefix). | ||||||
| 			RunStdString(&RunOpts{ | 			RunStdString(repo.Ctx, &RunOpts{ | ||||||
| 				Dir: repo.Path, | 				Dir: repo.Path, | ||||||
| 				Env: env, | 				Env: env, | ||||||
| 			}) | 			}) | ||||||
| @@ -453,7 +453,7 @@ func (repo *Repository) getBranches(env []string, commitID string, limit int) ([ | |||||||
| 		return branches, nil | 		return branches, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "branch").AddOptionValues("--contains", commitID).RunStdString(&RunOpts{ | 	stdout, _, err := NewCommand("branch").AddOptionValues("--contains", commitID).RunStdString(repo.Ctx, &RunOpts{ | ||||||
| 		Dir: repo.Path, | 		Dir: repo.Path, | ||||||
| 		Env: env, | 		Env: env, | ||||||
| 	}) | 	}) | ||||||
| @@ -495,7 +495,7 @@ func (repo *Repository) GetCommitsFromIDs(commitIDs []string) []*Commit { | |||||||
|  |  | ||||||
| // IsCommitInBranch check if the commit is on the branch | // IsCommitInBranch check if the commit is on the branch | ||||||
| func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err error) { | func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err error) { | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "branch", "--contains").AddDynamicArguments(commitID, branch).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("branch", "--contains").AddDynamicArguments(commitID, branch).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
| @@ -521,10 +521,10 @@ func (repo *Repository) AddLastCommitCache(cacheKey, fullName, sha string) error | |||||||
|  |  | ||||||
| // GetCommitBranchStart returns the commit where the branch diverged | // GetCommitBranchStart returns the commit where the branch diverged | ||||||
| func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID string) (string, error) { | func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID string) (string, error) { | ||||||
| 	cmd := NewCommand(repo.Ctx, "log", prettyLogFormat) | 	cmd := NewCommand("log", prettyLogFormat) | ||||||
| 	cmd.AddDynamicArguments(endCommitID) | 	cmd.AddDynamicArguments(endCommitID) | ||||||
|  |  | ||||||
| 	stdout, _, runErr := cmd.RunStdBytes(&RunOpts{ | 	stdout, _, runErr := cmd.RunStdBytes(repo.Ctx, &RunOpts{ | ||||||
| 		Dir: repo.Path, | 		Dir: repo.Path, | ||||||
| 		Env: env, | 		Env: env, | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	actualCommitID, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(commitID).RunStdString(&RunOpts{Dir: repo.Path}) | 	actualCommitID, _, err := NewCommand("rev-parse", "--verify").AddDynamicArguments(commitID).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	actualCommitID = strings.TrimSpace(actualCommitID) | 	actualCommitID = strings.TrimSpace(actualCommitID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if strings.Contains(err.Error(), "unknown revision or path") || | 		if strings.Contains(err.Error(), "unknown revision or path") || | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ import ( | |||||||
|  |  | ||||||
| // ResolveReference resolves a name to a reference | // ResolveReference resolves a name to a reference | ||||||
| func (repo *Repository) ResolveReference(name string) (string, error) { | func (repo *Repository) ResolveReference(name string) (string, error) { | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "show-ref", "--hash").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("show-ref", "--hash").AddDynamicArguments(name).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if strings.Contains(err.Error(), "not a valid ref") { | 		if strings.Contains(err.Error(), "not a valid ref") { | ||||||
| 			return "", ErrNotExist{name, ""} | 			return "", ErrNotExist{name, ""} | ||||||
| @@ -52,13 +52,13 @@ func (repo *Repository) GetRefCommitID(name string) (string, error) { | |||||||
|  |  | ||||||
| // SetReference sets the commit ID string of given reference (e.g. branch or tag). | // SetReference sets the commit ID string of given reference (e.g. branch or tag). | ||||||
| func (repo *Repository) SetReference(name, commitID string) error { | func (repo *Repository) SetReference(name, commitID string) error { | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "update-ref").AddDynamicArguments(name, commitID).RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("update-ref").AddDynamicArguments(name, commitID).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // RemoveReference removes the given reference (e.g. branch or tag). | // RemoveReference removes the given reference (e.g. branch or tag). | ||||||
| func (repo *Repository) RemoveReference(name string) error { | func (repo *Repository) RemoveReference(name string) error { | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "update-ref", "--no-deref", "-d").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("update-ref", "--no-deref", "-d").AddDynamicArguments(name).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -68,7 +68,7 @@ func (repo *Repository) IsCommitExist(name string) bool { | |||||||
| 		log.Error("IsCommitExist: %v", err) | 		log.Error("IsCommitExist: %v", err) | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "cat-file", "-e").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("cat-file", "-e").AddDynamicArguments(name).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err == nil | 	return err == nil | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import ( | |||||||
| // this requires git v2.18 to be installed | // this requires git v2.18 to be installed | ||||||
| func WriteCommitGraph(ctx context.Context, repoPath string) error { | func WriteCommitGraph(ctx context.Context, repoPath string) error { | ||||||
| 	if DefaultFeatures().CheckVersionAtLeast("2.18") { | 	if DefaultFeatures().CheckVersionAtLeast("2.18") { | ||||||
| 		if _, _, err := NewCommand(ctx, "commit-graph", "write").RunStdString(&RunOpts{Dir: repoPath}); err != nil { | 		if _, _, err := NewCommand("commit-graph", "write").RunStdString(ctx, &RunOpts{Dir: repoPath}); err != nil { | ||||||
| 			return fmt.Errorf("unable to write commit-graph for '%s' : %w", repoPath, err) | 			return fmt.Errorf("unable to write commit-graph for '%s' : %w", repoPath, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -39,13 +39,13 @@ func (repo *Repository) GetMergeBase(tmpRemote, base, head string) (string, stri | |||||||
| 	if tmpRemote != "origin" { | 	if tmpRemote != "origin" { | ||||||
| 		tmpBaseName := RemotePrefix + tmpRemote + "/tmp_" + base | 		tmpBaseName := RemotePrefix + tmpRemote + "/tmp_" + base | ||||||
| 		// Fetch commit into a temporary branch in order to be able to handle commits and tags | 		// Fetch commit into a temporary branch in order to be able to handle commits and tags | ||||||
| 		_, _, err := NewCommand(repo.Ctx, "fetch", "--no-tags").AddDynamicArguments(tmpRemote).AddDashesAndList(base + ":" + tmpBaseName).RunStdString(&RunOpts{Dir: repo.Path}) | 		_, _, err := NewCommand("fetch", "--no-tags").AddDynamicArguments(tmpRemote).AddDashesAndList(base+":"+tmpBaseName).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			base = tmpBaseName | 			base = tmpBaseName | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "merge-base").AddDashesAndList(base, head).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("merge-base").AddDashesAndList(base, head).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return strings.TrimSpace(stdout), base, err | 	return strings.TrimSpace(stdout), base, err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -94,9 +94,9 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string, | |||||||
| 		if !fileOnly { | 		if !fileOnly { | ||||||
| 			// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]' | 			// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]' | ||||||
| 			var logs []byte | 			var logs []byte | ||||||
| 			logs, _, err = NewCommand(repo.Ctx, "log").AddArguments(prettyLogFormat). | 			logs, _, err = NewCommand("log").AddArguments(prettyLogFormat). | ||||||
| 				AddDynamicArguments(baseCommitID+separator+headBranch).AddArguments("--"). | 				AddDynamicArguments(baseCommitID+separator+headBranch).AddArguments("--"). | ||||||
| 				RunStdBytes(&RunOpts{Dir: repo.Path}) | 				RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| @@ -150,8 +150,8 @@ func (repo *Repository) GetDiffNumChangedFiles(base, head string, directComparis | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]' | 	// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]' | ||||||
| 	if err := NewCommand(repo.Ctx, "diff", "-z", "--name-only").AddDynamicArguments(base + separator + head).AddArguments("--"). | 	if err := NewCommand("diff", "-z", "--name-only").AddDynamicArguments(base+separator+head).AddArguments("--"). | ||||||
| 		Run(&RunOpts{ | 		Run(repo.Ctx, &RunOpts{ | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: w, | 			Stdout: w, | ||||||
| 			Stderr: stderr, | 			Stderr: stderr, | ||||||
| @@ -161,7 +161,7 @@ func (repo *Repository) GetDiffNumChangedFiles(base, head string, directComparis | |||||||
| 			// previously it would return the results of git diff -z --name-only base head so let's try that... | 			// previously it would return the results of git diff -z --name-only base head so let's try that... | ||||||
| 			w = &lineCountWriter{} | 			w = &lineCountWriter{} | ||||||
| 			stderr.Reset() | 			stderr.Reset() | ||||||
| 			if err = NewCommand(repo.Ctx, "diff", "-z", "--name-only").AddDynamicArguments(base, head).AddArguments("--").Run(&RunOpts{ | 			if err = NewCommand("diff", "-z", "--name-only").AddDynamicArguments(base, head).AddArguments("--").Run(repo.Ctx, &RunOpts{ | ||||||
| 				Dir:    repo.Path, | 				Dir:    repo.Path, | ||||||
| 				Stdout: w, | 				Stdout: w, | ||||||
| 				Stderr: stderr, | 				Stderr: stderr, | ||||||
| @@ -189,8 +189,8 @@ func GetDiffShortStat(ctx context.Context, repoPath string, trustedArgs TrustedC | |||||||
| 	// $ git diff --shortstat 1ebb35b98889ff77299f24d82da426b434b0cca0...788b8b1440462d477f45b0088875 | 	// $ git diff --shortstat 1ebb35b98889ff77299f24d82da426b434b0cca0...788b8b1440462d477f45b0088875 | ||||||
| 	// we get: | 	// we get: | ||||||
| 	// " 9902 files changed, 2034198 insertions(+), 298800 deletions(-)\n" | 	// " 9902 files changed, 2034198 insertions(+), 298800 deletions(-)\n" | ||||||
| 	cmd := NewCommand(ctx, "diff", "--shortstat").AddArguments(trustedArgs...).AddDynamicArguments(dynamicArgs...) | 	cmd := NewCommand("diff", "--shortstat").AddArguments(trustedArgs...).AddDynamicArguments(dynamicArgs...) | ||||||
| 	stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) | 	stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, 0, 0, err | 		return 0, 0, 0, err | ||||||
| 	} | 	} | ||||||
| @@ -236,8 +236,8 @@ func parseDiffStat(stdout string) (numFiles, totalAdditions, totalDeletions int, | |||||||
| // GetDiff generates and returns patch data between given revisions, optimized for human readability | // GetDiff generates and returns patch data between given revisions, optimized for human readability | ||||||
| func (repo *Repository) GetDiff(compareArg string, w io.Writer) error { | func (repo *Repository) GetDiff(compareArg string, w io.Writer) error { | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	return NewCommand(repo.Ctx, "diff", "-p").AddDynamicArguments(compareArg). | 	return NewCommand("diff", "-p").AddDynamicArguments(compareArg). | ||||||
| 		Run(&RunOpts{ | 		Run(repo.Ctx, &RunOpts{ | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: w, | 			Stdout: w, | ||||||
| 			Stderr: stderr, | 			Stderr: stderr, | ||||||
| @@ -246,7 +246,7 @@ func (repo *Repository) GetDiff(compareArg string, w io.Writer) error { | |||||||
|  |  | ||||||
| // GetDiffBinary generates and returns patch data between given revisions, including binary diffs. | // GetDiffBinary generates and returns patch data between given revisions, including binary diffs. | ||||||
| func (repo *Repository) GetDiffBinary(compareArg string, w io.Writer) error { | func (repo *Repository) GetDiffBinary(compareArg string, w io.Writer) error { | ||||||
| 	return NewCommand(repo.Ctx, "diff", "-p", "--binary", "--histogram").AddDynamicArguments(compareArg).Run(&RunOpts{ | 	return NewCommand("diff", "-p", "--binary", "--histogram").AddDynamicArguments(compareArg).Run(repo.Ctx, &RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: w, | 		Stdout: w, | ||||||
| 	}) | 	}) | ||||||
| @@ -255,8 +255,8 @@ func (repo *Repository) GetDiffBinary(compareArg string, w io.Writer) error { | |||||||
| // GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply` | // GetPatch generates and returns format-patch data between given revisions, able to be used with `git apply` | ||||||
| func (repo *Repository) GetPatch(compareArg string, w io.Writer) error { | func (repo *Repository) GetPatch(compareArg string, w io.Writer) error { | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	return NewCommand(repo.Ctx, "format-patch", "--binary", "--stdout").AddDynamicArguments(compareArg). | 	return NewCommand("format-patch", "--binary", "--stdout").AddDynamicArguments(compareArg). | ||||||
| 		Run(&RunOpts{ | 		Run(repo.Ctx, &RunOpts{ | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: w, | 			Stdout: w, | ||||||
| 			Stderr: stderr, | 			Stderr: stderr, | ||||||
| @@ -271,13 +271,13 @@ func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, err | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	cmd := NewCommand(repo.Ctx, "diff-tree", "--name-only", "--root", "--no-commit-id", "-r", "-z") | 	cmd := NewCommand("diff-tree", "--name-only", "--root", "--no-commit-id", "-r", "-z") | ||||||
| 	if base == objectFormat.EmptyObjectID().String() { | 	if base == objectFormat.EmptyObjectID().String() { | ||||||
| 		cmd.AddDynamicArguments(head) | 		cmd.AddDynamicArguments(head) | ||||||
| 	} else { | 	} else { | ||||||
| 		cmd.AddDynamicArguments(base, head) | 		cmd.AddDynamicArguments(base, head) | ||||||
| 	} | 	} | ||||||
| 	stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := cmd.RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ func (repo *Repository) GetDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings, | |||||||
| 		Sign: true, | 		Sign: true, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	value, _, _ := NewCommand(repo.Ctx, "config", "--get", "commit.gpgsign").RunStdString(&RunOpts{Dir: repo.Path}) | 	value, _, _ := NewCommand("config", "--get", "commit.gpgsign").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	sign, valid := ParseBool(strings.TrimSpace(value)) | 	sign, valid := ParseBool(strings.TrimSpace(value)) | ||||||
| 	if !sign || !valid { | 	if !sign || !valid { | ||||||
| 		gpgSettings.Sign = false | 		gpgSettings.Sign = false | ||||||
| @@ -41,13 +41,13 @@ func (repo *Repository) GetDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings, | |||||||
| 		return gpgSettings, nil | 		return gpgSettings, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	signingKey, _, _ := NewCommand(repo.Ctx, "config", "--get", "user.signingkey").RunStdString(&RunOpts{Dir: repo.Path}) | 	signingKey, _, _ := NewCommand("config", "--get", "user.signingkey").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	gpgSettings.KeyID = strings.TrimSpace(signingKey) | 	gpgSettings.KeyID = strings.TrimSpace(signingKey) | ||||||
|  |  | ||||||
| 	defaultEmail, _, _ := NewCommand(repo.Ctx, "config", "--get", "user.email").RunStdString(&RunOpts{Dir: repo.Path}) | 	defaultEmail, _, _ := NewCommand("config", "--get", "user.email").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	gpgSettings.Email = strings.TrimSpace(defaultEmail) | 	gpgSettings.Email = strings.TrimSpace(defaultEmail) | ||||||
|  |  | ||||||
| 	defaultName, _, _ := NewCommand(repo.Ctx, "config", "--get", "user.name").RunStdString(&RunOpts{Dir: repo.Path}) | 	defaultName, _, _ := NewCommand("config", "--get", "user.name").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	gpgSettings.Name = strings.TrimSpace(defaultName) | 	gpgSettings.Name = strings.TrimSpace(defaultName) | ||||||
|  |  | ||||||
| 	if err := gpgSettings.LoadPublicKeyContent(); err != nil { | 	if err := gpgSettings.LoadPublicKeyContent(); err != nil { | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(treeish) != objectFormat.FullLength() { | 	if len(treeish) != objectFormat.FullLength() { | ||||||
| 		res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(treeish).RunStdString(&RunOpts{Dir: repo.Path}) | 		res, _, err := NewCommand("rev-parse", "--verify").AddDynamicArguments(treeish).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -42,7 +42,7 @@ func (repo *Repository) readTreeToIndex(id ObjectID, indexFilename ...string) er | |||||||
| 	if len(indexFilename) > 0 { | 	if len(indexFilename) > 0 { | ||||||
| 		env = append(os.Environ(), "GIT_INDEX_FILE="+indexFilename[0]) | 		env = append(os.Environ(), "GIT_INDEX_FILE="+indexFilename[0]) | ||||||
| 	} | 	} | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "read-tree").AddDynamicArguments(id.String()).RunStdString(&RunOpts{Dir: repo.Path, Env: env}) | 	_, _, err := NewCommand("read-tree").AddDynamicArguments(id.String()).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path, Env: env}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -83,14 +83,14 @@ func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (tmpIndexFilena | |||||||
|  |  | ||||||
| // EmptyIndex empties the index | // EmptyIndex empties the index | ||||||
| func (repo *Repository) EmptyIndex() error { | func (repo *Repository) EmptyIndex() error { | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "read-tree", "--empty").RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("read-tree", "--empty").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // LsFiles checks if the given filenames are in the index | // LsFiles checks if the given filenames are in the index | ||||||
| func (repo *Repository) LsFiles(filenames ...string) ([]string, error) { | func (repo *Repository) LsFiles(filenames ...string) ([]string, error) { | ||||||
| 	cmd := NewCommand(repo.Ctx, "ls-files", "-z").AddDashesAndList(filenames...) | 	cmd := NewCommand("ls-files", "-z").AddDashesAndList(filenames...) | ||||||
| 	res, _, err := cmd.RunStdBytes(&RunOpts{Dir: repo.Path}) | 	res, _, err := cmd.RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -108,7 +108,7 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	cmd := NewCommand(repo.Ctx, "update-index", "--remove", "-z", "--index-info") | 	cmd := NewCommand("update-index", "--remove", "-z", "--index-info") | ||||||
| 	stdout := new(bytes.Buffer) | 	stdout := new(bytes.Buffer) | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	buffer := new(bytes.Buffer) | 	buffer := new(bytes.Buffer) | ||||||
| @@ -118,7 +118,7 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error { | |||||||
| 			buffer.WriteString("0 blob " + objectFormat.EmptyObjectID().String() + "\t" + file + "\000") | 			buffer.WriteString("0 blob " + objectFormat.EmptyObjectID().String() + "\t" + file + "\000") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return cmd.Run(&RunOpts{ | 	return cmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdin:  bytes.NewReader(buffer.Bytes()), | 		Stdin:  bytes.NewReader(buffer.Bytes()), | ||||||
| 		Stdout: stdout, | 		Stdout: stdout, | ||||||
| @@ -134,7 +134,7 @@ type IndexObjectInfo struct { | |||||||
|  |  | ||||||
| // AddObjectsToIndex adds the provided object hashes to the index at the provided filenames | // AddObjectsToIndex adds the provided object hashes to the index at the provided filenames | ||||||
| func (repo *Repository) AddObjectsToIndex(objects ...IndexObjectInfo) error { | func (repo *Repository) AddObjectsToIndex(objects ...IndexObjectInfo) error { | ||||||
| 	cmd := NewCommand(repo.Ctx, "update-index", "--add", "--replace", "-z", "--index-info") | 	cmd := NewCommand("update-index", "--add", "--replace", "-z", "--index-info") | ||||||
| 	stdout := new(bytes.Buffer) | 	stdout := new(bytes.Buffer) | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	buffer := new(bytes.Buffer) | 	buffer := new(bytes.Buffer) | ||||||
| @@ -142,7 +142,7 @@ func (repo *Repository) AddObjectsToIndex(objects ...IndexObjectInfo) error { | |||||||
| 		// using format: mode SP type SP sha1 TAB path | 		// using format: mode SP type SP sha1 TAB path | ||||||
| 		buffer.WriteString(object.Mode + " blob " + object.Object.String() + "\t" + object.Filename + "\000") | 		buffer.WriteString(object.Mode + " blob " + object.Object.String() + "\t" + object.Filename + "\000") | ||||||
| 	} | 	} | ||||||
| 	return cmd.Run(&RunOpts{ | 	return cmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdin:  bytes.NewReader(buffer.Bytes()), | 		Stdin:  bytes.NewReader(buffer.Bytes()), | ||||||
| 		Stdout: stdout, | 		Stdout: stdout, | ||||||
| @@ -157,7 +157,7 @@ func (repo *Repository) AddObjectToIndex(mode string, object ObjectID, filename | |||||||
|  |  | ||||||
| // WriteTree writes the current index as a tree to the object db and returns its hash | // WriteTree writes the current index as a tree to the object db and returns its hash | ||||||
| func (repo *Repository) WriteTree() (*Tree, error) { | func (repo *Repository) WriteTree() (*Tree, error) { | ||||||
| 	stdout, _, runErr := NewCommand(repo.Ctx, "write-tree").RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, runErr := NewCommand("write-tree").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -68,13 +68,13 @@ func (repo *Repository) HashObject(reader io.Reader) (ObjectID, error) { | |||||||
| func (repo *Repository) hashObject(reader io.Reader, save bool) (string, error) { | func (repo *Repository) hashObject(reader io.Reader, save bool) (string, error) { | ||||||
| 	var cmd *Command | 	var cmd *Command | ||||||
| 	if save { | 	if save { | ||||||
| 		cmd = NewCommand(repo.Ctx, "hash-object", "-w", "--stdin") | 		cmd = NewCommand("hash-object", "-w", "--stdin") | ||||||
| 	} else { | 	} else { | ||||||
| 		cmd = NewCommand(repo.Ctx, "hash-object", "--stdin") | 		cmd = NewCommand("hash-object", "--stdin") | ||||||
| 	} | 	} | ||||||
| 	stdout := new(bytes.Buffer) | 	stdout := new(bytes.Buffer) | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	err := cmd.Run(&RunOpts{ | 	err := cmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdin:  reader, | 		Stdin:  reader, | ||||||
| 		Stdout: stdout, | 		Stdout: stdout, | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ func (repo *Repository) GetRefs() ([]*Reference, error) { | |||||||
| // ListOccurrences lists all refs of the given refType the given commit appears in sorted by creation date DESC | // ListOccurrences lists all refs of the given refType the given commit appears in sorted by creation date DESC | ||||||
| // refType should only be a literal "branch" or "tag" and nothing else | // refType should only be a literal "branch" or "tag" and nothing else | ||||||
| func (repo *Repository) ListOccurrences(ctx context.Context, refType, commitSHA string) ([]string, error) { | func (repo *Repository) ListOccurrences(ctx context.Context, refType, commitSHA string) ([]string, error) { | ||||||
| 	cmd := NewCommand(ctx) | 	cmd := NewCommand() | ||||||
| 	if refType == "branch" { | 	if refType == "branch" { | ||||||
| 		cmd.AddArguments("branch") | 		cmd.AddArguments("branch") | ||||||
| 	} else if refType == "tag" { | 	} else if refType == "tag" { | ||||||
| @@ -26,7 +26,7 @@ func (repo *Repository) ListOccurrences(ctx context.Context, refType, commitSHA | |||||||
| 	} else { | 	} else { | ||||||
| 		return nil, util.NewInvalidArgumentErrorf(`can only use "branch" or "tag" for refType, but got %q`, refType) | 		return nil, util.NewInvalidArgumentErrorf(`can only use "branch" or "tag" for refType, but got %q`, refType) | ||||||
| 	} | 	} | ||||||
| 	stdout, _, err := cmd.AddArguments("--no-color", "--sort=-creatordate", "--contains").AddDynamicArguments(commitSHA).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := cmd.AddArguments("--no-color", "--sort=-creatordate", "--contains").AddDynamicArguments(commitSHA).RunStdString(ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) { | |||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		stderrBuilder := &strings.Builder{} | 		stderrBuilder := &strings.Builder{} | ||||||
| 		err := NewCommand(repo.Ctx, "for-each-ref").Run(&RunOpts{ | 		err := NewCommand("for-each-ref").Run(repo.Ctx, &RunOpts{ | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: stdoutWriter, | 			Stdout: stdoutWriter, | ||||||
| 			Stderr: stderrBuilder, | 			Stderr: stderrBuilder, | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) | |||||||
|  |  | ||||||
| 	since := fromTime.Format(time.RFC3339) | 	since := fromTime.Format(time.RFC3339) | ||||||
|  |  | ||||||
| 	stdout, _, runErr := NewCommand(repo.Ctx, "rev-list", "--count", "--no-merges", "--branches=*", "--date=iso").AddOptionFormat("--since='%s'", since).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, runErr := NewCommand("rev-list", "--count", "--no-merges", "--branches=*", "--date=iso").AddOptionFormat("--since='%s'", since).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
| @@ -60,7 +60,7 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) | |||||||
| 		_ = stdoutWriter.Close() | 		_ = stdoutWriter.Close() | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| 	gitCmd := NewCommand(repo.Ctx, "log", "--numstat", "--no-merges", "--pretty=format:---%n%h%n%aN%n%aE%n", "--date=iso").AddOptionFormat("--since='%s'", since) | 	gitCmd := NewCommand("log", "--numstat", "--no-merges", "--pretty=format:---%n%h%n%aN%n%aE%n", "--date=iso").AddOptionFormat("--since='%s'", since) | ||||||
| 	if len(branch) == 0 { | 	if len(branch) == 0 { | ||||||
| 		gitCmd.AddArguments("--branches=*") | 		gitCmd.AddArguments("--branches=*") | ||||||
| 	} else { | 	} else { | ||||||
| @@ -68,7 +68,7 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stderr := new(strings.Builder) | 	stderr := new(strings.Builder) | ||||||
| 	err = gitCmd.Run(&RunOpts{ | 	err = gitCmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 		Env:    []string{}, | 		Env:    []string{}, | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: stdoutWriter, | 		Stdout: stdoutWriter, | ||||||
|   | |||||||
| @@ -24,13 +24,13 @@ func IsTagExist(ctx context.Context, repoPath, name string) bool { | |||||||
|  |  | ||||||
| // CreateTag create one tag in the repository | // CreateTag create one tag in the repository | ||||||
| func (repo *Repository) CreateTag(name, revision string) error { | func (repo *Repository) CreateTag(name, revision string) error { | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "tag").AddDashesAndList(name, revision).RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("tag").AddDashesAndList(name, revision).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // CreateAnnotatedTag create one annotated tag in the repository | // CreateAnnotatedTag create one annotated tag in the repository | ||||||
| func (repo *Repository) CreateAnnotatedTag(name, message, revision string) error { | func (repo *Repository) CreateAnnotatedTag(name, message, revision string) error { | ||||||
| 	_, _, err := NewCommand(repo.Ctx, "tag", "-a", "-m").AddDynamicArguments(message).AddDashesAndList(name, revision).RunStdString(&RunOpts{Dir: repo.Path}) | 	_, _, err := NewCommand("tag", "-a", "-m").AddDynamicArguments(message).AddDashesAndList(name, revision).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -40,7 +40,7 @@ func (repo *Repository) GetTagNameBySHA(sha string) (string, error) { | |||||||
| 		return "", fmt.Errorf("SHA is too short: %s", sha) | 		return "", fmt.Errorf("SHA is too short: %s", sha) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "show-ref", "--tags", "-d").RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("show-ref", "--tags", "-d").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -63,7 +63,7 @@ func (repo *Repository) GetTagNameBySHA(sha string) (string, error) { | |||||||
|  |  | ||||||
| // GetTagID returns the object ID for a tag (annotated tags have both an object SHA AND a commit SHA) | // GetTagID returns the object ID for a tag (annotated tags have both an object SHA AND a commit SHA) | ||||||
| func (repo *Repository) GetTagID(name string) (string, error) { | func (repo *Repository) GetTagID(name string) (string, error) { | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "show-ref", "--tags").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repo.Path}) | 	stdout, _, err := NewCommand("show-ref", "--tags").AddDashesAndList(name).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -123,9 +123,9 @@ func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) { | |||||||
| 	rc := &RunOpts{Dir: repo.Path, Stdout: stdoutWriter, Stderr: &stderr} | 	rc := &RunOpts{Dir: repo.Path, Stdout: stdoutWriter, Stderr: &stderr} | ||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		err := NewCommand(repo.Ctx, "for-each-ref"). | 		err := NewCommand("for-each-ref"). | ||||||
| 			AddOptionFormat("--format=%s", forEachRefFmt.Flag()). | 			AddOptionFormat("--format=%s", forEachRefFmt.Flag()). | ||||||
| 			AddArguments("--sort", "-*creatordate", "refs/tags").Run(rc) | 			AddArguments("--sort", "-*creatordate", "refs/tags").Run(repo.Ctx, rc) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			_ = stdoutWriter.CloseWithError(ConcatenateError(err, stderr.String())) | 			_ = stdoutWriter.CloseWithError(ConcatenateError(err, stderr.String())) | ||||||
| 		} else { | 		} else { | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt | |||||||
| 		"GIT_COMMITTER_EMAIL="+committer.Email, | 		"GIT_COMMITTER_EMAIL="+committer.Email, | ||||||
| 		"GIT_COMMITTER_DATE="+commitTimeStr, | 		"GIT_COMMITTER_DATE="+commitTimeStr, | ||||||
| 	) | 	) | ||||||
| 	cmd := NewCommand(repo.Ctx, "commit-tree").AddDynamicArguments(tree.ID.String()) | 	cmd := NewCommand("commit-tree").AddDynamicArguments(tree.ID.String()) | ||||||
|  |  | ||||||
| 	for _, parent := range opts.Parents { | 	for _, parent := range opts.Parents { | ||||||
| 		cmd.AddArguments("-p").AddDynamicArguments(parent) | 		cmd.AddArguments("-p").AddDynamicArguments(parent) | ||||||
| @@ -53,7 +53,7 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt | |||||||
|  |  | ||||||
| 	stdout := new(bytes.Buffer) | 	stdout := new(bytes.Buffer) | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	err := cmd.Run(&RunOpts{ | 	err := cmd.Run(repo.Ctx, &RunOpts{ | ||||||
| 		Env:    env, | 		Env:    env, | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdin:  messageBytes, | 		Stdin:  messageBytes, | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(idStr) != objectFormat.FullLength() { | 	if len(idStr) != objectFormat.FullLength() { | ||||||
| 		res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(idStr).RunStdString(&RunOpts{Dir: repo.Path}) | 		res, _, err := NewCommand("rev-parse", "--verify").AddDynamicArguments(idStr).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submodul | |||||||
| 			return scanner.Err() | 			return scanner.Err() | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	err = NewCommand(ctx, "ls-tree", "-r", "--", "HEAD").Run(opts) | 	err = NewCommand("ls-tree", "-r", "--", "HEAD").Run(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err) | 		return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -56,8 +56,8 @@ func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submodul | |||||||
| // It is only for generating new repos based on existing template, requires the .gitmodules file to be already present in the work dir. | // It is only for generating new repos based on existing template, requires the .gitmodules file to be already present in the work dir. | ||||||
| func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error { | func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error { | ||||||
| 	for _, submodule := range submodules { | 	for _, submodule := range submodules { | ||||||
| 		cmd := NewCommand(ctx, "update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path) | 		cmd := NewCommand("update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path) | ||||||
| 		if stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}); err != nil { | 		if stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}); err != nil { | ||||||
| 			log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err) | 			log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -30,14 +30,14 @@ func TestAddTemplateSubmoduleIndexes(t *testing.T) { | |||||||
| 	ctx := t.Context() | 	ctx := t.Context() | ||||||
| 	tmpDir := t.TempDir() | 	tmpDir := t.TempDir() | ||||||
| 	var err error | 	var err error | ||||||
| 	_, _, err = NewCommand(ctx, "init").RunStdString(&RunOpts{Dir: tmpDir}) | 	_, _, err = NewCommand("init").RunStdString(ctx, &RunOpts{Dir: tmpDir}) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 	_ = os.Mkdir(filepath.Join(tmpDir, "new-dir"), 0o755) | 	_ = os.Mkdir(filepath.Join(tmpDir, "new-dir"), 0o755) | ||||||
| 	err = AddTemplateSubmoduleIndexes(ctx, tmpDir, []TemplateSubmoduleCommit{{Path: "new-dir", Commit: "1234567890123456789012345678901234567890"}}) | 	err = AddTemplateSubmoduleIndexes(ctx, tmpDir, []TemplateSubmoduleCommit{{Path: "new-dir", Commit: "1234567890123456789012345678901234567890"}}) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 	_, _, err = NewCommand(ctx, "add", "--all").RunStdString(&RunOpts{Dir: tmpDir}) | 	_, _, err = NewCommand("add", "--all").RunStdString(ctx, &RunOpts{Dir: tmpDir}) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 	_, _, err = NewCommand(ctx, "-c", "user.name=a", "-c", "user.email=b", "commit", "-m=test").RunStdString(&RunOpts{Dir: tmpDir}) | 	_, _, err = NewCommand("-c", "user.name=a", "-c", "user.email=b", "commit", "-m=test").RunStdString(ctx, &RunOpts{Dir: tmpDir}) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
| 	submodules, err := GetTemplateSubmoduleCommits(DefaultContext, tmpDir) | 	submodules, err := GetTemplateSubmoduleCommits(DefaultContext, tmpDir) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
|   | |||||||
| @@ -48,10 +48,10 @@ func (t *Tree) SubTree(rpath string) (*Tree, error) { | |||||||
|  |  | ||||||
| // LsTree checks if the given filenames are in the tree | // LsTree checks if the given filenames are in the tree | ||||||
| func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error) { | func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error) { | ||||||
| 	cmd := NewCommand(repo.Ctx, "ls-tree", "-z", "--name-only"). | 	cmd := NewCommand("ls-tree", "-z", "--name-only"). | ||||||
| 		AddDashesAndList(append([]string{ref}, filenames...)...) | 		AddDashesAndList(append([]string{ref}, filenames...)...) | ||||||
|  |  | ||||||
| 	res, _, err := cmd.RunStdBytes(&RunOpts{Dir: repo.Path}) | 	res, _, err := cmd.RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -65,9 +65,9 @@ func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error | |||||||
|  |  | ||||||
| // GetTreePathLatestCommit returns the latest commit of a tree path | // GetTreePathLatestCommit returns the latest commit of a tree path | ||||||
| func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Commit, error) { | func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Commit, error) { | ||||||
| 	stdout, _, err := NewCommand(repo.Ctx, "rev-list", "-1"). | 	stdout, _, err := NewCommand("rev-list", "-1"). | ||||||
| 		AddDynamicArguments(refName).AddDashesAndList(treePath). | 		AddDynamicArguments(refName).AddDashesAndList(treePath). | ||||||
| 		RunStdString(&RunOpts{Dir: repo.Path}) | 		RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ func (t *Tree) ListEntries() (Entries, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, runErr := NewCommand(t.repo.Ctx, "ls-tree", "-l").AddDynamicArguments(t.ID.String()).RunStdBytes(&RunOpts{Dir: t.repo.Path}) | 	stdout, _, runErr := NewCommand("ls-tree", "-l").AddDynamicArguments(t.ID.String()).RunStdBytes(t.repo.Ctx, &RunOpts{Dir: t.repo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		if strings.Contains(runErr.Error(), "fatal: Not a valid object name") || strings.Contains(runErr.Error(), "fatal: not a tree object") { | 		if strings.Contains(runErr.Error(), "fatal: Not a valid object name") || strings.Contains(runErr.Error(), "fatal: not a tree object") { | ||||||
| 			return nil, ErrNotExist{ | 			return nil, ErrNotExist{ | ||||||
| @@ -96,10 +96,10 @@ func (t *Tree) listEntriesRecursive(extraArgs TrustedCmdArgs) (Entries, error) { | |||||||
| 		return t.entriesRecursive, nil | 		return t.entriesRecursive, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stdout, _, runErr := NewCommand(t.repo.Ctx, "ls-tree", "-t", "-r"). | 	stdout, _, runErr := NewCommand("ls-tree", "-t", "-r"). | ||||||
| 		AddArguments(extraArgs...). | 		AddArguments(extraArgs...). | ||||||
| 		AddDynamicArguments(t.ID.String()). | 		AddDynamicArguments(t.ID.String()). | ||||||
| 		RunStdBytes(&RunOpts{Dir: t.repo.Path}) | 		RunStdBytes(t.repo.Ctx, &RunOpts{Dir: t.repo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -33,9 +33,9 @@ func GetBranchCommitID(ctx context.Context, repo Repository, branch string) (str | |||||||
|  |  | ||||||
| // SetDefaultBranch sets default branch of repository. | // SetDefaultBranch sets default branch of repository. | ||||||
| func SetDefaultBranch(ctx context.Context, repo Repository, name string) error { | func SetDefaultBranch(ctx context.Context, repo Repository, name string) error { | ||||||
| 	_, _, err := git.NewCommand(ctx, "symbolic-ref", "HEAD"). | 	_, _, err := git.NewCommand("symbolic-ref", "HEAD"). | ||||||
| 		AddDynamicArguments(git.BranchPrefix+name). | 		AddDynamicArguments(git.BranchPrefix+name). | ||||||
| 		RunStdString(&git.RunOpts{Dir: repoPath(repo)}) | 		RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -158,7 +158,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro | |||||||
| 	var err error | 	var err error | ||||||
| 	if !update.Sized { | 	if !update.Sized { | ||||||
| 		var stdout string | 		var stdout string | ||||||
| 		stdout, _, err = git.NewCommand(ctx, "cat-file", "-s").AddDynamicArguments(update.BlobSha).RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) | 		stdout, _, err = git.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha).RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -143,7 +143,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro | |||||||
| 	var err error | 	var err error | ||||||
| 	if !update.Sized { | 	if !update.Sized { | ||||||
| 		var stdout string | 		var stdout string | ||||||
| 		stdout, _, err = git.NewCommand(ctx, "cat-file", "-s").AddDynamicArguments(update.BlobSha).RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) | 		stdout, _, err = git.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha).RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func getDefaultBranchSha(ctx context.Context, repo *repo_model.Repository) (string, error) { | func getDefaultBranchSha(ctx context.Context, repo *repo_model.Repository) (string, error) { | ||||||
| 	stdout, _, err := git.NewCommand(ctx, "show-ref", "-s").AddDynamicArguments(git.BranchPrefix + repo.DefaultBranch).RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) | 	stdout, _, err := git.NewCommand("show-ref", "-s").AddDynamicArguments(git.BranchPrefix+repo.DefaultBranch).RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -32,8 +32,8 @@ func getRepoChanges(ctx context.Context, repo *repo_model.Repository, revision s | |||||||
|  |  | ||||||
| 	needGenesis := len(status.CommitSha) == 0 | 	needGenesis := len(status.CommitSha) == 0 | ||||||
| 	if !needGenesis { | 	if !needGenesis { | ||||||
| 		hasAncestorCmd := git.NewCommand(ctx, "merge-base").AddDynamicArguments(status.CommitSha, revision) | 		hasAncestorCmd := git.NewCommand("merge-base").AddDynamicArguments(status.CommitSha, revision) | ||||||
| 		stdout, _, _ := hasAncestorCmd.RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) | 		stdout, _, _ := hasAncestorCmd.RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 		needGenesis = len(stdout) == 0 | 		needGenesis = len(stdout) == 0 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -86,7 +86,7 @@ func parseGitLsTreeOutput(stdout []byte) ([]internal.FileUpdate, error) { | |||||||
| // genesisChanges get changes to add repo to the indexer for the first time | // genesisChanges get changes to add repo to the indexer for the first time | ||||||
| func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) { | func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) { | ||||||
| 	var changes internal.RepoChanges | 	var changes internal.RepoChanges | ||||||
| 	stdout, _, runErr := git.NewCommand(ctx, "ls-tree", "--full-tree", "-l", "-r").AddDynamicArguments(revision).RunStdBytes(&git.RunOpts{Dir: repo.RepoPath()}) | 	stdout, _, runErr := git.NewCommand("ls-tree", "--full-tree", "-l", "-r").AddDynamicArguments(revision).RunStdBytes(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
| 	} | 	} | ||||||
| @@ -98,8 +98,8 @@ func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision s | |||||||
|  |  | ||||||
| // nonGenesisChanges get changes since the previous indexer update | // nonGenesisChanges get changes since the previous indexer update | ||||||
| func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) { | func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) { | ||||||
| 	diffCmd := git.NewCommand(ctx, "diff", "--name-status").AddDynamicArguments(repo.CodeIndexerStatus.CommitSha, revision) | 	diffCmd := git.NewCommand("diff", "--name-status").AddDynamicArguments(repo.CodeIndexerStatus.CommitSha, revision) | ||||||
| 	stdout, _, runErr := diffCmd.RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) | 	stdout, _, runErr := diffCmd.RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		// previous commit sha may have been removed by a force push, so | 		// previous commit sha may have been removed by a force push, so | ||||||
| 		// try rebuilding from scratch | 		// try rebuilding from scratch | ||||||
| @@ -115,9 +115,9 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio | |||||||
| 	updatedFilenames := make([]string, 0, 10) | 	updatedFilenames := make([]string, 0, 10) | ||||||
|  |  | ||||||
| 	updateChanges := func() error { | 	updateChanges := func() error { | ||||||
| 		cmd := git.NewCommand(ctx, "ls-tree", "--full-tree", "-l").AddDynamicArguments(revision). | 		cmd := git.NewCommand("ls-tree", "--full-tree", "-l").AddDynamicArguments(revision). | ||||||
| 			AddDashesAndList(updatedFilenames...) | 			AddDashesAndList(updatedFilenames...) | ||||||
| 		lsTreeStdout, _, err := cmd.RunStdBytes(&git.RunOpts{Dir: repo.RepoPath()}) | 		lsTreeStdout, _, err := cmd.RunStdBytes(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -186,7 +186,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r | |||||||
|  |  | ||||||
| 	// 2. Disallow force pushes to protected branches | 	// 2. Disallow force pushes to protected branches | ||||||
| 	if oldCommitID != objectFormat.EmptyObjectID().String() { | 	if oldCommitID != objectFormat.EmptyObjectID().String() { | ||||||
| 		output, _, err := git.NewCommand(ctx, "rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(&git.RunOpts{Dir: repo.RepoPath(), Env: ctx.env}) | 		output, _, err := git.NewCommand("rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath(), Env: ctx.env}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err) | 			log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err) | ||||||
| 			ctx.JSON(http.StatusInternalServerError, private.Response{ | 			ctx.JSON(http.StatusInternalServerError, private.Response{ | ||||||
|   | |||||||
| @@ -34,12 +34,12 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env [] | |||||||
| 		// When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all": | 		// When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all": | ||||||
| 		// List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits | 		// List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits | ||||||
| 		// So, it only lists the new commits received, doesn't list the commits already present in the receiving repository | 		// So, it only lists the new commits received, doesn't list the commits already present in the receiving repository | ||||||
| 		command = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(newCommitID).AddArguments("--not", "--all") | 		command = git.NewCommand("rev-list").AddDynamicArguments(newCommitID).AddArguments("--not", "--all") | ||||||
| 	} else { | 	} else { | ||||||
| 		command = git.NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID) | 		command = git.NewCommand("rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID) | ||||||
| 	} | 	} | ||||||
| 	// This is safe as force pushes are already forbidden | 	// This is safe as force pushes are already forbidden | ||||||
| 	err = command.Run(&git.RunOpts{ | 	err = command.Run(repo.Ctx, &git.RunOpts{ | ||||||
| 		Env:    env, | 		Env:    env, | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: stdoutWriter, | 		Stdout: stdoutWriter, | ||||||
| @@ -85,8 +85,8 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error { | |||||||
|  |  | ||||||
| 	commitID := git.MustIDFromString(sha) | 	commitID := git.MustIDFromString(sha) | ||||||
|  |  | ||||||
| 	return git.NewCommand(repo.Ctx, "cat-file", "commit").AddDynamicArguments(sha). | 	return git.NewCommand("cat-file", "commit").AddDynamicArguments(sha). | ||||||
| 		Run(&git.RunOpts{ | 		Run(repo.Ctx, &git.RunOpts{ | ||||||
| 			Env:    env, | 			Env:    env, | ||||||
| 			Dir:    repo.Path, | 			Dir:    repo.Path, | ||||||
| 			Stdout: stdoutWriter, | 			Stdout: stdoutWriter, | ||||||
|   | |||||||
| @@ -320,7 +320,7 @@ func dummyInfoRefs(ctx *context.Context) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		refs, _, err := git.NewCommand(ctx, "receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunStdBytes(&git.RunOpts{Dir: tmpDir}) | 		refs, _, err := git.NewCommand("receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &git.RunOpts{Dir: tmpDir}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error(fmt.Sprintf("%v - %s", err, string(refs))) | 			log.Error(fmt.Sprintf("%v - %s", err, string(refs))) | ||||||
| 		} | 		} | ||||||
| @@ -403,12 +403,12 @@ func (h *serviceHandler) sendFile(ctx *context.Context, contentType, file string | |||||||
| // one or more key=value pairs separated by colons | // one or more key=value pairs separated by colons | ||||||
| var safeGitProtocolHeader = regexp.MustCompile(`^[0-9a-zA-Z]+=[0-9a-zA-Z]+(:[0-9a-zA-Z]+=[0-9a-zA-Z]+)*$`) | var safeGitProtocolHeader = regexp.MustCompile(`^[0-9a-zA-Z]+=[0-9a-zA-Z]+(:[0-9a-zA-Z]+=[0-9a-zA-Z]+)*$`) | ||||||
|  |  | ||||||
| func prepareGitCmdWithAllowedService(ctx *context.Context, service string) (*git.Command, error) { | func prepareGitCmdWithAllowedService(service string) (*git.Command, error) { | ||||||
| 	if service == "receive-pack" { | 	if service == "receive-pack" { | ||||||
| 		return git.NewCommand(ctx, "receive-pack"), nil | 		return git.NewCommand("receive-pack"), nil | ||||||
| 	} | 	} | ||||||
| 	if service == "upload-pack" { | 	if service == "upload-pack" { | ||||||
| 		return git.NewCommand(ctx, "upload-pack"), nil | 		return git.NewCommand("upload-pack"), nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil, fmt.Errorf("service %q is not allowed", service) | 	return nil, fmt.Errorf("service %q is not allowed", service) | ||||||
| @@ -428,7 +428,7 @@ func serviceRPC(ctx *context.Context, h *serviceHandler, service string) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd, err := prepareGitCmdWithAllowedService(ctx, service) | 	cmd, err := prepareGitCmdWithAllowedService(service) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Failed to prepareGitCmdWithService: %v", err) | 		log.Error("Failed to prepareGitCmdWithService: %v", err) | ||||||
| 		ctx.Resp.WriteHeader(http.StatusUnauthorized) | 		ctx.Resp.WriteHeader(http.StatusUnauthorized) | ||||||
| @@ -458,7 +458,7 @@ func serviceRPC(ctx *context.Context, h *serviceHandler, service string) { | |||||||
|  |  | ||||||
| 	var stderr bytes.Buffer | 	var stderr bytes.Buffer | ||||||
| 	cmd.AddArguments("--stateless-rpc").AddDynamicArguments(h.getRepoDir()) | 	cmd.AddArguments("--stateless-rpc").AddDynamicArguments(h.getRepoDir()) | ||||||
| 	if err := cmd.Run(&git.RunOpts{ | 	if err := cmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:               h.getRepoDir(), | 		Dir:               h.getRepoDir(), | ||||||
| 		Env:               append(os.Environ(), h.environ...), | 		Env:               append(os.Environ(), h.environ...), | ||||||
| 		Stdout:            ctx.Resp, | 		Stdout:            ctx.Resp, | ||||||
| @@ -498,7 +498,7 @@ func getServiceType(ctx *context.Context) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func updateServerInfo(ctx gocontext.Context, dir string) []byte { | func updateServerInfo(ctx gocontext.Context, dir string) []byte { | ||||||
| 	out, _, err := git.NewCommand(ctx, "update-server-info").RunStdBytes(&git.RunOpts{Dir: dir}) | 	out, _, err := git.NewCommand("update-server-info").RunStdBytes(ctx, &git.RunOpts{Dir: dir}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error(fmt.Sprintf("%v - %s", err, string(out))) | 		log.Error(fmt.Sprintf("%v - %s", err, string(out))) | ||||||
| 	} | 	} | ||||||
| @@ -521,14 +521,14 @@ func GetInfoRefs(ctx *context.Context) { | |||||||
| 	} | 	} | ||||||
| 	setHeaderNoCache(ctx) | 	setHeaderNoCache(ctx) | ||||||
| 	service := getServiceType(ctx) | 	service := getServiceType(ctx) | ||||||
| 	cmd, err := prepareGitCmdWithAllowedService(ctx, service) | 	cmd, err := prepareGitCmdWithAllowedService(service) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		if protocol := ctx.Req.Header.Get("Git-Protocol"); protocol != "" && safeGitProtocolHeader.MatchString(protocol) { | 		if protocol := ctx.Req.Header.Get("Git-Protocol"); protocol != "" && safeGitProtocolHeader.MatchString(protocol) { | ||||||
| 			h.environ = append(h.environ, "GIT_PROTOCOL="+protocol) | 			h.environ = append(h.environ, "GIT_PROTOCOL="+protocol) | ||||||
| 		} | 		} | ||||||
| 		h.environ = append(os.Environ(), h.environ...) | 		h.environ = append(os.Environ(), h.environ...) | ||||||
|  |  | ||||||
| 		refs, _, err := cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").RunStdBytes(&git.RunOpts{Env: h.environ, Dir: h.getRepoDir()}) | 		refs, _, err := cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &git.RunOpts{Env: h.environ, Dir: h.getRepoDir()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error(fmt.Sprintf("%v - %s", err, string(refs))) | 			log.Error(fmt.Sprintf("%v - %s", err, string(refs))) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -242,7 +242,7 @@ func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) stri | |||||||
| 		} | 		} | ||||||
| 		if commitSHA != "" { | 		if commitSHA != "" { | ||||||
| 			// Get immediate parent of the first commit in the patch, grab history back | 			// Get immediate parent of the first commit in the patch, grab history back | ||||||
| 			parentCommit, _, err = git.NewCommand(ctx, "rev-list", "-1", "--skip=1").AddDynamicArguments(commitSHA).RunStdString(&git.RunOpts{Dir: ctx.Repo.GitRepo.Path}) | 			parentCommit, _, err = git.NewCommand("rev-list", "-1", "--skip=1").AddDynamicArguments(commitSHA).RunStdString(ctx, &git.RunOpts{Dir: ctx.Repo.GitRepo.Path}) | ||||||
| 			if err == nil { | 			if err == nil { | ||||||
| 				parentCommit = strings.TrimSpace(parentCommit) | 				parentCommit = strings.TrimSpace(parentCommit) | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -182,9 +182,9 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !forcePush.Value() { | 		if !forcePush.Value() { | ||||||
| 			output, _, err := git.NewCommand(ctx, "rev-list", "--max-count=1"). | 			output, _, err := git.NewCommand("rev-list", "--max-count=1"). | ||||||
| 				AddDynamicArguments(oldCommitID, "^"+opts.NewCommitIDs[i]). | 				AddDynamicArguments(oldCommitID, "^"+opts.NewCommitIDs[i]). | ||||||
| 				RunStdString(&git.RunOpts{Dir: repo.RepoPath(), Env: os.Environ()}) | 				RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath(), Env: os.Environ()}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, fmt.Errorf("failed to detect force push: %w", err) | 				return nil, fmt.Errorf("failed to detect force push: %w", err) | ||||||
| 			} else if len(output) > 0 { | 			} else if len(output) > 0 { | ||||||
|   | |||||||
| @@ -92,15 +92,15 @@ func SigningKey(ctx context.Context, repoPath string) (string, *git.Signature) { | |||||||
|  |  | ||||||
| 	if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" { | 	if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" { | ||||||
| 		// Can ignore the error here as it means that commit.gpgsign is not set | 		// Can ignore the error here as it means that commit.gpgsign is not set | ||||||
| 		value, _, _ := git.NewCommand(ctx, "config", "--get", "commit.gpgsign").RunStdString(&git.RunOpts{Dir: repoPath}) | 		value, _, _ := git.NewCommand("config", "--get", "commit.gpgsign").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 		sign, valid := git.ParseBool(strings.TrimSpace(value)) | 		sign, valid := git.ParseBool(strings.TrimSpace(value)) | ||||||
| 		if !sign || !valid { | 		if !sign || !valid { | ||||||
| 			return "", nil | 			return "", nil | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		signingKey, _, _ := git.NewCommand(ctx, "config", "--get", "user.signingkey").RunStdString(&git.RunOpts{Dir: repoPath}) | 		signingKey, _, _ := git.NewCommand("config", "--get", "user.signingkey").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 		signingName, _, _ := git.NewCommand(ctx, "config", "--get", "user.name").RunStdString(&git.RunOpts{Dir: repoPath}) | 		signingName, _, _ := git.NewCommand("config", "--get", "user.name").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 		signingEmail, _, _ := git.NewCommand(ctx, "config", "--get", "user.email").RunStdString(&git.RunOpts{Dir: repoPath}) | 		signingEmail, _, _ := git.NewCommand("config", "--get", "user.email").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 		return strings.TrimSpace(signingKey), &git.Signature{ | 		return strings.TrimSpace(signingKey), &git.Signature{ | ||||||
| 			Name:  strings.TrimSpace(signingName), | 			Name:  strings.TrimSpace(signingName), | ||||||
| 			Email: strings.TrimSpace(signingEmail), | 			Email: strings.TrimSpace(signingEmail), | ||||||
|   | |||||||
| @@ -18,9 +18,9 @@ func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) | |||||||
| 	numReposUpdated := 0 | 	numReposUpdated := 0 | ||||||
| 	err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { | 	err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { | ||||||
| 		numRepos++ | 		numRepos++ | ||||||
| 		_, _, defaultBranchErr := git.NewCommand(ctx, "rev-parse").AddDashesAndList(repo.DefaultBranch).RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) | 		_, _, defaultBranchErr := git.NewCommand("rev-parse").AddDashesAndList(repo.DefaultBranch).RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
|  |  | ||||||
| 		head, _, headErr := git.NewCommand(ctx, "symbolic-ref", "--short", "HEAD").RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) | 		head, _, headErr := git.NewCommand("symbolic-ref", "--short", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
|  |  | ||||||
| 		// what we expect: default branch is valid, and HEAD points to it | 		// what we expect: default branch is valid, and HEAD points to it | ||||||
| 		if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch { | 		if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch { | ||||||
| @@ -46,7 +46,7 @@ func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// otherwise, let's try fixing HEAD | 		// otherwise, let's try fixing HEAD | ||||||
| 		err := git.NewCommand(ctx, "symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch).Run(&git.RunOpts{Dir: repo.RepoPath()}) | 		err := git.NewCommand("symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch).Run(ctx, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err) | 			logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err) | ||||||
| 			return nil | 			return nil | ||||||
|   | |||||||
| @@ -42,17 +42,17 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro | |||||||
|  |  | ||||||
| 			if !pr.HasMerged { | 			if !pr.HasMerged { | ||||||
| 				var err error | 				var err error | ||||||
| 				pr.MergeBase, _, err = git.NewCommand(ctx, "merge-base").AddDashesAndList(pr.BaseBranch, pr.GetGitRefName()).RunStdString(&git.RunOpts{Dir: repoPath}) | 				pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, pr.GetGitRefName()).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					var err2 error | 					var err2 error | ||||||
| 					pr.MergeBase, _, err2 = git.NewCommand(ctx, "rev-parse").AddDynamicArguments(git.BranchPrefix + pr.BaseBranch).RunStdString(&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 { | 					if err2 != nil { | ||||||
| 						logger.Warn("Unable to get merge base for PR ID %d, #%d onto %s in %s/%s. Error: %v & %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err, err2) | 						logger.Warn("Unable to get merge base for PR ID %d, #%d onto %s in %s/%s. Error: %v & %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err, err2) | ||||||
| 						return nil | 						return nil | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				parentsString, _, err := git.NewCommand(ctx, "rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(&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 { | 				if err != nil { | ||||||
| 					logger.Warn("Unable to get parents for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err) | 					logger.Warn("Unable to get parents for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err) | ||||||
| 					return nil | 					return nil | ||||||
| @@ -64,8 +64,8 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro | |||||||
|  |  | ||||||
| 				refs := append([]string{}, parents[1:]...) | 				refs := append([]string{}, parents[1:]...) | ||||||
| 				refs = append(refs, pr.GetGitRefName()) | 				refs = append(refs, pr.GetGitRefName()) | ||||||
| 				cmd := git.NewCommand(ctx, "merge-base").AddDashesAndList(refs...) | 				cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) | ||||||
| 				pr.MergeBase, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) | 				pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					logger.Warn("Unable to get merge base for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err) | 					logger.Warn("Unable to get merge base for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err) | ||||||
| 					return nil | 					return nil | ||||||
|   | |||||||
| @@ -99,11 +99,11 @@ func checkEnablePushOptions(ctx context.Context, logger log.Logger, autofix bool | |||||||
| 		defer r.Close() | 		defer r.Close() | ||||||
|  |  | ||||||
| 		if autofix { | 		if autofix { | ||||||
| 			_, _, err := git.NewCommand(ctx, "config", "receive.advertisePushOptions", "true").RunStdString(&git.RunOpts{Dir: r.Path}) | 			_, _, err := git.NewCommand("config", "receive.advertisePushOptions", "true").RunStdString(ctx, &git.RunOpts{Dir: r.Path}) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		value, _, err := git.NewCommand(ctx, "config", "receive.advertisePushOptions").RunStdString(&git.RunOpts{Dir: r.Path}) | 		value, _, err := git.NewCommand("config", "receive.advertisePushOptions").RunStdString(ctx, &git.RunOpts{Dir: r.Path}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -54,12 +54,12 @@ func runGitDiffTree(ctx context.Context, gitRepo *git.Repository, useMergeBase b | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := git.NewCommand(ctx, "diff-tree", "--raw", "-r", "--find-renames", "--root") | 	cmd := git.NewCommand("diff-tree", "--raw", "-r", "--find-renames", "--root") | ||||||
| 	if useMergeBase { | 	if useMergeBase { | ||||||
| 		cmd.AddArguments("--merge-base") | 		cmd.AddArguments("--merge-base") | ||||||
| 	} | 	} | ||||||
| 	cmd.AddDynamicArguments(baseCommitID, headCommitID) | 	cmd.AddDynamicArguments(baseCommitID, headCommitID) | ||||||
| 	stdout, _, runErr := cmd.RunStdString(&git.RunOpts{Dir: gitRepo.Path}) | 	stdout, _, runErr := cmd.RunStdString(ctx, &git.RunOpts{Dir: gitRepo.Path}) | ||||||
| 	if runErr != nil { | 	if runErr != nil { | ||||||
| 		log.Warn("git diff-tree: %v", runErr) | 		log.Warn("git diff-tree: %v", runErr) | ||||||
| 		return nil, runErr | 		return nil, runErr | ||||||
|   | |||||||
| @@ -1122,7 +1122,7 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi | |||||||
| 	cmdCtx, cmdCancel := context.WithCancel(ctx) | 	cmdCtx, cmdCancel := context.WithCancel(ctx) | ||||||
| 	defer cmdCancel() | 	defer cmdCancel() | ||||||
|  |  | ||||||
| 	cmdDiff := git.NewCommand(cmdCtx) | 	cmdDiff := git.NewCommand() | ||||||
| 	objectFormat, err := gitRepo.GetObjectFormat() | 	objectFormat, err := gitRepo.GetObjectFormat() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -1173,7 +1173,7 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi | |||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		stderr := &bytes.Buffer{} | 		stderr := &bytes.Buffer{} | ||||||
| 		if err := cmdDiff.Run(&git.RunOpts{ | 		if err := cmdDiff.Run(cmdCtx, &git.RunOpts{ | ||||||
| 			Timeout: time.Duration(setting.Git.Timeout.Default) * time.Second, | 			Timeout: time.Duration(setting.Git.Timeout.Default) * time.Second, | ||||||
| 			Dir:     repoPath, | 			Dir:     repoPath, | ||||||
| 			Stdout:  writer, | 			Stdout:  writer, | ||||||
|   | |||||||
| @@ -488,7 +488,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR | |||||||
| 	if pr.Head.CloneURL == "" || pr.Head.Ref == "" { | 	if pr.Head.CloneURL == "" || pr.Head.Ref == "" { | ||||||
| 		// Set head information if pr.Head.SHA is available | 		// Set head information if pr.Head.SHA is available | ||||||
| 		if pr.Head.SHA != "" { | 		if pr.Head.SHA != "" { | ||||||
| 			_, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) | 			_, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) | 				log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) | ||||||
| 			} | 			} | ||||||
| @@ -518,7 +518,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR | |||||||
| 	if !ok { | 	if !ok { | ||||||
| 		// Set head information if pr.Head.SHA is available | 		// Set head information if pr.Head.SHA is available | ||||||
| 		if pr.Head.SHA != "" { | 		if pr.Head.SHA != "" { | ||||||
| 			_, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) | 			_, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) | 				log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err) | ||||||
| 			} | 			} | ||||||
| @@ -553,7 +553,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR | |||||||
| 			fetchArg = git.BranchPrefix + fetchArg | 			fetchArg = git.BranchPrefix + fetchArg | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		_, _, err = git.NewCommand(ctx, "fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(&git.RunOpts{Dir: g.gitPath()}) | 		_, _, err = git.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) | 			log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) | ||||||
| 			// We need to continue here so that the Head.Ref is reset and we attempt to set the gitref for the PR | 			// We need to continue here so that the Head.Ref is reset and we attempt to set the gitref for the PR | ||||||
| @@ -577,7 +577,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR | |||||||
| 		pr.Head.SHA = headSha | 		pr.Head.SHA = headSha | ||||||
| 	} | 	} | ||||||
| 	if pr.Head.SHA != "" { | 	if pr.Head.SHA != "" { | ||||||
| 		_, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) | 		_, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) | 			log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -662,7 +662,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba | |||||||
| 				fetchArg = git.BranchPrefix + fetchArg | 				fetchArg = git.BranchPrefix + fetchArg | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(ctx, "fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) | 			_, _, err = git.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) | 				log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) | ||||||
| 				return head, nil | 				return head, nil | ||||||
| @@ -681,7 +681,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba | |||||||
| 			pr.Head.SHA = headSha | 			pr.Head.SHA = headSha | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		_, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) | 		_, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return "", err | 			return "", err | ||||||
| 		} | 		} | ||||||
| @@ -698,13 +698,13 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba | |||||||
| 		// The SHA is empty | 		// The SHA is empty | ||||||
| 		log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName) | 		log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName) | ||||||
| 	} else { | 	} else { | ||||||
| 		_, _, err = git.NewCommand(ctx, "rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) | 		_, _, err = git.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			// Git update-ref remove bad references with a relative path | 			// Git update-ref remove bad references with a relative path | ||||||
| 			log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing  %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitRefName()) | 			log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing  %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitRefName()) | ||||||
| 		} else { | 		} else { | ||||||
| 			// set head information | 			// set head information | ||||||
| 			_, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) | 			_, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) | 				log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err) | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -237,7 +237,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { | |||||||
| 	fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | 	fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||||
| 	baseRef := "master" | 	baseRef := "master" | ||||||
| 	assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName)) | 	assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName)) | ||||||
| 	err := git.NewCommand(git.DefaultContext, "symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(&git.RunOpts{Dir: fromRepo.RepoPath()}) | 	err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(git.DefaultContext, &git.RunOpts{Dir: fromRepo.RepoPath()}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644)) | 	assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644)) | ||||||
| 	assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) | 	assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) | ||||||
| @@ -261,7 +261,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { | |||||||
| 	// fromRepo branch1 | 	// fromRepo branch1 | ||||||
| 	// | 	// | ||||||
| 	headRef := "branch1" | 	headRef := "branch1" | ||||||
| 	_, _, err = git.NewCommand(git.DefaultContext, "checkout", "-b").AddDynamicArguments(headRef).RunStdString(&git.RunOpts{Dir: fromRepo.RepoPath()}) | 	_, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(headRef).RunStdString(git.DefaultContext, &git.RunOpts{Dir: fromRepo.RepoPath()}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644)) | 	assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644)) | ||||||
| 	assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) | 	assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) | ||||||
| @@ -285,7 +285,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { | |||||||
| 	assert.NoError(t, git.CloneWithArgs(git.DefaultContext, nil, fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{ | 	assert.NoError(t, git.CloneWithArgs(git.DefaultContext, nil, fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{ | ||||||
| 		Branch: headRef, | 		Branch: headRef, | ||||||
| 	})) | 	})) | ||||||
| 	_, _, err = git.NewCommand(git.DefaultContext, "checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(&git.RunOpts{Dir: forkRepo.RepoPath()}) | 	_, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(git.DefaultContext, &git.RunOpts{Dir: forkRepo.RepoPath()}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# branch2 %s", forkRepo.RepoPath())), 0o644)) | 	assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# branch2 %s", forkRepo.RepoPath())), 0o644)) | ||||||
| 	assert.NoError(t, git.AddChanges(forkRepo.RepoPath(), true)) | 	assert.NoError(t, git.AddChanges(forkRepo.RepoPath(), true)) | ||||||
|   | |||||||
| @@ -40,13 +40,13 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error | |||||||
| 	remoteName := m.GetRemoteName() | 	remoteName := m.GetRemoteName() | ||||||
| 	repoPath := m.GetRepository(ctx).RepoPath() | 	repoPath := m.GetRepository(ctx).RepoPath() | ||||||
| 	// Remove old remote | 	// Remove old remote | ||||||
| 	_, _, err = git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: repoPath}) | 	_, _, err = git.NewCommand("remote", "rm").AddDynamicArguments(remoteName).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil && !git.IsRemoteNotExistError(err) { | 	if err != nil && !git.IsRemoteNotExistError(err) { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := git.NewCommand(ctx, "remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(addr) | 	cmd := git.NewCommand("remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(addr) | ||||||
| 	_, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) | 	_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil && !git.IsRemoteNotExistError(err) { | 	if err != nil && !git.IsRemoteNotExistError(err) { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -55,13 +55,13 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error | |||||||
| 		wikiPath := m.Repo.WikiPath() | 		wikiPath := m.Repo.WikiPath() | ||||||
| 		wikiRemotePath := repo_module.WikiRemoteURL(ctx, addr) | 		wikiRemotePath := repo_module.WikiRemoteURL(ctx, addr) | ||||||
| 		// Remove old remote of wiki | 		// Remove old remote of wiki | ||||||
| 		_, _, err = git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(remoteName).RunStdString(&git.RunOpts{Dir: wikiPath}) | 		_, _, err = git.NewCommand("remote", "rm").AddDynamicArguments(remoteName).RunStdString(ctx, &git.RunOpts{Dir: wikiPath}) | ||||||
| 		if err != nil && !git.IsRemoteNotExistError(err) { | 		if err != nil && !git.IsRemoteNotExistError(err) { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cmd = git.NewCommand(ctx, "remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(wikiRemotePath) | 		cmd = git.NewCommand("remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(wikiRemotePath) | ||||||
| 		_, _, err = cmd.RunStdString(&git.RunOpts{Dir: wikiPath}) | 		_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: wikiPath}) | ||||||
| 		if err != nil && !git.IsRemoteNotExistError(err) { | 		if err != nil && !git.IsRemoteNotExistError(err) { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -208,8 +208,8 @@ func pruneBrokenReferences(ctx context.Context, | |||||||
|  |  | ||||||
| 	stderrBuilder.Reset() | 	stderrBuilder.Reset() | ||||||
| 	stdoutBuilder.Reset() | 	stdoutBuilder.Reset() | ||||||
| 	pruneErr := git.NewCommand(ctx, "remote", "prune").AddDynamicArguments(m.GetRemoteName()). | 	pruneErr := git.NewCommand("remote", "prune").AddDynamicArguments(m.GetRemoteName()). | ||||||
| 		Run(&git.RunOpts{ | 		Run(ctx, &git.RunOpts{ | ||||||
| 			Timeout: timeout, | 			Timeout: timeout, | ||||||
| 			Dir:     repoPath, | 			Dir:     repoPath, | ||||||
| 			Stdout:  stdoutBuilder, | 			Stdout:  stdoutBuilder, | ||||||
| @@ -243,7 +243,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo | |||||||
| 	log.Trace("SyncMirrors [repo: %-v]: running git remote update...", m.Repo) | 	log.Trace("SyncMirrors [repo: %-v]: running git remote update...", m.Repo) | ||||||
|  |  | ||||||
| 	// use fetch but not remote update because git fetch support --tags but remote update doesn't | 	// use fetch but not remote update because git fetch support --tags but remote update doesn't | ||||||
| 	cmd := git.NewCommand(ctx, "fetch") | 	cmd := git.NewCommand("fetch") | ||||||
| 	if m.EnablePrune { | 	if m.EnablePrune { | ||||||
| 		cmd.AddArguments("--prune") | 		cmd.AddArguments("--prune") | ||||||
| 	} | 	} | ||||||
| @@ -259,7 +259,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo | |||||||
|  |  | ||||||
| 	stdoutBuilder := strings.Builder{} | 	stdoutBuilder := strings.Builder{} | ||||||
| 	stderrBuilder := strings.Builder{} | 	stderrBuilder := strings.Builder{} | ||||||
| 	if err := cmd.Run(&git.RunOpts{ | 	if err := cmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Timeout: timeout, | 		Timeout: timeout, | ||||||
| 		Dir:     repoPath, | 		Dir:     repoPath, | ||||||
| 		Env:     envs, | 		Env:     envs, | ||||||
| @@ -284,7 +284,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo | |||||||
| 				// Successful prune - reattempt mirror | 				// Successful prune - reattempt mirror | ||||||
| 				stderrBuilder.Reset() | 				stderrBuilder.Reset() | ||||||
| 				stdoutBuilder.Reset() | 				stdoutBuilder.Reset() | ||||||
| 				if err = cmd.Run(&git.RunOpts{ | 				if err = cmd.Run(ctx, &git.RunOpts{ | ||||||
| 					Timeout: timeout, | 					Timeout: timeout, | ||||||
| 					Dir:     repoPath, | 					Dir:     repoPath, | ||||||
| 					Stdout:  &stdoutBuilder, | 					Stdout:  &stdoutBuilder, | ||||||
| @@ -352,8 +352,8 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo | |||||||
| 		log.Trace("SyncMirrors [repo: %-v Wiki]: running git remote update...", m.Repo) | 		log.Trace("SyncMirrors [repo: %-v Wiki]: running git remote update...", m.Repo) | ||||||
| 		stderrBuilder.Reset() | 		stderrBuilder.Reset() | ||||||
| 		stdoutBuilder.Reset() | 		stdoutBuilder.Reset() | ||||||
| 		if err := git.NewCommand(ctx, "remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()). | 		if err := git.NewCommand("remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()). | ||||||
| 			Run(&git.RunOpts{ | 			Run(ctx, &git.RunOpts{ | ||||||
| 				Timeout: timeout, | 				Timeout: timeout, | ||||||
| 				Dir:     wikiPath, | 				Dir:     wikiPath, | ||||||
| 				Stdout:  &stdoutBuilder, | 				Stdout:  &stdoutBuilder, | ||||||
| @@ -378,8 +378,8 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo | |||||||
| 					stderrBuilder.Reset() | 					stderrBuilder.Reset() | ||||||
| 					stdoutBuilder.Reset() | 					stdoutBuilder.Reset() | ||||||
|  |  | ||||||
| 					if err = git.NewCommand(ctx, "remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()). | 					if err = git.NewCommand("remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()). | ||||||
| 						Run(&git.RunOpts{ | 						Run(ctx, &git.RunOpts{ | ||||||
| 							Timeout: timeout, | 							Timeout: timeout, | ||||||
| 							Dir:     wikiPath, | 							Dir:     wikiPath, | ||||||
| 							Stdout:  &stdoutBuilder, | 							Stdout:  &stdoutBuilder, | ||||||
|   | |||||||
| @@ -30,14 +30,14 @@ var stripExitStatus = regexp.MustCompile(`exit status \d+ - `) | |||||||
| // AddPushMirrorRemote registers the push mirror remote. | // AddPushMirrorRemote registers the push mirror remote. | ||||||
| func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr string) error { | func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr string) error { | ||||||
| 	addRemoteAndConfig := func(addr, path string) error { | 	addRemoteAndConfig := func(addr, path string) error { | ||||||
| 		cmd := git.NewCommand(ctx, "remote", "add", "--mirror=push").AddDynamicArguments(m.RemoteName, addr) | 		cmd := git.NewCommand("remote", "add", "--mirror=push").AddDynamicArguments(m.RemoteName, addr) | ||||||
| 		if _, _, err := cmd.RunStdString(&git.RunOpts{Dir: path}); err != nil { | 		if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		if _, _, err := git.NewCommand(ctx, "config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*").RunStdString(&git.RunOpts{Dir: path}); err != nil { | 		if _, _, err := git.NewCommand("config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*").RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		if _, _, err := git.NewCommand(ctx, "config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*").RunStdString(&git.RunOpts{Dir: path}); err != nil { | 		if _, _, err := git.NewCommand("config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*").RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		return nil | 		return nil | ||||||
| @@ -61,15 +61,15 @@ func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr str | |||||||
|  |  | ||||||
| // RemovePushMirrorRemote removes the push mirror remote. | // RemovePushMirrorRemote removes the push mirror remote. | ||||||
| func RemovePushMirrorRemote(ctx context.Context, m *repo_model.PushMirror) error { | func RemovePushMirrorRemote(ctx context.Context, m *repo_model.PushMirror) error { | ||||||
| 	cmd := git.NewCommand(ctx, "remote", "rm").AddDynamicArguments(m.RemoteName) | 	cmd := git.NewCommand("remote", "rm").AddDynamicArguments(m.RemoteName) | ||||||
| 	_ = m.GetRepository(ctx) | 	_ = m.GetRepository(ctx) | ||||||
|  |  | ||||||
| 	if _, _, err := cmd.RunStdString(&git.RunOpts{Dir: m.Repo.RepoPath()}); err != nil { | 	if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: m.Repo.RepoPath()}); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if m.Repo.HasWiki() { | 	if m.Repo.HasWiki() { | ||||||
| 		if _, _, err := cmd.RunStdString(&git.RunOpts{Dir: m.Repo.WikiPath()}); err != nil { | 		if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: m.Repo.WikiPath()}); err != nil { | ||||||
| 			// The wiki remote may not exist | 			// The wiki remote may not exist | ||||||
| 			log.Warn("Wiki Remote[%d] could not be removed: %v", m.ID, err) | 			log.Warn("Wiki Remote[%d] could not be removed: %v", m.ID, err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -206,9 +206,9 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com | |||||||
| 	prHeadRef := pr.GetGitRefName() | 	prHeadRef := pr.GetGitRefName() | ||||||
|  |  | ||||||
| 	// Check if the pull request is merged into BaseBranch | 	// Check if the pull request is merged into BaseBranch | ||||||
| 	if _, _, err := git.NewCommand(ctx, "merge-base", "--is-ancestor"). | 	if _, _, err := git.NewCommand("merge-base", "--is-ancestor"). | ||||||
| 		AddDynamicArguments(prHeadRef, pr.BaseBranch). | 		AddDynamicArguments(prHeadRef, pr.BaseBranch). | ||||||
| 		RunStdString(&git.RunOpts{Dir: pr.BaseRepo.RepoPath()}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: pr.BaseRepo.RepoPath()}); err != nil { | ||||||
| 		if strings.Contains(err.Error(), "exit status 1") { | 		if strings.Contains(err.Error(), "exit status 1") { | ||||||
| 			// prHeadRef is not an ancestor of the base branch | 			// prHeadRef is not an ancestor of the base branch | ||||||
| 			return nil, nil | 			return nil, nil | ||||||
| @@ -234,9 +234,9 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com | |||||||
| 	objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName) | 	objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName) | ||||||
|  |  | ||||||
| 	// Get the commit from BaseBranch where the pull request got merged | 	// Get the commit from BaseBranch where the pull request got merged | ||||||
| 	mergeCommit, _, err := git.NewCommand(ctx, "rev-list", "--ancestry-path", "--merges", "--reverse"). | 	mergeCommit, _, err := git.NewCommand("rev-list", "--ancestry-path", "--merges", "--reverse"). | ||||||
| 		AddDynamicArguments(prHeadCommitID+".."+pr.BaseBranch). | 		AddDynamicArguments(prHeadCommitID+".."+pr.BaseBranch). | ||||||
| 		RunStdString(&git.RunOpts{Dir: pr.BaseRepo.RepoPath()}) | 		RunStdString(ctx, &git.RunOpts{Dir: pr.BaseRepo.RepoPath()}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err) | 		return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err) | ||||||
| 	} else if len(mergeCommit) < objectFormat.FullLength() { | 	} else if len(mergeCommit) < objectFormat.FullLength() { | ||||||
|   | |||||||
| @@ -356,12 +356,12 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use | |||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	mergeCtx.env = append(mergeCtx.env, repo_module.EnvPushTrigger+"="+string(pushTrigger)) | 	mergeCtx.env = append(mergeCtx.env, repo_module.EnvPushTrigger+"="+string(pushTrigger)) | ||||||
| 	pushCmd := git.NewCommand(ctx, "push", "origin").AddDynamicArguments(baseBranch + ":" + git.BranchPrefix + pr.BaseBranch) | 	pushCmd := git.NewCommand("push", "origin").AddDynamicArguments(baseBranch + ":" + git.BranchPrefix + pr.BaseBranch) | ||||||
|  |  | ||||||
| 	// Push back to upstream. | 	// Push back to upstream. | ||||||
| 	// This cause an api call to "/api/internal/hook/post-receive/...", | 	// This cause an api call to "/api/internal/hook/post-receive/...", | ||||||
| 	// If it's merge, all db transaction and operations should be there but not here to prevent deadlock. | 	// If it's merge, all db transaction and operations should be there but not here to prevent deadlock. | ||||||
| 	if err := pushCmd.Run(mergeCtx.RunOpts()); err != nil { | 	if err := pushCmd.Run(ctx, mergeCtx.RunOpts()); err != nil { | ||||||
| 		if strings.Contains(mergeCtx.errbuf.String(), "non-fast-forward") { | 		if strings.Contains(mergeCtx.errbuf.String(), "non-fast-forward") { | ||||||
| 			return "", &git.ErrPushOutOfDate{ | 			return "", &git.ErrPushOutOfDate{ | ||||||
| 				StdOut: mergeCtx.outbuf.String(), | 				StdOut: mergeCtx.outbuf.String(), | ||||||
| @@ -386,13 +386,13 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use | |||||||
| } | } | ||||||
|  |  | ||||||
| func commitAndSignNoAuthor(ctx *mergeContext, message string) error { | func commitAndSignNoAuthor(ctx *mergeContext, message string) error { | ||||||
| 	cmdCommit := git.NewCommand(ctx, "commit").AddOptionFormat("--message=%s", message) | 	cmdCommit := git.NewCommand("commit").AddOptionFormat("--message=%s", message) | ||||||
| 	if ctx.signKeyID == "" { | 	if ctx.signKeyID == "" { | ||||||
| 		cmdCommit.AddArguments("--no-gpg-sign") | 		cmdCommit.AddArguments("--no-gpg-sign") | ||||||
| 	} else { | 	} else { | ||||||
| 		cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID) | 		cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID) | ||||||
| 	} | 	} | ||||||
| 	if err := cmdCommit.Run(ctx.RunOpts()); err != nil { | 	if err := cmdCommit.Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 		log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | 		log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 		return fmt.Errorf("git commit %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | 		return fmt.Errorf("git commit %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 	} | 	} | ||||||
| @@ -453,7 +453,7 @@ func (err ErrMergeDivergingFastForwardOnly) Error() string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *git.Command) error { | func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *git.Command) error { | ||||||
| 	if err := cmd.Run(ctx.RunOpts()); err != nil { | 	if err := cmd.Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 		// Merge will leave a MERGE_HEAD file in the .git folder if there is a conflict | 		// Merge will leave a MERGE_HEAD file in the .git folder if there is a conflict | ||||||
| 		if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "MERGE_HEAD")); statErr == nil { | 		if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "MERGE_HEAD")); statErr == nil { | ||||||
| 			// We have a merge conflict error | 			// We have a merge conflict error | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ import ( | |||||||
|  |  | ||||||
| // doMergeStyleFastForwardOnly merges the tracking into the current HEAD - which is assumed to be staging branch (equal to the pr.BaseBranch) | // doMergeStyleFastForwardOnly merges the tracking into the current HEAD - which is assumed to be staging branch (equal to the pr.BaseBranch) | ||||||
| func doMergeStyleFastForwardOnly(ctx *mergeContext) error { | func doMergeStyleFastForwardOnly(ctx *mergeContext) error { | ||||||
| 	cmd := git.NewCommand(ctx, "merge", "--ff-only").AddDynamicArguments(trackingBranch) | 	cmd := git.NewCommand("merge", "--ff-only").AddDynamicArguments(trackingBranch) | ||||||
| 	if err := runMergeCommand(ctx, repo_model.MergeStyleFastForwardOnly, cmd); err != nil { | 	if err := runMergeCommand(ctx, repo_model.MergeStyleFastForwardOnly, cmd); err != nil { | ||||||
| 		log.Error("%-v Unable to merge tracking into base: %v", ctx.pr, err) | 		log.Error("%-v Unable to merge tracking into base: %v", ctx.pr, err) | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ import ( | |||||||
|  |  | ||||||
| // doMergeStyleMerge merges the tracking branch into the current HEAD - which is assumed to be the staging branch (equal to the pr.BaseBranch) | // doMergeStyleMerge merges the tracking branch into the current HEAD - which is assumed to be the staging branch (equal to the pr.BaseBranch) | ||||||
| func doMergeStyleMerge(ctx *mergeContext, message string) error { | func doMergeStyleMerge(ctx *mergeContext, message string) error { | ||||||
| 	cmd := git.NewCommand(ctx, "merge", "--no-ff", "--no-commit").AddDynamicArguments(trackingBranch) | 	cmd := git.NewCommand("merge", "--no-ff", "--no-commit").AddDynamicArguments(trackingBranch) | ||||||
| 	if err := runMergeCommand(ctx, repo_model.MergeStyleMerge, cmd); err != nil { | 	if err := runMergeCommand(ctx, repo_model.MergeStyleMerge, cmd); err != nil { | ||||||
| 		log.Error("%-v Unable to merge tracking into base: %v", ctx.pr, err) | 		log.Error("%-v Unable to merge tracking into base: %v", ctx.pr, err) | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ func createTemporaryRepoForMerge(ctx context.Context, pr *issues_model.PullReque | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if expectedHeadCommitID != "" { | 	if expectedHeadCommitID != "" { | ||||||
| 		trackingCommitID, _, err := git.NewCommand(ctx, "show-ref", "--hash").AddDynamicArguments(git.BranchPrefix + trackingBranch).RunStdString(&git.RunOpts{Dir: mergeCtx.tmpBasePath}) | 		trackingCommitID, _, err := git.NewCommand("show-ref", "--hash").AddDynamicArguments(git.BranchPrefix+trackingBranch).RunStdString(ctx, &git.RunOpts{Dir: mergeCtx.tmpBasePath}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
| 			log.Error("failed to get sha of head branch in %-v: show-ref[%s] --hash refs/heads/tracking: %v", mergeCtx.pr, mergeCtx.tmpBasePath, err) | 			log.Error("failed to get sha of head branch in %-v: show-ref[%s] --hash refs/heads/tracking: %v", mergeCtx.pr, mergeCtx.tmpBasePath, err) | ||||||
| @@ -151,8 +151,8 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	setConfig := func(key, value string) error { | 	setConfig := func(key, value string) error { | ||||||
| 		if err := git.NewCommand(ctx, "config", "--local").AddDynamicArguments(key, value). | 		if err := git.NewCommand("config", "--local").AddDynamicArguments(key, value). | ||||||
| 			Run(ctx.RunOpts()); err != nil { | 			Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 			log.Error("git config [%s -> %q]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String()) | 			log.Error("git config [%s -> %q]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 			return fmt.Errorf("git config [%s -> %q]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String()) | 			return fmt.Errorf("git config [%s -> %q]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 		} | 		} | ||||||
| @@ -184,8 +184,8 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Read base branch index | 	// Read base branch index | ||||||
| 	if err := git.NewCommand(ctx, "read-tree", "HEAD"). | 	if err := git.NewCommand("read-tree", "HEAD"). | ||||||
| 		Run(ctx.RunOpts()); err != nil { | 		Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 		log.Error("git read-tree HEAD: %v\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String()) | 		log.Error("git read-tree HEAD: %v\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 		return fmt.Errorf("Unable to read base branch in to the index: %w\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String()) | 		return fmt.Errorf("Unable to read base branch in to the index: %w\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 	} | 	} | ||||||
| @@ -221,8 +221,8 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string, o | |||||||
| 		return 0, nil, nil | 		return 0, nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = git.NewCommand(ctx, "diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").AddDynamicArguments(baseBranch, headBranch). | 	err = git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").AddDynamicArguments(baseBranch, headBranch). | ||||||
| 		Run(&git.RunOpts{ | 		Run(ctx, &git.RunOpts{ | ||||||
| 			Dir:    repoPath, | 			Dir:    repoPath, | ||||||
| 			Stdout: diffOutWriter, | 			Stdout: diffOutWriter, | ||||||
| 			PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { | 			PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { | ||||||
| @@ -272,16 +272,16 @@ func (err ErrRebaseConflicts) Error() string { | |||||||
| // if there is a conflict it will return an ErrRebaseConflicts | // if there is a conflict it will return an ErrRebaseConflicts | ||||||
| func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle) error { | func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle) error { | ||||||
| 	// Checkout head branch | 	// Checkout head branch | ||||||
| 	if err := git.NewCommand(ctx, "checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch). | 	if err := git.NewCommand("checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch). | ||||||
| 		Run(ctx.RunOpts()); err != nil { | 		Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 		return fmt.Errorf("unable to git checkout tracking as staging in temp repo for %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | 		return fmt.Errorf("unable to git checkout tracking as staging in temp repo for %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 	} | 	} | ||||||
| 	ctx.outbuf.Reset() | 	ctx.outbuf.Reset() | ||||||
| 	ctx.errbuf.Reset() | 	ctx.errbuf.Reset() | ||||||
|  |  | ||||||
| 	// Rebase before merging | 	// Rebase before merging | ||||||
| 	if err := git.NewCommand(ctx, "rebase").AddDynamicArguments(baseBranch). | 	if err := git.NewCommand("rebase").AddDynamicArguments(baseBranch). | ||||||
| 		Run(ctx.RunOpts()); err != nil { | 		Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 		// Rebase will leave a REBASE_HEAD file in .git if there is a conflict | 		// Rebase will leave a REBASE_HEAD file in .git if there is a conflict | ||||||
| 		if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "REBASE_HEAD")); statErr == nil { | 		if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "REBASE_HEAD")); statErr == nil { | ||||||
| 			var commitSha string | 			var commitSha string | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ import ( | |||||||
| // getRebaseAmendMessage composes the message to amend commits in rebase merge of a pull request. | // getRebaseAmendMessage composes the message to amend commits in rebase merge of a pull request. | ||||||
| func getRebaseAmendMessage(ctx *mergeContext, baseGitRepo *git.Repository) (message string, err error) { | func getRebaseAmendMessage(ctx *mergeContext, baseGitRepo *git.Repository) (message string, err error) { | ||||||
| 	// Get existing commit message. | 	// Get existing commit message. | ||||||
| 	commitMessage, _, err := git.NewCommand(ctx, "show", "--format=%B", "-s").RunStdString(&git.RunOpts{Dir: ctx.tmpBasePath}) | 	commitMessage, _, err := git.NewCommand("show", "--format=%B", "-s").RunStdString(ctx, &git.RunOpts{Dir: ctx.tmpBasePath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| @@ -42,7 +42,7 @@ func doMergeRebaseFastForward(ctx *mergeContext) error { | |||||||
| 		return fmt.Errorf("Failed to get full commit id for HEAD: %w", err) | 		return fmt.Errorf("Failed to get full commit id for HEAD: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := git.NewCommand(ctx, "merge", "--ff-only").AddDynamicArguments(stagingBranch) | 	cmd := git.NewCommand("merge", "--ff-only").AddDynamicArguments(stagingBranch) | ||||||
| 	if err := runMergeCommand(ctx, repo_model.MergeStyleRebase, cmd); err != nil { | 	if err := runMergeCommand(ctx, repo_model.MergeStyleRebase, cmd); err != nil { | ||||||
| 		log.Error("Unable to merge staging into base: %v", err) | 		log.Error("Unable to merge staging into base: %v", err) | ||||||
| 		return err | 		return err | ||||||
| @@ -73,7 +73,7 @@ func doMergeRebaseFastForward(ctx *mergeContext) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if newMessage != "" { | 	if newMessage != "" { | ||||||
| 		if err := git.NewCommand(ctx, "commit", "--amend").AddOptionFormat("--message=%s", newMessage).Run(&git.RunOpts{Dir: ctx.tmpBasePath}); err != nil { | 		if err := git.NewCommand("commit", "--amend").AddOptionFormat("--message=%s", newMessage).Run(ctx, &git.RunOpts{Dir: ctx.tmpBasePath}); err != nil { | ||||||
| 			log.Error("Unable to amend commit message: %v", err) | 			log.Error("Unable to amend commit message: %v", err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -84,7 +84,7 @@ func doMergeRebaseFastForward(ctx *mergeContext) error { | |||||||
|  |  | ||||||
| // Perform rebase merge with merge commit. | // Perform rebase merge with merge commit. | ||||||
| func doMergeRebaseMergeCommit(ctx *mergeContext, message string) error { | func doMergeRebaseMergeCommit(ctx *mergeContext, message string) error { | ||||||
| 	cmd := git.NewCommand(ctx, "merge").AddArguments("--no-ff", "--no-commit").AddDynamicArguments(stagingBranch) | 	cmd := git.NewCommand("merge").AddArguments("--no-ff", "--no-commit").AddDynamicArguments(stagingBranch) | ||||||
|  |  | ||||||
| 	if err := runMergeCommand(ctx, repo_model.MergeStyleRebaseMerge, cmd); err != nil { | 	if err := runMergeCommand(ctx, repo_model.MergeStyleRebaseMerge, cmd); err != nil { | ||||||
| 		log.Error("Unable to merge staging into base: %v", err) | 		log.Error("Unable to merge staging into base: %v", err) | ||||||
| @@ -105,8 +105,8 @@ func doMergeStyleRebase(ctx *mergeContext, mergeStyle repo_model.MergeStyle, mes | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Checkout base branch again | 	// Checkout base branch again | ||||||
| 	if err := git.NewCommand(ctx, "checkout").AddDynamicArguments(baseBranch). | 	if err := git.NewCommand("checkout").AddDynamicArguments(baseBranch). | ||||||
| 		Run(ctx.RunOpts()); err != nil { | 		Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 		log.Error("git checkout base prior to merge post staging rebase %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | 		log.Error("git checkout base prior to merge post staging rebase %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 		return fmt.Errorf("git checkout base prior to merge post staging rebase  %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | 		return fmt.Errorf("git checkout base prior to merge post staging rebase  %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error { | |||||||
| 		return fmt.Errorf("getAuthorSignatureSquash: %w", err) | 		return fmt.Errorf("getAuthorSignatureSquash: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmdMerge := git.NewCommand(ctx, "merge", "--squash").AddDynamicArguments(trackingBranch) | 	cmdMerge := git.NewCommand("merge", "--squash").AddDynamicArguments(trackingBranch) | ||||||
| 	if err := runMergeCommand(ctx, repo_model.MergeStyleSquash, cmdMerge); err != nil { | 	if err := runMergeCommand(ctx, repo_model.MergeStyleSquash, cmdMerge); err != nil { | ||||||
| 		log.Error("%-v Unable to merge --squash tracking into base: %v", ctx.pr, err) | 		log.Error("%-v Unable to merge --squash tracking into base: %v", ctx.pr, err) | ||||||
| 		return err | 		return err | ||||||
| @@ -71,7 +71,7 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error { | |||||||
| 		} | 		} | ||||||
| 		message += fmt.Sprintf("\nCo-committed-by: %s\n", sig.String()) | 		message += fmt.Sprintf("\nCo-committed-by: %s\n", sig.String()) | ||||||
| 	} | 	} | ||||||
| 	cmdCommit := git.NewCommand(ctx, "commit"). | 	cmdCommit := git.NewCommand("commit"). | ||||||
| 		AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email). | 		AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email). | ||||||
| 		AddOptionFormat("--message=%s", message) | 		AddOptionFormat("--message=%s", message) | ||||||
| 	if ctx.signKeyID == "" { | 	if ctx.signKeyID == "" { | ||||||
| @@ -79,7 +79,7 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error { | |||||||
| 	} else { | 	} else { | ||||||
| 		cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID) | 		cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID) | ||||||
| 	} | 	} | ||||||
| 	if err := cmdCommit.Run(ctx.RunOpts()); err != nil { | 	if err := cmdCommit.Run(ctx, ctx.RunOpts()); err != nil { | ||||||
| 		log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | 		log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 		return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", ctx.pr.HeadRepo.FullName(), ctx.pr.HeadBranch, ctx.pr.BaseRepo.FullName(), ctx.pr.BaseBranch, err, ctx.outbuf.String(), ctx.errbuf.String()) | 		return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", ctx.pr.HeadRepo.FullName(), ctx.pr.HeadBranch, ctx.pr.BaseRepo.FullName(), ctx.pr.BaseBranch, err, ctx.outbuf.String(), ctx.errbuf.String()) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -92,7 +92,7 @@ func testPatch(ctx context.Context, prCtx *prContext, pr *issues_model.PullReque | |||||||
| 	defer gitRepo.Close() | 	defer gitRepo.Close() | ||||||
|  |  | ||||||
| 	// 1. update merge base | 	// 1. update merge base | ||||||
| 	pr.MergeBase, _, err = git.NewCommand(ctx, "merge-base", "--", "base", "tracking").RunStdString(&git.RunOpts{Dir: prCtx.tmpBasePath}) | 	pr.MergeBase, _, err = git.NewCommand("merge-base", "--", "base", "tracking").RunStdString(ctx, &git.RunOpts{Dir: prCtx.tmpBasePath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		var err2 error | 		var err2 error | ||||||
| 		pr.MergeBase, err2 = gitRepo.GetRefCommitID(git.BranchPrefix + "base") | 		pr.MergeBase, err2 = gitRepo.GetRefCommitID(git.BranchPrefix + "base") | ||||||
| @@ -192,7 +192,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Need to get the objects from the object db to attempt to merge | 		// Need to get the objects from the object db to attempt to merge | ||||||
| 		root, _, err := git.NewCommand(ctx, "unpack-file").AddDynamicArguments(file.stage1.sha).RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 		root, _, err := git.NewCommand("unpack-file").AddDynamicArguments(file.stage1.sha).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("unable to get root object: %s at path: %s for merging. Error: %w", file.stage1.sha, file.stage1.path, err) | 			return fmt.Errorf("unable to get root object: %s at path: %s for merging. Error: %w", file.stage1.sha, file.stage1.path, err) | ||||||
| 		} | 		} | ||||||
| @@ -201,7 +201,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f | |||||||
| 			_ = util.Remove(filepath.Join(tmpBasePath, root)) | 			_ = util.Remove(filepath.Join(tmpBasePath, root)) | ||||||
| 		}() | 		}() | ||||||
|  |  | ||||||
| 		base, _, err := git.NewCommand(ctx, "unpack-file").AddDynamicArguments(file.stage2.sha).RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 		base, _, err := git.NewCommand("unpack-file").AddDynamicArguments(file.stage2.sha).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("unable to get base object: %s at path: %s for merging. Error: %w", file.stage2.sha, file.stage2.path, err) | 			return fmt.Errorf("unable to get base object: %s at path: %s for merging. Error: %w", file.stage2.sha, file.stage2.path, err) | ||||||
| 		} | 		} | ||||||
| @@ -209,7 +209,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f | |||||||
| 		defer func() { | 		defer func() { | ||||||
| 			_ = util.Remove(base) | 			_ = util.Remove(base) | ||||||
| 		}() | 		}() | ||||||
| 		head, _, err := git.NewCommand(ctx, "unpack-file").AddDynamicArguments(file.stage3.sha).RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 		head, _, err := git.NewCommand("unpack-file").AddDynamicArguments(file.stage3.sha).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("unable to get head object:%s at path: %s for merging. Error: %w", file.stage3.sha, file.stage3.path, err) | 			return fmt.Errorf("unable to get head object:%s at path: %s for merging. Error: %w", file.stage3.sha, file.stage3.path, err) | ||||||
| 		} | 		} | ||||||
| @@ -219,13 +219,13 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f | |||||||
| 		}() | 		}() | ||||||
|  |  | ||||||
| 		// now git merge-file annoyingly takes a different order to the merge-tree ... | 		// now git merge-file annoyingly takes a different order to the merge-tree ... | ||||||
| 		_, _, conflictErr := git.NewCommand(ctx, "merge-file").AddDynamicArguments(base, root, head).RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 		_, _, conflictErr := git.NewCommand("merge-file").AddDynamicArguments(base, root, head).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 		if conflictErr != nil { | 		if conflictErr != nil { | ||||||
| 			return &errMergeConflict{file.stage2.path} | 			return &errMergeConflict{file.stage2.path} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// base now contains the merged data | 		// base now contains the merged data | ||||||
| 		hash, _, err := git.NewCommand(ctx, "hash-object", "-w", "--path").AddDynamicArguments(file.stage2.path, base).RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 		hash, _, err := git.NewCommand("hash-object", "-w", "--path").AddDynamicArguments(file.stage2.path, base).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -250,7 +250,7 @@ func AttemptThreeWayMerge(ctx context.Context, gitPath string, gitRepo *git.Repo | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
|  |  | ||||||
| 	// First we use read-tree to do a simple three-way merge | 	// First we use read-tree to do a simple three-way merge | ||||||
| 	if _, _, err := git.NewCommand(ctx, "read-tree", "-m").AddDynamicArguments(base, ours, theirs).RunStdString(&git.RunOpts{Dir: gitPath}); err != nil { | 	if _, _, err := git.NewCommand("read-tree", "-m").AddDynamicArguments(base, ours, theirs).RunStdString(ctx, &git.RunOpts{Dir: gitPath}); err != nil { | ||||||
| 		log.Error("Unable to run read-tree -m! Error: %v", err) | 		log.Error("Unable to run read-tree -m! Error: %v", err) | ||||||
| 		return false, nil, fmt.Errorf("unable to run read-tree -m! Error: %w", err) | 		return false, nil, fmt.Errorf("unable to run read-tree -m! Error: %w", err) | ||||||
| 	} | 	} | ||||||
| @@ -324,9 +324,9 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * | |||||||
| 		// No conflicts detected so we need to check if the patch is empty... | 		// No conflicts detected so we need to check if the patch is empty... | ||||||
| 		// a. Write the newly merged tree and check the new tree-hash | 		// a. Write the newly merged tree and check the new tree-hash | ||||||
| 		var treeHash string | 		var treeHash string | ||||||
| 		treeHash, _, err = git.NewCommand(ctx, "write-tree").RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 		treeHash, _, err = git.NewCommand("write-tree").RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			lsfiles, _, _ := git.NewCommand(ctx, "ls-files", "-u").RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 			lsfiles, _, _ := git.NewCommand("ls-files", "-u").RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 			return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles) | 			return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles) | ||||||
| 		} | 		} | ||||||
| 		treeHash = strings.TrimSpace(treeHash) | 		treeHash = strings.TrimSpace(treeHash) | ||||||
| @@ -387,7 +387,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * | |||||||
| 	log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath) | 	log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath) | ||||||
|  |  | ||||||
| 	// 4. Read the base branch in to the index of the temporary repository | 	// 4. Read the base branch in to the index of the temporary repository | ||||||
| 	_, _, err = git.NewCommand(gitRepo.Ctx, "read-tree", "base").RunStdString(&git.RunOpts{Dir: tmpBasePath}) | 	_, _, err = git.NewCommand("read-tree", "base").RunStdString(gitRepo.Ctx, &git.RunOpts{Dir: tmpBasePath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, fmt.Errorf("git read-tree %s: %w", pr.BaseBranch, err) | 		return false, fmt.Errorf("git read-tree %s: %w", pr.BaseBranch, err) | ||||||
| 	} | 	} | ||||||
| @@ -400,7 +400,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * | |||||||
| 	prConfig := prUnit.PullRequestsConfig() | 	prConfig := prUnit.PullRequestsConfig() | ||||||
|  |  | ||||||
| 	// 6. Prepare the arguments to apply the patch against the index | 	// 6. Prepare the arguments to apply the patch against the index | ||||||
| 	cmdApply := git.NewCommand(gitRepo.Ctx, "apply", "--check", "--cached") | 	cmdApply := git.NewCommand("apply", "--check", "--cached") | ||||||
| 	if prConfig.IgnoreWhitespaceConflicts { | 	if prConfig.IgnoreWhitespaceConflicts { | ||||||
| 		cmdApply.AddArguments("--ignore-whitespace") | 		cmdApply.AddArguments("--ignore-whitespace") | ||||||
| 	} | 	} | ||||||
| @@ -431,7 +431,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * | |||||||
|  |  | ||||||
| 	// 8. Run the check command | 	// 8. Run the check command | ||||||
| 	conflict = false | 	conflict = false | ||||||
| 	err = cmdApply.Run(&git.RunOpts{ | 	err = cmdApply.Run(gitRepo.Ctx, &git.RunOpts{ | ||||||
| 		Dir:    tmpBasePath, | 		Dir:    tmpBasePath, | ||||||
| 		Stderr: stderrWriter, | 		Stderr: stderrWriter, | ||||||
| 		PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { | 		PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { | ||||||
|   | |||||||
| @@ -72,8 +72,8 @@ func readUnmergedLsFileLines(ctx context.Context, tmpBasePath string, outputChan | |||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| 	stderr := &strings.Builder{} | 	stderr := &strings.Builder{} | ||||||
| 	err = git.NewCommand(ctx, "ls-files", "-u", "-z"). | 	err = git.NewCommand("ls-files", "-u", "-z"). | ||||||
| 		Run(&git.RunOpts{ | 		Run(ctx, &git.RunOpts{ | ||||||
| 			Dir:    tmpBasePath, | 			Dir:    tmpBasePath, | ||||||
| 			Stdout: lsFilesWriter, | 			Stdout: lsFilesWriter, | ||||||
| 			Stderr: stderr, | 			Stderr: stderr, | ||||||
|   | |||||||
| @@ -504,14 +504,14 @@ func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, | |||||||
| 		return false, fmt.Errorf("GetMergeBase: %w", err) | 		return false, fmt.Errorf("GetMergeBase: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := git.NewCommand(ctx, "diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base) | 	cmd := git.NewCommand("diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base) | ||||||
| 	stdoutReader, stdoutWriter, err := os.Pipe() | 	stdoutReader, stdoutWriter, err := os.Pipe() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, fmt.Errorf("unable to open pipe for to run diff: %w", err) | 		return false, fmt.Errorf("unable to open pipe for to run diff: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	if err := cmd.Run(&git.RunOpts{ | 	if err := cmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    prCtx.tmpBasePath, | 		Dir:    prCtx.tmpBasePath, | ||||||
| 		Stdout: stdoutWriter, | 		Stdout: stdoutWriter, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
| @@ -628,7 +628,7 @@ func UpdateRef(ctx context.Context, pr *issues_model.PullRequest) (err error) { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, _, err = git.NewCommand(ctx, "update-ref").AddDynamicArguments(pr.GetGitRefName(), pr.HeadCommitID).RunStdString(&git.RunOpts{Dir: pr.BaseRepo.RepoPath()}) | 	_, _, err = git.NewCommand("update-ref").AddDynamicArguments(pr.GetGitRefName(), pr.HeadCommitID).RunStdString(ctx, &git.RunOpts{Dir: pr.BaseRepo.RepoPath()}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Unable to update ref in base repository for PR[%d] Error: %v", pr.ID, err) | 		log.Error("Unable to update ref in base repository for PR[%d] Error: %v", pr.ID, err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -133,22 +133,22 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) | |||||||
| 		return nil, nil, fmt.Errorf("Unable to add base repository to temporary repo [%s -> tmpBasePath]: %w", pr.BaseRepo.FullName(), err) | 		return nil, nil, fmt.Errorf("Unable to add base repository to temporary repo [%s -> tmpBasePath]: %w", pr.BaseRepo.FullName(), err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := git.NewCommand(ctx, "remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath). | 	if err := git.NewCommand("remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath). | ||||||
| 		Run(prCtx.RunOpts()); err != nil { | 		Run(ctx, prCtx.RunOpts()); err != nil { | ||||||
| 		log.Error("%-v Unable to add base repository as origin [%s -> %s]: %v\n%s\n%s", pr, pr.BaseRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		log.Error("%-v Unable to add base repository as origin [%s -> %s]: %v\n%s\n%s", pr, pr.BaseRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| 		cancel() | 		cancel() | ||||||
| 		return nil, nil, fmt.Errorf("Unable to add base repository as origin [%s -> tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		return nil, nil, fmt.Errorf("Unable to add base repository as origin [%s -> tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := git.NewCommand(ctx, "fetch", "origin").AddArguments(fetchArgs...).AddDashesAndList(pr.BaseBranch+":"+baseBranch, pr.BaseBranch+":original_"+baseBranch). | 	if err := git.NewCommand("fetch", "origin").AddArguments(fetchArgs...).AddDashesAndList(pr.BaseBranch+":"+baseBranch, pr.BaseBranch+":original_"+baseBranch). | ||||||
| 		Run(prCtx.RunOpts()); err != nil { | 		Run(ctx, prCtx.RunOpts()); err != nil { | ||||||
| 		log.Error("%-v Unable to fetch origin base branch [%s:%s -> base, original_base in %s]: %v:\n%s\n%s", pr, pr.BaseRepo.FullName(), pr.BaseBranch, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		log.Error("%-v Unable to fetch origin base branch [%s:%s -> base, original_base in %s]: %v:\n%s\n%s", pr, pr.BaseRepo.FullName(), pr.BaseBranch, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| 		cancel() | 		cancel() | ||||||
| 		return nil, nil, fmt.Errorf("Unable to fetch origin base branch [%s:%s -> base, original_base in tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), pr.BaseBranch, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		return nil, nil, fmt.Errorf("Unable to fetch origin base branch [%s:%s -> base, original_base in tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), pr.BaseBranch, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := git.NewCommand(ctx, "symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch). | 	if err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch). | ||||||
| 		Run(prCtx.RunOpts()); err != nil { | 		Run(ctx, prCtx.RunOpts()); err != nil { | ||||||
| 		log.Error("%-v Unable to set HEAD as base branch in [%s]: %v\n%s\n%s", pr, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		log.Error("%-v Unable to set HEAD as base branch in [%s]: %v\n%s\n%s", pr, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| 		cancel() | 		cancel() | ||||||
| 		return nil, nil, fmt.Errorf("Unable to set HEAD as base branch in tmpBasePath: %w\n%s\n%s", err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		return nil, nil, fmt.Errorf("Unable to set HEAD as base branch in tmpBasePath: %w\n%s\n%s", err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| @@ -160,8 +160,8 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) | |||||||
| 		return nil, nil, fmt.Errorf("Unable to add head base repository to temporary repo [%s -> tmpBasePath]: %w", pr.HeadRepo.FullName(), err) | 		return nil, nil, fmt.Errorf("Unable to add head base repository to temporary repo [%s -> tmpBasePath]: %w", pr.HeadRepo.FullName(), err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := git.NewCommand(ctx, "remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath). | 	if err := git.NewCommand("remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath). | ||||||
| 		Run(prCtx.RunOpts()); err != nil { | 		Run(ctx, prCtx.RunOpts()); err != nil { | ||||||
| 		log.Error("%-v Unable to add head repository as head_repo [%s -> %s]: %v\n%s\n%s", pr, pr.HeadRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		log.Error("%-v Unable to add head repository as head_repo [%s -> %s]: %v\n%s\n%s", pr, pr.HeadRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| 		cancel() | 		cancel() | ||||||
| 		return nil, nil, fmt.Errorf("Unable to add head repository as head_repo [%s -> tmpBasePath]: %w\n%s\n%s", pr.HeadRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String()) | 		return nil, nil, fmt.Errorf("Unable to add head repository as head_repo [%s -> tmpBasePath]: %w\n%s\n%s", pr.HeadRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String()) | ||||||
| @@ -178,8 +178,8 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) | |||||||
| 	} else { | 	} else { | ||||||
| 		headBranch = pr.GetGitRefName() | 		headBranch = pr.GetGitRefName() | ||||||
| 	} | 	} | ||||||
| 	if err := git.NewCommand(ctx, "fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch). | 	if err := git.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch). | ||||||
| 		Run(prCtx.RunOpts()); err != nil { | 		Run(ctx, prCtx.RunOpts()); err != nil { | ||||||
| 		cancel() | 		cancel() | ||||||
| 		if !git.IsBranchExist(ctx, pr.HeadRepo.RepoPath(), pr.HeadBranch) { | 		if !git.IsBranchExist(ctx, pr.HeadRepo.RepoPath(), pr.HeadBranch) { | ||||||
| 			return nil, nil, git_model.ErrBranchNotExist{ | 			return nil, nil, git_model.ErrBranchNotExist{ | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
|  |  | ||||||
| 	// Determine the old merge-base before the rebase - we use this for LFS push later on | 	// Determine the old merge-base before the rebase - we use this for LFS push later on | ||||||
| 	oldMergeBase, _, _ := git.NewCommand(ctx, "merge-base").AddDashesAndList(baseBranch, trackingBranch).RunStdString(&git.RunOpts{Dir: mergeCtx.tmpBasePath}) | 	oldMergeBase, _, _ := git.NewCommand("merge-base").AddDashesAndList(baseBranch, trackingBranch).RunStdString(ctx, &git.RunOpts{Dir: mergeCtx.tmpBasePath}) | ||||||
| 	oldMergeBase = strings.TrimSpace(oldMergeBase) | 	oldMergeBase = strings.TrimSpace(oldMergeBase) | ||||||
|  |  | ||||||
| 	// Rebase the tracking branch on to the base as the staging branch | 	// Rebase the tracking branch on to the base as the staging branch | ||||||
| @@ -62,7 +62,7 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques | |||||||
| 		headUser = pr.HeadRepo.Owner | 		headUser = pr.HeadRepo.Owner | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pushCmd := git.NewCommand(ctx, "push", "-f", "head_repo"). | 	pushCmd := git.NewCommand("push", "-f", "head_repo"). | ||||||
| 		AddDynamicArguments(stagingBranch + ":" + git.BranchPrefix + pr.HeadBranch) | 		AddDynamicArguments(stagingBranch + ":" + git.BranchPrefix + pr.HeadBranch) | ||||||
|  |  | ||||||
| 	// Push back to the head repository. | 	// Push back to the head repository. | ||||||
| @@ -71,7 +71,7 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques | |||||||
| 	mergeCtx.outbuf.Reset() | 	mergeCtx.outbuf.Reset() | ||||||
| 	mergeCtx.errbuf.Reset() | 	mergeCtx.errbuf.Reset() | ||||||
|  |  | ||||||
| 	if err := pushCmd.Run(&git.RunOpts{ | 	if err := pushCmd.Run(ctx, &git.RunOpts{ | ||||||
| 		Env: repo_module.FullPushingEnvironment( | 		Env: repo_module.FullPushingEnvironment( | ||||||
| 			headUser, | 			headUser, | ||||||
| 			doer, | 			doer, | ||||||
|   | |||||||
| @@ -375,8 +375,8 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if stdout, _, err := git.NewCommand(ctx, "tag", "-d").AddDashesAndList(rel.TagName). | 		if stdout, _, err := git.NewCommand("tag", "-d").AddDashesAndList(rel.TagName). | ||||||
| 			RunStdString(&git.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") { | 			RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") { | ||||||
| 			log.Error("DeleteReleaseByID (git tag -d): %d in %v Failed:\nStdout: %s\nError: %v", rel.ID, repo, stdout, err) | 			log.Error("DeleteReleaseByID (git tag -d): %d in %v Failed:\nStdout: %s\nError: %v", rel.ID, repo, stdout, err) | ||||||
| 			return fmt.Errorf("git tag -d: %w", err) | 			return fmt.Errorf("git tag -d: %w", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -90,8 +90,8 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR | |||||||
| 			return fmt.Errorf("checkDaemonExportOK: %w", err) | 			return fmt.Errorf("checkDaemonExportOK: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if stdout, _, err := git.NewCommand(ctx, "update-server-info"). | 		if stdout, _, err := git.NewCommand("update-server-info"). | ||||||
| 			RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | 			RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||||
| 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||||
| 			return fmt.Errorf("CreateRepository(git update-server-info): %w", err) | 			return fmt.Errorf("CreateRepository(git update-server-info): %w", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -86,10 +86,10 @@ func GitGcRepos(ctx context.Context, timeout time.Duration, args git.TrustedCmdA | |||||||
| // GitGcRepo calls 'git gc' to remove unnecessary files and optimize the local repository | // GitGcRepo calls 'git gc' to remove unnecessary files and optimize the local repository | ||||||
| func GitGcRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args git.TrustedCmdArgs) error { | func GitGcRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args git.TrustedCmdArgs) error { | ||||||
| 	log.Trace("Running git gc on %-v", repo) | 	log.Trace("Running git gc on %-v", repo) | ||||||
| 	command := git.NewCommand(ctx, "gc").AddArguments(args...) | 	command := git.NewCommand("gc").AddArguments(args...) | ||||||
| 	var stdout string | 	var stdout string | ||||||
| 	var err error | 	var err error | ||||||
| 	stdout, _, err = command.RunStdString(&git.RunOpts{Timeout: timeout, Dir: repo.RepoPath()}) | 	stdout, _, err = command.RunStdString(ctx, &git.RunOpts{Timeout: timeout, Dir: repo.RepoPath()}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Repository garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err) | 		log.Error("Repository garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err) | ||||||
| 		desc := fmt.Sprintf("Repository garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err) | 		desc := fmt.Sprintf("Repository garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err) | ||||||
|   | |||||||
| @@ -125,13 +125,13 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int | |||||||
| 		_ = stdoutWriter.Close() | 		_ = stdoutWriter.Close() | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| 	gitCmd := git.NewCommand(repo.Ctx, "log", "--shortstat", "--no-merges", "--pretty=format:---%n%aN%n%aE%n%as", "--reverse") | 	gitCmd := git.NewCommand("log", "--shortstat", "--no-merges", "--pretty=format:---%n%aN%n%aE%n%as", "--reverse") | ||||||
| 	// AddOptionFormat("--max-count=%d", limit) | 	// AddOptionFormat("--max-count=%d", limit) | ||||||
| 	gitCmd.AddDynamicArguments(baseCommit.ID.String()) | 	gitCmd.AddDynamicArguments(baseCommit.ID.String()) | ||||||
|  |  | ||||||
| 	var extendedCommitStats []*ExtendedCommitStats | 	var extendedCommitStats []*ExtendedCommitStats | ||||||
| 	stderr := new(strings.Builder) | 	stderr := new(strings.Builder) | ||||||
| 	err = gitCmd.Run(&git.RunOpts{ | 	err = gitCmd.Run(repo.Ctx, &git.RunOpts{ | ||||||
| 		Dir:    repo.Path, | 		Dir:    repo.Path, | ||||||
| 		Stdout: stdoutWriter, | 		Stdout: stdoutWriter, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
|   | |||||||
| @@ -67,8 +67,8 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, | |||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	// Clone to temporary path and do the init commit. | 	// Clone to temporary path and do the init commit. | ||||||
| 	if stdout, _, err := git.NewCommand(ctx, "clone").AddDynamicArguments(repoPath, tmpDir). | 	if stdout, _, err := git.NewCommand("clone").AddDynamicArguments(repoPath, tmpDir). | ||||||
| 		RunStdString(&git.RunOpts{Dir: "", Env: env}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: "", Env: env}); err != nil { | ||||||
| 		log.Error("Failed to clone from %v into %s: stdout: %s\nError: %v", repo, tmpDir, stdout, err) | 		log.Error("Failed to clone from %v into %s: stdout: %s\nError: %v", repo, tmpDir, stdout, err) | ||||||
| 		return fmt.Errorf("git clone: %w", err) | 		return fmt.Errorf("git clone: %w", err) | ||||||
| 	} | 	} | ||||||
| @@ -299,8 +299,8 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt | |||||||
| 			return fmt.Errorf("checkDaemonExportOK: %w", err) | 			return fmt.Errorf("checkDaemonExportOK: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if stdout, _, err := git.NewCommand(ctx, "update-server-info"). | 		if stdout, _, err := git.NewCommand("update-server-info"). | ||||||
| 			RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | 			RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||||
| 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | 			log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||||
| 			rollbackRepo = repo | 			rollbackRepo = repo | ||||||
| 			rollbackRepo.OwnerID = u.ID | 			rollbackRepo.OwnerID = u.ID | ||||||
| @@ -312,7 +312,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt | |||||||
| 		if len(opts.License) > 0 { | 		if len(opts.License) > 0 { | ||||||
| 			licenses = append(licenses, ConvertLicenseName(opts.License)) | 			licenses = append(licenses, ConvertLicenseName(opts.License)) | ||||||
|  |  | ||||||
| 			stdout, _, err := git.NewCommand(ctx, "rev-parse", "HEAD").RunStdString(&git.RunOpts{Dir: repoPath}) | 			stdout, _, err := git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err) | 				log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||||
| 				rollbackRepo = repo | 				rollbackRepo = repo | ||||||
|   | |||||||
| @@ -164,12 +164,12 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user | |||||||
| 	stdout := &strings.Builder{} | 	stdout := &strings.Builder{} | ||||||
| 	stderr := &strings.Builder{} | 	stderr := &strings.Builder{} | ||||||
|  |  | ||||||
| 	cmdApply := git.NewCommand(ctx, "apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary") | 	cmdApply := git.NewCommand("apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary") | ||||||
| 	if git.DefaultFeatures().CheckVersionAtLeast("2.32") { | 	if git.DefaultFeatures().CheckVersionAtLeast("2.32") { | ||||||
| 		cmdApply.AddArguments("-3") | 		cmdApply.AddArguments("-3") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := cmdApply.Run(&git.RunOpts{ | 	if err := cmdApply.Run(ctx, &git.RunOpts{ | ||||||
| 		Dir:    t.basePath, | 		Dir:    t.basePath, | ||||||
| 		Stdout: stdout, | 		Stdout: stdout, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
|   | |||||||
| @@ -52,12 +52,12 @@ func (t *TemporaryUploadRepository) Close() { | |||||||
|  |  | ||||||
| // Clone the base repository to our path and set branch as the HEAD | // Clone the base repository to our path and set branch as the HEAD | ||||||
| func (t *TemporaryUploadRepository) Clone(branch string, bare bool) error { | func (t *TemporaryUploadRepository) Clone(branch string, bare bool) error { | ||||||
| 	cmd := git.NewCommand(t.ctx, "clone", "-s", "-b").AddDynamicArguments(branch, t.repo.RepoPath(), t.basePath) | 	cmd := git.NewCommand("clone", "-s", "-b").AddDynamicArguments(branch, t.repo.RepoPath(), t.basePath) | ||||||
| 	if bare { | 	if bare { | ||||||
| 		cmd.AddArguments("--bare") | 		cmd.AddArguments("--bare") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, _, err := cmd.RunStdString(nil); err != nil { | 	if _, _, err := cmd.RunStdString(t.ctx, nil); err != nil { | ||||||
| 		stderr := err.Error() | 		stderr := err.Error() | ||||||
| 		if matched, _ := regexp.MatchString(".*Remote branch .* not found in upstream origin.*", stderr); matched { | 		if matched, _ := regexp.MatchString(".*Remote branch .* not found in upstream origin.*", stderr); matched { | ||||||
| 			return git.ErrBranchNotExist{ | 			return git.ErrBranchNotExist{ | ||||||
| @@ -96,7 +96,7 @@ func (t *TemporaryUploadRepository) Init(objectFormatName string) error { | |||||||
|  |  | ||||||
| // SetDefaultIndex sets the git index to our HEAD | // SetDefaultIndex sets the git index to our HEAD | ||||||
| func (t *TemporaryUploadRepository) SetDefaultIndex() error { | func (t *TemporaryUploadRepository) SetDefaultIndex() error { | ||||||
| 	if _, _, err := git.NewCommand(t.ctx, "read-tree", "HEAD").RunStdString(&git.RunOpts{Dir: t.basePath}); err != nil { | 	if _, _, err := git.NewCommand("read-tree", "HEAD").RunStdString(t.ctx, &git.RunOpts{Dir: t.basePath}); err != nil { | ||||||
| 		return fmt.Errorf("SetDefaultIndex: %w", err) | 		return fmt.Errorf("SetDefaultIndex: %w", err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| @@ -104,7 +104,7 @@ func (t *TemporaryUploadRepository) SetDefaultIndex() error { | |||||||
|  |  | ||||||
| // RefreshIndex looks at the current index and checks to see if merges or updates are needed by checking stat() information. | // RefreshIndex looks at the current index and checks to see if merges or updates are needed by checking stat() information. | ||||||
| func (t *TemporaryUploadRepository) RefreshIndex() error { | func (t *TemporaryUploadRepository) RefreshIndex() error { | ||||||
| 	if _, _, err := git.NewCommand(t.ctx, "update-index", "--refresh").RunStdString(&git.RunOpts{Dir: t.basePath}); err != nil { | 	if _, _, err := git.NewCommand("update-index", "--refresh").RunStdString(t.ctx, &git.RunOpts{Dir: t.basePath}); err != nil { | ||||||
| 		return fmt.Errorf("RefreshIndex: %w", err) | 		return fmt.Errorf("RefreshIndex: %w", err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| @@ -115,8 +115,8 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro | |||||||
| 	stdOut := new(bytes.Buffer) | 	stdOut := new(bytes.Buffer) | ||||||
| 	stdErr := new(bytes.Buffer) | 	stdErr := new(bytes.Buffer) | ||||||
|  |  | ||||||
| 	if err := git.NewCommand(t.ctx, "ls-files", "-z").AddDashesAndList(filenames...). | 	if err := git.NewCommand("ls-files", "-z").AddDashesAndList(filenames...). | ||||||
| 		Run(&git.RunOpts{ | 		Run(t.ctx, &git.RunOpts{ | ||||||
| 			Dir:    t.basePath, | 			Dir:    t.basePath, | ||||||
| 			Stdout: stdOut, | 			Stdout: stdOut, | ||||||
| 			Stderr: stdErr, | 			Stderr: stdErr, | ||||||
| @@ -151,8 +151,8 @@ func (t *TemporaryUploadRepository) RemoveFilesFromIndex(filenames ...string) er | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := git.NewCommand(t.ctx, "update-index", "--remove", "-z", "--index-info"). | 	if err := git.NewCommand("update-index", "--remove", "-z", "--index-info"). | ||||||
| 		Run(&git.RunOpts{ | 		Run(t.ctx, &git.RunOpts{ | ||||||
| 			Dir:    t.basePath, | 			Dir:    t.basePath, | ||||||
| 			Stdin:  stdIn, | 			Stdin:  stdIn, | ||||||
| 			Stdout: stdOut, | 			Stdout: stdOut, | ||||||
| @@ -168,8 +168,8 @@ func (t *TemporaryUploadRepository) HashObject(content io.Reader) (string, error | |||||||
| 	stdOut := new(bytes.Buffer) | 	stdOut := new(bytes.Buffer) | ||||||
| 	stdErr := new(bytes.Buffer) | 	stdErr := new(bytes.Buffer) | ||||||
|  |  | ||||||
| 	if err := git.NewCommand(t.ctx, "hash-object", "-w", "--stdin"). | 	if err := git.NewCommand("hash-object", "-w", "--stdin"). | ||||||
| 		Run(&git.RunOpts{ | 		Run(t.ctx, &git.RunOpts{ | ||||||
| 			Dir:    t.basePath, | 			Dir:    t.basePath, | ||||||
| 			Stdin:  content, | 			Stdin:  content, | ||||||
| 			Stdout: stdOut, | 			Stdout: stdOut, | ||||||
| @@ -184,7 +184,7 @@ func (t *TemporaryUploadRepository) HashObject(content io.Reader) (string, error | |||||||
|  |  | ||||||
| // AddObjectToIndex adds the provided object hash to the index with the provided mode and path | // AddObjectToIndex adds the provided object hash to the index with the provided mode and path | ||||||
| func (t *TemporaryUploadRepository) AddObjectToIndex(mode, objectHash, objectPath string) error { | func (t *TemporaryUploadRepository) AddObjectToIndex(mode, objectHash, objectPath string) error { | ||||||
| 	if _, _, err := git.NewCommand(t.ctx, "update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, objectHash, objectPath).RunStdString(&git.RunOpts{Dir: t.basePath}); err != nil { | 	if _, _, err := git.NewCommand("update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, objectHash, objectPath).RunStdString(t.ctx, &git.RunOpts{Dir: t.basePath}); err != nil { | ||||||
| 		stderr := err.Error() | 		stderr := err.Error() | ||||||
| 		if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched { | 		if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched { | ||||||
| 			return ErrFilePathInvalid{ | 			return ErrFilePathInvalid{ | ||||||
| @@ -200,7 +200,7 @@ func (t *TemporaryUploadRepository) AddObjectToIndex(mode, objectHash, objectPat | |||||||
|  |  | ||||||
| // WriteTree writes the current index as a tree to the object db and returns its hash | // WriteTree writes the current index as a tree to the object db and returns its hash | ||||||
| func (t *TemporaryUploadRepository) WriteTree() (string, error) { | func (t *TemporaryUploadRepository) WriteTree() (string, error) { | ||||||
| 	stdout, _, err := git.NewCommand(t.ctx, "write-tree").RunStdString(&git.RunOpts{Dir: t.basePath}) | 	stdout, _, err := git.NewCommand("write-tree").RunStdString(t.ctx, &git.RunOpts{Dir: t.basePath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Unable to write tree in temporary repo: %s(%s): Error: %v", t.repo.FullName(), t.basePath, err) | 		log.Error("Unable to write tree in temporary repo: %s(%s): Error: %v", t.repo.FullName(), t.basePath, err) | ||||||
| 		return "", fmt.Errorf("Unable to write-tree in temporary repo for: %s Error: %w", t.repo.FullName(), err) | 		return "", fmt.Errorf("Unable to write-tree in temporary repo for: %s Error: %w", t.repo.FullName(), err) | ||||||
| @@ -218,7 +218,7 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ref string) (string, erro | |||||||
| 	if ref == "" { | 	if ref == "" { | ||||||
| 		ref = "HEAD" | 		ref = "HEAD" | ||||||
| 	} | 	} | ||||||
| 	stdout, _, err := git.NewCommand(t.ctx, "rev-parse").AddDynamicArguments(ref).RunStdString(&git.RunOpts{Dir: t.basePath}) | 	stdout, _, err := git.NewCommand("rev-parse").AddDynamicArguments(ref).RunStdString(t.ctx, &git.RunOpts{Dir: t.basePath}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Unable to get last ref for %s in temporary repo: %s(%s): Error: %v", ref, t.repo.FullName(), t.basePath, err) | 		log.Error("Unable to get last ref for %s in temporary repo: %s(%s): Error: %v", ref, t.repo.FullName(), t.basePath, err) | ||||||
| 		return "", fmt.Errorf("Unable to rev-parse %s in temporary repo for: %s Error: %w", ref, t.repo.FullName(), err) | 		return "", fmt.Errorf("Unable to rev-parse %s in temporary repo for: %s Error: %w", ref, t.repo.FullName(), err) | ||||||
| @@ -286,7 +286,7 @@ func (t *TemporaryUploadRepository) CommitTree(opts *CommitTreeUserOptions) (str | |||||||
| 	_, _ = messageBytes.WriteString(opts.CommitMessage) | 	_, _ = messageBytes.WriteString(opts.CommitMessage) | ||||||
| 	_, _ = messageBytes.WriteString("\n") | 	_, _ = messageBytes.WriteString("\n") | ||||||
|  |  | ||||||
| 	cmdCommitTree := git.NewCommand(t.ctx, "commit-tree").AddDynamicArguments(opts.TreeHash) | 	cmdCommitTree := git.NewCommand("commit-tree").AddDynamicArguments(opts.TreeHash) | ||||||
| 	if opts.ParentCommitID != "" { | 	if opts.ParentCommitID != "" { | ||||||
| 		cmdCommitTree.AddOptionValues("-p", opts.ParentCommitID) | 		cmdCommitTree.AddOptionValues("-p", opts.ParentCommitID) | ||||||
| 	} | 	} | ||||||
| @@ -333,7 +333,7 @@ func (t *TemporaryUploadRepository) CommitTree(opts *CommitTreeUserOptions) (str | |||||||
| 	stdout := new(bytes.Buffer) | 	stdout := new(bytes.Buffer) | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	if err := cmdCommitTree. | 	if err := cmdCommitTree. | ||||||
| 		Run(&git.RunOpts{ | 		Run(t.ctx, &git.RunOpts{ | ||||||
| 			Env:    env, | 			Env:    env, | ||||||
| 			Dir:    t.basePath, | 			Dir:    t.basePath, | ||||||
| 			Stdin:  messageBytes, | 			Stdin:  messageBytes, | ||||||
| @@ -385,8 +385,8 @@ func (t *TemporaryUploadRepository) DiffIndex() (*gitdiff.Diff, error) { | |||||||
| 	}() | 	}() | ||||||
| 	stderr := new(bytes.Buffer) | 	stderr := new(bytes.Buffer) | ||||||
| 	var diff *gitdiff.Diff | 	var diff *gitdiff.Diff | ||||||
| 	err = git.NewCommand(t.ctx, "diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD"). | 	err = git.NewCommand("diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD"). | ||||||
| 		Run(&git.RunOpts{ | 		Run(t.ctx, &git.RunOpts{ | ||||||
| 			Timeout: 30 * time.Second, | 			Timeout: 30 * time.Second, | ||||||
| 			Dir:     t.basePath, | 			Dir:     t.basePath, | ||||||
| 			Stdout:  stdoutWriter, | 			Stdout:  stdoutWriter, | ||||||
|   | |||||||
| @@ -152,13 +152,13 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork | |||||||
|  |  | ||||||
| 		needsRollback = true | 		needsRollback = true | ||||||
|  |  | ||||||
| 		cloneCmd := git.NewCommand(txCtx, "clone", "--bare") | 		cloneCmd := git.NewCommand("clone", "--bare") | ||||||
| 		if opts.SingleBranch != "" { | 		if opts.SingleBranch != "" { | ||||||
| 			cloneCmd.AddArguments("--single-branch", "--branch").AddDynamicArguments(opts.SingleBranch) | 			cloneCmd.AddArguments("--single-branch", "--branch").AddDynamicArguments(opts.SingleBranch) | ||||||
| 		} | 		} | ||||||
| 		repoPath := repo_model.RepoPath(owner.Name, repo.Name) | 		repoPath := repo_model.RepoPath(owner.Name, repo.Name) | ||||||
| 		if stdout, _, err := cloneCmd.AddDynamicArguments(oldRepoPath, repoPath). | 		if stdout, _, err := cloneCmd.AddDynamicArguments(oldRepoPath, repoPath). | ||||||
| 			RunStdBytes(&git.RunOpts{Timeout: 10 * time.Minute}); err != nil { | 			RunStdBytes(txCtx, &git.RunOpts{Timeout: 10 * time.Minute}); err != nil { | ||||||
| 			log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err) | 			log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err) | ||||||
| 			return fmt.Errorf("git clone: %w", err) | 			return fmt.Errorf("git clone: %w", err) | ||||||
| 		} | 		} | ||||||
| @@ -167,8 +167,8 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork | |||||||
| 			return fmt.Errorf("checkDaemonExportOK: %w", err) | 			return fmt.Errorf("checkDaemonExportOK: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if stdout, _, err := git.NewCommand(txCtx, "update-server-info"). | 		if stdout, _, err := git.NewCommand("update-server-info"). | ||||||
| 			RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | 			RunStdString(txCtx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||||
| 			log.Error("Fork Repository (git update-server-info) failed for %v:\nStdout: %s\nError: %v", repo, stdout, err) | 			log.Error("Fork Repository (git update-server-info) failed for %v:\nStdout: %s\nError: %v", repo, stdout, err) | ||||||
| 			return fmt.Errorf("git update-server-info: %w", err) | 			return fmt.Errorf("git update-server-info: %w", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -236,8 +236,8 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if stdout, _, err := git.NewCommand(ctx, "remote", "add", "origin").AddDynamicArguments(repo.RepoPath()). | 	if stdout, _, err := git.NewCommand("remote", "add", "origin").AddDynamicArguments(repo.RepoPath()). | ||||||
| 		RunStdString(&git.RunOpts{Dir: tmpDir, Env: env}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: tmpDir, Env: env}); err != nil { | ||||||
| 		log.Error("Unable to add %v as remote origin to temporary repo to %s: stdout %s\nError: %v", repo, tmpDir, stdout, err) | 		log.Error("Unable to add %v as remote origin to temporary repo to %s: stdout %s\nError: %v", repo, tmpDir, stdout, err) | ||||||
| 		return fmt.Errorf("git remote add: %w", err) | 		return fmt.Errorf("git remote add: %w", err) | ||||||
| 	} | 	} | ||||||
| @@ -371,8 +371,8 @@ func generateRepository(ctx context.Context, doer, owner *user_model.User, templ | |||||||
| 		return generateRepo, fmt.Errorf("checkDaemonExportOK: %w", err) | 		return generateRepo, fmt.Errorf("checkDaemonExportOK: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if stdout, _, err := git.NewCommand(ctx, "update-server-info"). | 	if stdout, _, err := git.NewCommand("update-server-info"). | ||||||
| 		RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||||
| 		log.Error("GenerateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", generateRepo, stdout, err) | 		log.Error("GenerateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", generateRepo, stdout, err) | ||||||
| 		return generateRepo, fmt.Errorf("error in GenerateRepository(git update-server-info): %w", err) | 		return generateRepo, fmt.Errorf("error in GenerateRepository(git update-server-info): %w", err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bo | |||||||
| 		page = 1 | 		page = 1 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	graphCmd := git.NewCommand(r.Ctx, "log", "--graph", "--date-order", "--decorate=full") | 	graphCmd := git.NewCommand("log", "--graph", "--date-order", "--decorate=full") | ||||||
|  |  | ||||||
| 	if hidePRRefs { | 	if hidePRRefs { | ||||||
| 		graphCmd.AddArguments("--exclude=" + git.PullPrefix + "*") | 		graphCmd.AddArguments("--exclude=" + git.PullPrefix + "*") | ||||||
| @@ -53,7 +53,7 @@ func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bo | |||||||
|  |  | ||||||
| 	scanner := bufio.NewScanner(stdoutReader) | 	scanner := bufio.NewScanner(stdoutReader) | ||||||
|  |  | ||||||
| 	if err := graphCmd.Run(&git.RunOpts{ | 	if err := graphCmd.Run(r.Ctx, &git.RunOpts{ | ||||||
| 		Dir:    r.Path, | 		Dir:    r.Path, | ||||||
| 		Stdout: stdoutWriter, | 		Stdout: stdoutWriter, | ||||||
| 		Stderr: stderr, | 		Stderr: stderr, | ||||||
|   | |||||||
| @@ -33,13 +33,13 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi | |||||||
| 	committerName := sig.Name | 	committerName := sig.Name | ||||||
| 	committerEmail := sig.Email | 	committerEmail := sig.Email | ||||||
|  |  | ||||||
| 	if stdout, _, err := git.NewCommand(ctx, "add", "--all"). | 	if stdout, _, err := git.NewCommand("add", "--all"). | ||||||
| 		RunStdString(&git.RunOpts{Dir: tmpPath}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: tmpPath}); err != nil { | ||||||
| 		log.Error("git add --all failed: Stdout: %s\nError: %v", stdout, err) | 		log.Error("git add --all failed: Stdout: %s\nError: %v", stdout, err) | ||||||
| 		return fmt.Errorf("git add --all: %w", err) | 		return fmt.Errorf("git add --all: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := git.NewCommand(ctx, "commit", "--message=Initial commit"). | 	cmd := git.NewCommand("commit", "--message=Initial commit"). | ||||||
| 		AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email) | 		AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email) | ||||||
|  |  | ||||||
| 	sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u) | 	sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u) | ||||||
| @@ -61,7 +61,7 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi | |||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	if stdout, _, err := cmd. | 	if stdout, _, err := cmd. | ||||||
| 		RunStdString(&git.RunOpts{Dir: tmpPath, Env: env}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: tmpPath, Env: env}); err != nil { | ||||||
| 		log.Error("Failed to commit: %v: Stdout: %s\nError: %v", cmd.LogString(), stdout, err) | 		log.Error("Failed to commit: %v: Stdout: %s\nError: %v", cmd.LogString(), stdout, err) | ||||||
| 		return fmt.Errorf("git commit: %w", err) | 		return fmt.Errorf("git commit: %w", err) | ||||||
| 	} | 	} | ||||||
| @@ -70,8 +70,8 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi | |||||||
| 		defaultBranch = setting.Repository.DefaultBranch | 		defaultBranch = setting.Repository.DefaultBranch | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if stdout, _, err := git.NewCommand(ctx, "push", "origin").AddDynamicArguments("HEAD:" + defaultBranch). | 	if stdout, _, err := git.NewCommand("push", "origin").AddDynamicArguments("HEAD:"+defaultBranch). | ||||||
| 		RunStdString(&git.RunOpts{Dir: tmpPath, Env: repo_module.InternalPushingEnvironment(u, repo)}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: tmpPath, Env: repo_module.InternalPushingEnvironment(u, repo)}); err != nil { | ||||||
| 		log.Error("Failed to push back to HEAD: Stdout: %s\nError: %v", stdout, err) | 		log.Error("Failed to push back to HEAD: Stdout: %s\nError: %v", stdout, err) | ||||||
| 		return fmt.Errorf("git push: %w", err) | 		return fmt.Errorf("git push: %w", err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -120,8 +120,8 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, | |||||||
| 		return repo, fmt.Errorf("checkDaemonExportOK: %w", err) | 		return repo, fmt.Errorf("checkDaemonExportOK: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if stdout, _, err := git.NewCommand(ctx, "update-server-info"). | 	if stdout, _, err := git.NewCommand("update-server-info"). | ||||||
| 		RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | 		RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||||
| 		log.Error("MigrateRepositoryGitData(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | 		log.Error("MigrateRepositoryGitData(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||||
| 		return repo, fmt.Errorf("error in MigrateRepositoryGitData(git update-server-info): %w", err) | 		return repo, fmt.Errorf("error in MigrateRepositoryGitData(git update-server-info): %w", err) | ||||||
| 	} | 	} | ||||||
| @@ -230,9 +230,9 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, | |||||||
|  |  | ||||||
| 		// this is necessary for sync local tags from remote | 		// this is necessary for sync local tags from remote | ||||||
| 		configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) | 		configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) | ||||||
| 		if stdout, _, err := git.NewCommand(ctx, "config"). | 		if stdout, _, err := git.NewCommand("config"). | ||||||
| 			AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). | 			AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). | ||||||
| 			RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { | 			RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { | ||||||
| 			log.Error("MigrateRepositoryGitData(git config --add <remote> +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) | 			log.Error("MigrateRepositoryGitData(git config --add <remote> +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) | ||||||
| 			return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add <remote> +refs/tags/*:refs/tags/*): %w", err) | 			return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add <remote> +refs/tags/*:refs/tags/*): %w", err) | ||||||
| 		} | 		} | ||||||
| @@ -251,9 +251,9 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, | |||||||
| // cleanUpMigrateGitConfig removes mirror info which prevents "push --all". | // cleanUpMigrateGitConfig removes mirror info which prevents "push --all". | ||||||
| // This also removes possible user credentials. | // This also removes possible user credentials. | ||||||
| func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error { | func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error { | ||||||
| 	cmd := git.NewCommand(ctx, "remote", "rm", "origin") | 	cmd := git.NewCommand("remote", "rm", "origin") | ||||||
| 	// if the origin does not exist | 	// if the origin does not exist | ||||||
| 	_, _, err := cmd.RunStdString(&git.RunOpts{ | 	_, _, err := cmd.RunStdString(ctx, &git.RunOpts{ | ||||||
| 		Dir: repoPath, | 		Dir: repoPath, | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil && !git.IsRemoteNotExistError(err) { | 	if err != nil && !git.IsRemoteNotExistError(err) { | ||||||
| @@ -274,7 +274,7 @@ func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, _, err := git.NewCommand(ctx, "remote", "rm", "origin").RunStdString(&git.RunOpts{Dir: repoPath}) | 	_, _, err := git.NewCommand("remote", "rm", "origin").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) | ||||||
| 	if err != nil && !git.IsRemoteNotExistError(err) { | 	if err != nil && !git.IsRemoteNotExistError(err) { | ||||||
| 		return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err) | 		return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ func InitWiki(ctx context.Context, repo *repo_model.Repository) error { | |||||||
| 		return fmt.Errorf("InitRepository: %w", err) | 		return fmt.Errorf("InitRepository: %w", err) | ||||||
| 	} else if err = repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil { | 	} else if err = repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil { | ||||||
| 		return fmt.Errorf("createDelegateHooks: %w", err) | 		return fmt.Errorf("createDelegateHooks: %w", err) | ||||||
| 	} else if _, _, err = git.NewCommand(ctx, "symbolic-ref", "HEAD").AddDynamicArguments(git.BranchPrefix + repo.DefaultWikiBranch).RunStdString(&git.RunOpts{Dir: repo.WikiPath()}); err != nil { | 	} else if _, _, err = git.NewCommand("symbolic-ref", "HEAD").AddDynamicArguments(git.BranchPrefix+repo.DefaultWikiBranch).RunStdString(ctx, &git.RunOpts{Dir: repo.WikiPath()}); err != nil { | ||||||
| 		return fmt.Errorf("unable to set default wiki branch to %q: %w", repo.DefaultWikiBranch, err) | 		return fmt.Errorf("unable to set default wiki branch to %q: %w", repo.DefaultWikiBranch, err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
|   | |||||||
| @@ -30,8 +30,8 @@ func TestAPIGitTags(t *testing.T) { | |||||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) | 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) | ||||||
|  |  | ||||||
| 	// Set up git config for the tagger | 	// Set up git config for the tagger | ||||||
| 	_ = git.NewCommand(git.DefaultContext, "config", "user.name").AddDynamicArguments(user.Name).Run(&git.RunOpts{Dir: repo.RepoPath()}) | 	_ = git.NewCommand("config", "user.name").AddDynamicArguments(user.Name).Run(git.DefaultContext, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
| 	_ = git.NewCommand(git.DefaultContext, "config", "user.email").AddDynamicArguments(user.Email).Run(&git.RunOpts{Dir: repo.RepoPath()}) | 	_ = git.NewCommand("config", "user.email").AddDynamicArguments(user.Email).Run(git.DefaultContext, &git.RunOpts{Dir: repo.RepoPath()}) | ||||||
|  |  | ||||||
| 	gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo) | 	gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo) | ||||||
| 	defer gitRepo.Close() | 	defer gitRepo.Close() | ||||||
|   | |||||||
| @@ -153,9 +153,9 @@ func lfsCommitAndPushTest(t *testing.T, dstPath string, sizes ...int) (pushedFil | |||||||
| 	t.Run("CommitAndPushLFS", func(t *testing.T) { | 	t.Run("CommitAndPushLFS", func(t *testing.T) { | ||||||
| 		defer tests.PrintCurrentTest(t)() | 		defer tests.PrintCurrentTest(t)() | ||||||
| 		prefix := "lfs-data-file-" | 		prefix := "lfs-data-file-" | ||||||
| 		err := git.NewCommand(git.DefaultContext, "lfs").AddArguments("install").Run(&git.RunOpts{Dir: dstPath}) | 		err := git.NewCommand("lfs").AddArguments("install").Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		_, _, err = git.NewCommand(git.DefaultContext, "lfs").AddArguments("track").AddDynamicArguments(prefix + "*").RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err = git.NewCommand("lfs").AddArguments("track").AddDynamicArguments(prefix+"*").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		err = git.AddChanges(dstPath, false, ".gitattributes") | 		err = git.AddChanges(dstPath, false, ".gitattributes") | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| @@ -271,20 +271,20 @@ func lockTest(t *testing.T, repoPath string) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func lockFileTest(t *testing.T, filename, repoPath string) { | func lockFileTest(t *testing.T, filename, repoPath string) { | ||||||
| 	_, _, err := git.NewCommand(git.DefaultContext, "lfs").AddArguments("locks").RunStdString(&git.RunOpts{Dir: repoPath}) | 	_, _, err := git.NewCommand("lfs").AddArguments("locks").RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	_, _, err = git.NewCommand(git.DefaultContext, "lfs").AddArguments("lock").AddDynamicArguments(filename).RunStdString(&git.RunOpts{Dir: repoPath}) | 	_, _, err = git.NewCommand("lfs").AddArguments("lock").AddDynamicArguments(filename).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	_, _, err = git.NewCommand(git.DefaultContext, "lfs").AddArguments("locks").RunStdString(&git.RunOpts{Dir: repoPath}) | 	_, _, err = git.NewCommand("lfs").AddArguments("locks").RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	_, _, err = git.NewCommand(git.DefaultContext, "lfs").AddArguments("unlock").AddDynamicArguments(filename).RunStdString(&git.RunOpts{Dir: repoPath}) | 	_, _, err = git.NewCommand("lfs").AddArguments("unlock").AddDynamicArguments(filename).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| } | } | ||||||
|  |  | ||||||
| func doCommitAndPush(t *testing.T, size int, repoPath, prefix string) string { | func doCommitAndPush(t *testing.T, size int, repoPath, prefix string) string { | ||||||
| 	name, err := generateCommitWithNewData(size, repoPath, "user2@example.com", "User Two", prefix) | 	name, err := generateCommitWithNewData(size, repoPath, "user2@example.com", "User Two", prefix) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	_, _, err = git.NewCommand(git.DefaultContext, "push", "origin", "master").RunStdString(&git.RunOpts{Dir: repoPath}) // Push | 	_, _, err = git.NewCommand("push", "origin", "master").RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) // Push | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	return name | 	return name | ||||||
| } | } | ||||||
| @@ -386,7 +386,7 @@ func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *tes | |||||||
| 		// Try to force push without force push permissions, which should fail | 		// Try to force push without force push permissions, which should fail | ||||||
| 		t.Run("ForcePushWithoutForcePermissions", func(t *testing.T) { | 		t.Run("ForcePushWithoutForcePermissions", func(t *testing.T) { | ||||||
| 			t.Run("CreateDivergentHistory", func(t *testing.T) { | 			t.Run("CreateDivergentHistory", func(t *testing.T) { | ||||||
| 				git.NewCommand(git.DefaultContext, "reset", "--hard", "HEAD~1").Run(&git.RunOpts{Dir: dstPath}) | 				git.NewCommand("reset", "--hard", "HEAD~1").Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 				_, err := generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "branch-data-file-new") | 				_, err := generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "branch-data-file-new") | ||||||
| 				assert.NoError(t, err) | 				assert.NoError(t, err) | ||||||
| 			}) | 			}) | ||||||
| @@ -785,7 +785,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, headBranch string | |||||||
| 		}) | 		}) | ||||||
|  |  | ||||||
| 		t.Run("Push", func(t *testing.T) { | 		t.Run("Push", func(t *testing.T) { | ||||||
| 			err := git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic=" + headBranch).Run(&git.RunOpts{Dir: dstPath}) | 			err := git.NewCommand("push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic="+headBranch).Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
|  |  | ||||||
| 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+1) | 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+1) | ||||||
| @@ -803,7 +803,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, headBranch string | |||||||
| 			assert.Contains(t, "Testing commit 1", prMsg.Body) | 			assert.Contains(t, "Testing commit 1", prMsg.Body) | ||||||
| 			assert.Equal(t, commit, prMsg.Head.Sha) | 			assert.Equal(t, commit, prMsg.Head.Sha) | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "origin").AddDynamicArguments("HEAD:refs/for/master/test/" + headBranch).RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err = git.NewCommand("push", "origin").AddDynamicArguments("HEAD:refs/for/master/test/"+headBranch).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
|  |  | ||||||
| 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) | 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) | ||||||
| @@ -851,7 +851,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, headBranch string | |||||||
| 		}) | 		}) | ||||||
|  |  | ||||||
| 		t.Run("Push2", func(t *testing.T) { | 		t.Run("Push2", func(t *testing.T) { | ||||||
| 			err := git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic=" + headBranch).Run(&git.RunOpts{Dir: dstPath}) | 			err := git.NewCommand("push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic="+headBranch).Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
|  |  | ||||||
| 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) | 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) | ||||||
| @@ -861,7 +861,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, headBranch string | |||||||
| 			assert.False(t, prMsg.HasMerged) | 			assert.False(t, prMsg.HasMerged) | ||||||
| 			assert.Equal(t, commit, prMsg.Head.Sha) | 			assert.Equal(t, commit, prMsg.Head.Sha) | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "origin").AddDynamicArguments("HEAD:refs/for/master/test/" + headBranch).RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err = git.NewCommand("push", "origin").AddDynamicArguments("HEAD:refs/for/master/test/"+headBranch).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
|  |  | ||||||
| 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) | 			unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) | ||||||
|   | |||||||
| @@ -122,7 +122,7 @@ func doGitInitTestRepository(dstPath string) func(*testing.T) { | |||||||
| 		// Init repository in dstPath | 		// Init repository in dstPath | ||||||
| 		assert.NoError(t, git.InitRepository(git.DefaultContext, dstPath, false, git.Sha1ObjectFormat.Name())) | 		assert.NoError(t, git.InitRepository(git.DefaultContext, dstPath, false, git.Sha1ObjectFormat.Name())) | ||||||
| 		// forcibly set default branch to master | 		// forcibly set default branch to master | ||||||
| 		_, _, err := git.NewCommand(git.DefaultContext, "symbolic-ref", "HEAD", git.BranchPrefix+"master").RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommand("symbolic-ref", "HEAD", git.BranchPrefix+"master").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		assert.NoError(t, os.WriteFile(filepath.Join(dstPath, "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", dstPath)), 0o644)) | 		assert.NoError(t, os.WriteFile(filepath.Join(dstPath, "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", dstPath)), 0o644)) | ||||||
| 		assert.NoError(t, git.AddChanges(dstPath, true)) | 		assert.NoError(t, git.AddChanges(dstPath, true)) | ||||||
| @@ -141,21 +141,21 @@ func doGitInitTestRepository(dstPath string) func(*testing.T) { | |||||||
|  |  | ||||||
| func doGitAddRemote(dstPath, remoteName string, u *url.URL) func(*testing.T) { | func doGitAddRemote(dstPath, remoteName string, u *url.URL) func(*testing.T) { | ||||||
| 	return func(t *testing.T) { | 	return func(t *testing.T) { | ||||||
| 		_, _, err := git.NewCommand(git.DefaultContext, "remote", "add").AddDynamicArguments(remoteName, u.String()).RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommand("remote", "add").AddDynamicArguments(remoteName, u.String()).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func doGitPushTestRepository(dstPath string, args ...string) func(*testing.T) { | func doGitPushTestRepository(dstPath string, args ...string) func(*testing.T) { | ||||||
| 	return func(t *testing.T) { | 	return func(t *testing.T) { | ||||||
| 		_, _, err := git.NewCommand(git.DefaultContext, "push", "-u").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommand("push", "-u").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func doGitPushTestRepositoryFail(dstPath string, args ...string) func(*testing.T) { | func doGitPushTestRepositoryFail(dstPath string, args ...string) func(*testing.T) { | ||||||
| 	return func(t *testing.T) { | 	return func(t *testing.T) { | ||||||
| 		_, _, err := git.NewCommand(git.DefaultContext, "push").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommand("push").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.Error(t, err) | 		assert.Error(t, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -180,28 +180,28 @@ func doGitAddSomeCommits(dstPath, branch string) func(*testing.T) { | |||||||
|  |  | ||||||
| func doGitCreateBranch(dstPath, branch string) func(*testing.T) { | func doGitCreateBranch(dstPath, branch string) func(*testing.T) { | ||||||
| 	return func(t *testing.T) { | 	return func(t *testing.T) { | ||||||
| 		_, _, err := git.NewCommand(git.DefaultContext, "checkout", "-b").AddDynamicArguments(branch).RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommand("checkout", "-b").AddDynamicArguments(branch).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func doGitCheckoutBranch(dstPath string, args ...string) func(*testing.T) { | func doGitCheckoutBranch(dstPath string, args ...string) func(*testing.T) { | ||||||
| 	return func(t *testing.T) { | 	return func(t *testing.T) { | ||||||
| 		_, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, git.AllowLFSFiltersArgs()...).AddArguments("checkout").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommandNoGlobals(git.AllowLFSFiltersArgs()...).AddArguments("checkout").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func doGitMerge(dstPath string, args ...string) func(*testing.T) { | func doGitMerge(dstPath string, args ...string) func(*testing.T) { | ||||||
| 	return func(t *testing.T) { | 	return func(t *testing.T) { | ||||||
| 		_, _, err := git.NewCommand(git.DefaultContext, "merge").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommand("merge").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func doGitPull(dstPath string, args ...string) func(*testing.T) { | func doGitPull(dstPath string, args ...string) func(*testing.T) { | ||||||
| 	return func(t *testing.T) { | 	return func(t *testing.T) { | ||||||
| 		_, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, git.AllowLFSFiltersArgs()...).AddArguments("pull").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommandNoGlobals(git.AllowLFSFiltersArgs()...).AddArguments("pull").AddArguments(git.ToTrustedCmdArgs(args)...).RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ func TestGitLFSSSH(t *testing.T) { | |||||||
| 			setting.LFS.AllowPureSSH = true | 			setting.LFS.AllowPureSSH = true | ||||||
| 			require.NoError(t, cfg.Save()) | 			require.NoError(t, cfg.Save()) | ||||||
|  |  | ||||||
| 			_, _, cmdErr := git.NewCommand(t.Context(), "config", "lfs.sshtransfer", "always").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, cmdErr := git.NewCommand("config", "lfs.sshtransfer", "always").RunStdString(t.Context(), &git.RunOpts{Dir: dstPath}) | ||||||
| 			assert.NoError(t, cmdErr) | 			assert.NoError(t, cmdErr) | ||||||
| 			lfsCommitAndPushTest(t, dstPath, 10) | 			lfsCommitAndPushTest(t, dstPath, 10) | ||||||
| 		}) | 		}) | ||||||
|   | |||||||
| @@ -101,10 +101,10 @@ func TestAgitPullPush(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		// push to create an agit pull request | 		// push to create an agit pull request | ||||||
| 		err = git.NewCommand(git.DefaultContext, "push", "origin", | 		err = git.NewCommand("push", "origin", | ||||||
| 			"-o", "title=test-title", "-o", "description=test-description", | 			"-o", "title=test-title", "-o", "description=test-description", | ||||||
| 			"HEAD:refs/for/master/test-agit-push", | 			"HEAD:refs/for/master/test-agit-push", | ||||||
| 		).Run(&git.RunOpts{Dir: dstPath}) | 		).Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		// check pull request exist | 		// check pull request exist | ||||||
| @@ -118,20 +118,20 @@ func TestAgitPullPush(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		// push 2 | 		// push 2 | ||||||
| 		err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master/test-agit-push").Run(&git.RunOpts{Dir: dstPath}) | 		err = git.NewCommand("push", "origin", "HEAD:refs/for/master/test-agit-push").Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		// reset to first commit | 		// reset to first commit | ||||||
| 		err = git.NewCommand(git.DefaultContext, "reset", "--hard", "HEAD~1").Run(&git.RunOpts{Dir: dstPath}) | 		err = git.NewCommand("reset", "--hard", "HEAD~1").Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		// test force push without confirm | 		// test force push without confirm | ||||||
| 		_, stderr, err := git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master/test-agit-push").RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, stderr, err := git.NewCommand("push", "origin", "HEAD:refs/for/master/test-agit-push").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.Error(t, err) | 		assert.Error(t, err) | ||||||
| 		assert.Contains(t, stderr, "[remote rejected] HEAD -> refs/for/master/test-agit-push (request `force-push` push option)") | 		assert.Contains(t, stderr, "[remote rejected] HEAD -> refs/for/master/test-agit-push (request `force-push` push option)") | ||||||
|  |  | ||||||
| 		// test force push with confirm | 		// test force push with confirm | ||||||
| 		err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master/test-agit-push", "-o", "force-push").Run(&git.RunOpts{Dir: dstPath}) | 		err = git.NewCommand("push", "origin", "HEAD:refs/for/master/test-agit-push", "-o", "force-push").Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -204,8 +204,8 @@ func TestPushPullRefs(t *testing.T) { | |||||||
| 		dstPath := t.TempDir() | 		dstPath := t.TempDir() | ||||||
| 		doGitClone(dstPath, u)(t) | 		doGitClone(dstPath, u)(t) | ||||||
|  |  | ||||||
| 		cmd := git.NewCommand(git.DefaultContext, "push", "--delete", "origin", "refs/pull/2/head") | 		cmd := git.NewCommand("push", "--delete", "origin", "refs/pull/2/head") | ||||||
| 		stdout, stderr, err := cmd.RunStdString(&git.RunOpts{ | 		stdout, stderr, err := cmd.RunStdString(git.DefaultContext, &git.RunOpts{ | ||||||
| 			Dir: dstPath, | 			Dir: dstPath, | ||||||
| 		}) | 		}) | ||||||
| 		assert.Error(t, err) | 		assert.Error(t, err) | ||||||
|   | |||||||
| @@ -265,7 +265,7 @@ func TestCreateAgitPullWithReadPermission(t *testing.T) { | |||||||
| 		t.Run("add commit", doGitAddSomeCommits(dstPath, "master")) | 		t.Run("add commit", doGitAddSomeCommits(dstPath, "master")) | ||||||
|  |  | ||||||
| 		t.Run("do agit pull create", func(t *testing.T) { | 		t.Run("do agit pull create", func(t *testing.T) { | ||||||
| 			err := git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic=" + "test-topic").Run(&git.RunOpts{Dir: dstPath}) | 			err := git.NewCommand("push", "origin", "HEAD:refs/for/master", "-o").AddDynamicArguments("topic="+"test-topic").Run(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			assert.NoError(t, err) | 			assert.NoError(t, err) | ||||||
| 		}) | 		}) | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -293,12 +293,12 @@ func TestCantMergeUnrelated(t *testing.T) { | |||||||
| 		}) | 		}) | ||||||
| 		path := repo_model.RepoPath(user1.Name, repo1.Name) | 		path := repo_model.RepoPath(user1.Name, repo1.Name) | ||||||
|  |  | ||||||
| 		err := git.NewCommand(git.DefaultContext, "read-tree", "--empty").Run(&git.RunOpts{Dir: path}) | 		err := git.NewCommand("read-tree", "--empty").Run(git.DefaultContext, &git.RunOpts{Dir: path}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		stdin := bytes.NewBufferString("Unrelated File") | 		stdin := bytes.NewBufferString("Unrelated File") | ||||||
| 		var stdout strings.Builder | 		var stdout strings.Builder | ||||||
| 		err = git.NewCommand(git.DefaultContext, "hash-object", "-w", "--stdin").Run(&git.RunOpts{ | 		err = git.NewCommand("hash-object", "-w", "--stdin").Run(git.DefaultContext, &git.RunOpts{ | ||||||
| 			Dir:    path, | 			Dir:    path, | ||||||
| 			Stdin:  stdin, | 			Stdin:  stdin, | ||||||
| 			Stdout: &stdout, | 			Stdout: &stdout, | ||||||
| @@ -307,10 +307,10 @@ func TestCantMergeUnrelated(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		sha := strings.TrimSpace(stdout.String()) | 		sha := strings.TrimSpace(stdout.String()) | ||||||
|  |  | ||||||
| 		_, _, err = git.NewCommand(git.DefaultContext, "update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments("100644", sha, "somewher-over-the-rainbow").RunStdString(&git.RunOpts{Dir: path}) | 		_, _, err = git.NewCommand("update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments("100644", sha, "somewher-over-the-rainbow").RunStdString(git.DefaultContext, &git.RunOpts{Dir: path}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		treeSha, _, err := git.NewCommand(git.DefaultContext, "write-tree").RunStdString(&git.RunOpts{Dir: path}) | 		treeSha, _, err := git.NewCommand("write-tree").RunStdString(git.DefaultContext, &git.RunOpts{Dir: path}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		treeSha = strings.TrimSpace(treeSha) | 		treeSha = strings.TrimSpace(treeSha) | ||||||
|  |  | ||||||
| @@ -330,8 +330,8 @@ func TestCantMergeUnrelated(t *testing.T) { | |||||||
| 		_, _ = messageBytes.WriteString("\n") | 		_, _ = messageBytes.WriteString("\n") | ||||||
|  |  | ||||||
| 		stdout.Reset() | 		stdout.Reset() | ||||||
| 		err = git.NewCommand(git.DefaultContext, "commit-tree").AddDynamicArguments(treeSha). | 		err = git.NewCommand("commit-tree").AddDynamicArguments(treeSha). | ||||||
| 			Run(&git.RunOpts{ | 			Run(git.DefaultContext, &git.RunOpts{ | ||||||
| 				Env:    env, | 				Env:    env, | ||||||
| 				Dir:    path, | 				Dir:    path, | ||||||
| 				Stdin:  messageBytes, | 				Stdin:  messageBytes, | ||||||
| @@ -340,7 +340,7 @@ func TestCantMergeUnrelated(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		commitSha := strings.TrimSpace(stdout.String()) | 		commitSha := strings.TrimSpace(stdout.String()) | ||||||
|  |  | ||||||
| 		_, _, err = git.NewCommand(git.DefaultContext, "branch", "unrelated").AddDynamicArguments(commitSha).RunStdString(&git.RunOpts{Dir: path}) | 		_, _, err = git.NewCommand("branch", "unrelated").AddDynamicArguments(commitSha).RunStdString(git.DefaultContext, &git.RunOpts{Dir: path}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		testEditFileToNewBranch(t, session, "user1", "repo1", "master", "conflict", "README.md", "Hello, World (Edited Once)\n") | 		testEditFileToNewBranch(t, session, "user1", "repo1", "master", "conflict", "README.md", "Hello, World (Edited Once)\n") | ||||||
| @@ -914,13 +914,13 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing. | |||||||
|  |  | ||||||
| 		stderrBuf := &bytes.Buffer{} | 		stderrBuf := &bytes.Buffer{} | ||||||
|  |  | ||||||
| 		err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o"). | 		err = git.NewCommand("push", "origin", "HEAD:refs/for/master", "-o"). | ||||||
| 			AddDynamicArguments(`topic=test/head2`). | 			AddDynamicArguments(`topic=test/head2`). | ||||||
| 			AddArguments("-o"). | 			AddArguments("-o"). | ||||||
| 			AddDynamicArguments(`title="create a test pull request with agit"`). | 			AddDynamicArguments(`title="create a test pull request with agit"`). | ||||||
| 			AddArguments("-o"). | 			AddArguments("-o"). | ||||||
| 			AddDynamicArguments(`description="This PR is a test pull request which created with agit"`). | 			AddDynamicArguments(`description="This PR is a test pull request which created with agit"`). | ||||||
| 			Run(&git.RunOpts{Dir: dstPath, Stderr: stderrBuf}) | 			Run(git.DefaultContext, &git.RunOpts{Dir: dstPath, Stderr: stderrBuf}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  |  | ||||||
| 		assert.Contains(t, stderrBuf.String(), setting.AppURL+"user2/repo1/pulls/6") | 		assert.Contains(t, stderrBuf.String(), setting.AppURL+"user2/repo1/pulls/6") | ||||||
|   | |||||||
| @@ -55,10 +55,10 @@ func TestCreateNewTagProtected(t *testing.T) { | |||||||
|  |  | ||||||
| 			doGitClone(dstPath, u)(t) | 			doGitClone(dstPath, u)(t) | ||||||
|  |  | ||||||
| 			_, _, err := git.NewCommand(git.DefaultContext, "tag", "v-2").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err := git.NewCommand("tag", "v-2").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			assert.NoError(t, err) | 			assert.NoError(t, err) | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "--tags").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err = git.NewCommand("push", "--tags").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			assert.Error(t, err) | 			assert.Error(t, err) | ||||||
| 			assert.Contains(t, err.Error(), "Tag v-2 is protected") | 			assert.Contains(t, err.Error(), "Tag v-2 is protected") | ||||||
| 		}) | 		}) | ||||||
| @@ -75,20 +75,20 @@ func TestCreateNewTagProtected(t *testing.T) { | |||||||
|  |  | ||||||
| 			doGitClone(dstPath, u)(t) | 			doGitClone(dstPath, u)(t) | ||||||
|  |  | ||||||
| 			_, _, err := git.NewCommand(git.DefaultContext, "tag", "v-1.1", "-m", "force update", "--force").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err := git.NewCommand("tag", "v-1.1", "-m", "force update", "--force").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "--tags").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err = git.NewCommand("push", "--tags").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "tag", "v-1.1", "-m", "force update v2", "--force").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err = git.NewCommand("tag", "v-1.1", "-m", "force update v2", "--force").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "--tags").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err = git.NewCommand("push", "--tags").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.Error(t, err) | 			require.Error(t, err) | ||||||
| 			assert.Contains(t, err.Error(), "the tag already exists in the remote") | 			assert.Contains(t, err.Error(), "the tag already exists in the remote") | ||||||
|  |  | ||||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "--tags", "--force").RunStdString(&git.RunOpts{Dir: dstPath}) | 			_, _, err = git.NewCommand("push", "--tags", "--force").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 			require.NoError(t, err) | 			require.NoError(t, err) | ||||||
| 			req := NewRequestf(t, "GET", "/%s/releases/tag/v-1.1", repo.FullName()) | 			req := NewRequestf(t, "GET", "/%s/releases/tag/v-1.1", repo.FullName()) | ||||||
| 			resp := MakeRequest(t, req, http.StatusOK) | 			resp := MakeRequest(t, req, http.StatusOK) | ||||||
| @@ -137,15 +137,15 @@ func TestRepushTag(t *testing.T) { | |||||||
| 		doGitClone(dstPath, u)(t) | 		doGitClone(dstPath, u)(t) | ||||||
|  |  | ||||||
| 		// create and push a tag | 		// create and push a tag | ||||||
| 		_, _, err := git.NewCommand(git.DefaultContext, "tag", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err := git.NewCommand("tag", "v2.0").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		_, _, err = git.NewCommand(git.DefaultContext, "push", "origin", "--tags", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err = git.NewCommand("push", "origin", "--tags", "v2.0").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		// create a release for the tag | 		// create a release for the tag | ||||||
| 		createdRelease := createNewReleaseUsingAPI(t, token, owner, repo, "v2.0", "", "Release of v2.0", "desc") | 		createdRelease := createNewReleaseUsingAPI(t, token, owner, repo, "v2.0", "", "Release of v2.0", "desc") | ||||||
| 		assert.False(t, createdRelease.IsDraft) | 		assert.False(t, createdRelease.IsDraft) | ||||||
| 		// delete the tag | 		// delete the tag | ||||||
| 		_, _, err = git.NewCommand(git.DefaultContext, "push", "origin", "--delete", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err = git.NewCommand("push", "origin", "--delete", "v2.0").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		// query the release by API and it should be a draft | 		// query the release by API and it should be a draft | ||||||
| 		req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, "v2.0")) | 		req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, "v2.0")) | ||||||
| @@ -154,7 +154,7 @@ func TestRepushTag(t *testing.T) { | |||||||
| 		DecodeJSON(t, resp, &respRelease) | 		DecodeJSON(t, resp, &respRelease) | ||||||
| 		assert.True(t, respRelease.IsDraft) | 		assert.True(t, respRelease.IsDraft) | ||||||
| 		// re-push the tag | 		// re-push the tag | ||||||
| 		_, _, err = git.NewCommand(git.DefaultContext, "push", "origin", "--tags", "v2.0").RunStdString(&git.RunOpts{Dir: dstPath}) | 		_, _, err = git.NewCommand("push", "origin", "--tags", "v2.0").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		// query the release by API and it should not be a draft | 		// query the release by API and it should not be a draft | ||||||
| 		req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, "v2.0")) | 		req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, "v2.0")) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 TheFox0x7
					TheFox0x7