Skip to content

Commit 0e834b0

Browse files
committed
fix
1 parent 2de2656 commit 0e834b0

File tree

7 files changed

+28
-20
lines changed

7 files changed

+28
-20
lines changed

modules/git/gitcmd/command.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,11 @@ func (c *Command) WithUseContextTimeout(useContextTimeout bool) *Command {
310310
// For most cases, "Run" family functions can get its caller info automatically
311311
// But if you need to call "Run" family functions in a wrapper function: "FeatureFunc -> GeneralWrapperFunc -> RunXxx",
312312
// then you can to call this function in GeneralWrapperFunc to set the caller info of FeatureFunc.
313+
// The caller info can only be set once.
313314
func (c *Command) WithParentCallerInfo(optInfo ...string) *Command {
315+
if c.opts.callerInfo != "" {
316+
return c
317+
}
314318
if len(optInfo) > 0 {
315319
c.opts.callerInfo = optInfo[0]
316320
return c
@@ -428,7 +432,8 @@ type runStdError struct {
428432
}
429433

430434
func (r *runStdError) Error() string {
431-
// the stderr must be in the returned error text, some code only checks `strings.Contains(err.Error(), "git error")`
435+
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
436+
// But a lof of code only checks `strings.Contains(err.Error(), "git error")`
432437
if r.errMsg == "" {
433438
r.errMsg = ConcatenateError(r.err, r.stderr).Error()
434439
}
@@ -458,7 +463,7 @@ func (c *Command) RunStdString(ctx context.Context) (stdout, stderr string, runE
458463
}
459464

460465
// RunStdBytes runs the command and returns stdout/stderr as bytes. and store stderr to returned error (err combined with stderr).
461-
func (c *Command) RunStdBytes(ctx context.Context) ( /*stdout*/ []byte /*stderr*/, []byte /*runErr*/, RunStdError) {
466+
func (c *Command) RunStdBytes(ctx context.Context) (stdout, stderr []byte, runErr RunStdError) {
462467
return c.WithParentCallerInfo().runStdBytes(ctx)
463468
}
464469

@@ -467,14 +472,15 @@ func (c *Command) runStdBytes(ctx context.Context) ( /*stdout*/ []byte /*stderr*
467472
// we must panic here, otherwise there would be bugs if developers set Stdin/Stderr by mistake, and it would be very difficult to debug
468473
panic("stdout and stderr field must be nil when using RunStdBytes")
469474
}
470-
471475
stdoutBuf := &bytes.Buffer{}
472476
stderrBuf := &bytes.Buffer{}
473477
err := c.WithParentCallerInfo().
474478
WithStdout(stdoutBuf).
475479
WithStderr(stderrBuf).
476480
Run(ctx)
477481
if err != nil {
482+
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
483+
// But a lot of code depends on it, so we have to keep this behavior
478484
return nil, stderrBuf.Bytes(), &runStdError{err: err, stderr: util.UnsafeBytesToString(stderrBuf.Bytes())}
479485
}
480486
// even if there is no err, there could still be some stderr output

modules/git/gitcmd/command_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func TestRunWithContextStd(t *testing.T) {
4141
if assert.Error(t, err) {
4242
assert.Equal(t, stderr, err.Stderr())
4343
assert.Equal(t, "fatal: Not a valid object name no-such\n", err.Stderr())
44+
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
4445
assert.Equal(t, "exit status 128 - fatal: Not a valid object name no-such\n", err.Error())
4546
assert.Empty(t, stdout)
4647
}
@@ -52,6 +53,7 @@ func TestRunWithContextStd(t *testing.T) {
5253
if assert.Error(t, err) {
5354
assert.Equal(t, string(stderr), err.Stderr())
5455
assert.Equal(t, "fatal: Not a valid object name no-such\n", err.Stderr())
56+
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message
5557
assert.Equal(t, "exit status 128 - fatal: Not a valid object name no-such\n", err.Error())
5658
assert.Empty(t, stdout)
5759
}

services/pull/merge.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use
406406
// Push back to upstream.
407407
// This cause an api call to "/api/internal/hook/post-receive/...",
408408
// If it's merge, all db transaction and operations should be there but not here to prevent deadlock.
409-
if err := mergeCtx.WithCmd(pushCmd).Run(ctx); err != nil {
409+
if err := mergeCtx.PrepareGitCmd(pushCmd).Run(ctx); err != nil {
410410
if strings.Contains(mergeCtx.errbuf.String(), "non-fast-forward") {
411411
return "", &git.ErrPushOutOfDate{
412412
StdOut: mergeCtx.outbuf.String(),
@@ -440,7 +440,7 @@ func commitAndSignNoAuthor(ctx *mergeContext, message string) error {
440440
}
441441
cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
442442
}
443-
if err := ctx.WithCmd(cmdCommit).Run(ctx); err != nil {
443+
if err := ctx.PrepareGitCmd(cmdCommit).Run(ctx); err != nil {
444444
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
445445
return fmt.Errorf("git commit %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
446446
}
@@ -501,7 +501,7 @@ func (err ErrMergeDivergingFastForwardOnly) Error() string {
501501
}
502502

503503
func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *gitcmd.Command) error {
504-
if err := ctx.WithCmd(cmd).Run(ctx); err != nil {
504+
if err := ctx.PrepareGitCmd(cmd).Run(ctx); err != nil {
505505
// Merge will leave a MERGE_HEAD file in the .git folder if there is a conflict
506506
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "MERGE_HEAD")); statErr == nil {
507507
// We have a merge conflict error

services/pull/merge_prepare.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type mergeContext struct {
3232
env []string
3333
}
3434

35-
func (ctx *mergeContext) WithCmd(cmd *gitcmd.Command) *gitcmd.Command {
35+
func (ctx *mergeContext) PrepareGitCmd(cmd *gitcmd.Command) *gitcmd.Command {
3636
ctx.outbuf.Reset()
3737
ctx.errbuf.Reset()
3838
return cmd.WithEnv(ctx.env).
@@ -73,7 +73,7 @@ func createTemporaryRepoForMerge(ctx context.Context, pr *issues_model.PullReque
7373
}
7474

7575
if expectedHeadCommitID != "" {
76-
trackingCommitID, _, err := mergeCtx.WithCmd(gitcmd.NewCommand("show-ref", "--hash").AddDynamicArguments(git.BranchPrefix + trackingBranch)).RunStdString(ctx)
76+
trackingCommitID, _, err := mergeCtx.PrepareGitCmd(gitcmd.NewCommand("show-ref", "--hash").AddDynamicArguments(git.BranchPrefix + trackingBranch)).RunStdString(ctx)
7777
if err != nil {
7878
defer cancel()
7979
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,7 +151,7 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
151151
}
152152

153153
setConfig := func(key, value string) error {
154-
if err := ctx.WithCmd(gitcmd.NewCommand("config", "--local").AddDynamicArguments(key, value)).
154+
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("config", "--local").AddDynamicArguments(key, value)).
155155
Run(ctx); err != nil {
156156
log.Error("git config [%s -> %q]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
157157
return fmt.Errorf("git config [%s -> %q]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
@@ -184,7 +184,7 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
184184
}
185185

186186
// Read base branch index
187-
if err := ctx.WithCmd(gitcmd.NewCommand("read-tree", "HEAD")).
187+
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("read-tree", "HEAD")).
188188
Run(ctx); err != nil {
189189
log.Error("git read-tree HEAD: %v\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
190190
return fmt.Errorf("Unable to read base branch in to the index: %w\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
@@ -272,15 +272,15 @@ func (err ErrRebaseConflicts) Error() string {
272272
// if there is a conflict it will return an ErrRebaseConflicts
273273
func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle) error {
274274
// Checkout head branch
275-
if err := ctx.WithCmd(gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch)).
275+
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch)).
276276
Run(ctx); err != nil {
277277
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())
278278
}
279279
ctx.outbuf.Reset()
280280
ctx.errbuf.Reset()
281281

282282
// Rebase before merging
283-
if err := ctx.WithCmd(gitcmd.NewCommand("rebase").AddDynamicArguments(baseBranch)).
283+
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("rebase").AddDynamicArguments(baseBranch)).
284284
Run(ctx); err != nil {
285285
// Rebase will leave a REBASE_HEAD file in .git if there is a conflict
286286
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "REBASE_HEAD")); statErr == nil {

services/pull/merge_rebase.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func doMergeStyleRebase(ctx *mergeContext, mergeStyle repo_model.MergeStyle, mes
109109
}
110110

111111
// Checkout base branch again
112-
if err := ctx.WithCmd(gitcmd.NewCommand("checkout").AddDynamicArguments(baseBranch)).
112+
if err := ctx.PrepareGitCmd(gitcmd.NewCommand("checkout").AddDynamicArguments(baseBranch)).
113113
Run(ctx); err != nil {
114114
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())
115115
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())

services/pull/merge_squash.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error {
8080
}
8181
cmdCommit.AddOptionFormat("-S%s", ctx.signKey.KeyID)
8282
}
83-
if err := ctx.WithCmd(cmdCommit).Run(ctx); err != nil {
83+
if err := ctx.PrepareGitCmd(cmdCommit).Run(ctx); err != nil {
8484
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
8585
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())
8686
}

services/pull/temp_repo.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type prTmpRepoContext struct {
3737
errbuf *strings.Builder // any use should be preceded by a Reset and preferably after use
3838
}
3939

40-
func (ctx *prTmpRepoContext) WithCmd(cmd *gitcmd.Command) *gitcmd.Command {
40+
func (ctx *prTmpRepoContext) PrepareGitCmd(cmd *gitcmd.Command) *gitcmd.Command {
4141
ctx.outbuf.Reset()
4242
ctx.errbuf.Reset()
4343
return cmd.WithDir(ctx.tmpBasePath).
@@ -130,22 +130,22 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
130130
return nil, nil, fmt.Errorf("Unable to add base repository to temporary repo [%s -> tmpBasePath]: %w", pr.BaseRepo.FullName(), err)
131131
}
132132

133-
if err := prCtx.WithCmd(gitcmd.NewCommand("remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath)).
133+
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath)).
134134
Run(ctx); err != nil {
135135
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())
136136
cancel()
137137
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())
138138
}
139139

140-
if err := prCtx.WithCmd(gitcmd.NewCommand("fetch", "origin").AddArguments(fetchArgs...).
140+
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("fetch", "origin").AddArguments(fetchArgs...).
141141
AddDashesAndList(git.BranchPrefix+pr.BaseBranch+":"+git.BranchPrefix+baseBranch, git.BranchPrefix+pr.BaseBranch+":"+git.BranchPrefix+"original_"+baseBranch)).
142142
Run(ctx); err != nil {
143143
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())
144144
cancel()
145145
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())
146146
}
147147

148-
if err := prCtx.WithCmd(gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch)).
148+
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch)).
149149
Run(ctx); err != nil {
150150
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())
151151
cancel()
@@ -158,7 +158,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
158158
return nil, nil, fmt.Errorf("Unable to add head base repository to temporary repo [%s -> tmpBasePath]: %w", pr.HeadRepo.FullName(), err)
159159
}
160160

161-
if err := prCtx.WithCmd(gitcmd.NewCommand("remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath)).
161+
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath)).
162162
Run(ctx); err != nil {
163163
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())
164164
cancel()
@@ -176,7 +176,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
176176
} else {
177177
headBranch = pr.GetGitHeadRefName()
178178
}
179-
if err := prCtx.WithCmd(gitcmd.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch)).
179+
if err := prCtx.PrepareGitCmd(gitcmd.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch)).
180180
Run(ctx); err != nil {
181181
cancel()
182182
if !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {

0 commit comments

Comments
 (0)