From f8a48b61fc95b9a7a4afc4d7a28c358439dbf6ff Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 15 Nov 2025 17:47:35 +0100 Subject: [PATCH] Suppress output from background fetch However, show it when there was an error. This is important for the case that a fork that you have as a remote was deleted, in which case the command log is the only way to get notified about that. --- pkg/commands/git_commands/sync.go | 1 + pkg/commands/git_commands/sync_test.go | 5 +++++ pkg/commands/oscommands/cmd_obj.go | 15 +++++++++++++++ pkg/commands/oscommands/cmd_obj_runner.go | 12 +++++++++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pkg/commands/git_commands/sync.go b/pkg/commands/git_commands/sync.go index 0f5559a7b..d64a0910c 100644 --- a/pkg/commands/git_commands/sync.go +++ b/pkg/commands/git_commands/sync.go @@ -79,6 +79,7 @@ func (self *SyncCommands) FetchBackgroundCmdObj() *oscommands.CmdObj { cmdObj := self.cmd.New(cmdArgs) cmdObj.DontLog().FailOnCredentialRequest() + cmdObj.SuppressOutputUnlessError() return cmdObj } diff --git a/pkg/commands/git_commands/sync_test.go b/pkg/commands/git_commands/sync_test.go index 99f934a16..fdc44a6b9 100644 --- a/pkg/commands/git_commands/sync_test.go +++ b/pkg/commands/git_commands/sync_test.go @@ -104,6 +104,7 @@ func TestSyncPush(t *testing.T) { if err == nil { assert.True(t, cmdObj.ShouldLog()) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.PROMPT) + assert.False(t, cmdObj.ShouldSuppressOutputUnlessError()) } s.test(cmdObj, err) }) @@ -124,6 +125,7 @@ func TestSyncFetch(t *testing.T) { test: func(cmdObj *oscommands.CmdObj) { assert.True(t, cmdObj.ShouldLog()) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.PROMPT) + assert.False(t, cmdObj.ShouldSuppressOutputUnlessError()) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--no-write-fetch-head"}) }, }, @@ -133,6 +135,7 @@ func TestSyncFetch(t *testing.T) { test: func(cmdObj *oscommands.CmdObj) { assert.True(t, cmdObj.ShouldLog()) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.PROMPT) + assert.False(t, cmdObj.ShouldSuppressOutputUnlessError()) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--all", "--no-write-fetch-head"}) }, }, @@ -162,6 +165,7 @@ func TestSyncFetchBackground(t *testing.T) { test: func(cmdObj *oscommands.CmdObj) { assert.False(t, cmdObj.ShouldLog()) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.FAIL) + assert.True(t, cmdObj.ShouldSuppressOutputUnlessError()) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--no-write-fetch-head"}) }, }, @@ -171,6 +175,7 @@ func TestSyncFetchBackground(t *testing.T) { test: func(cmdObj *oscommands.CmdObj) { assert.False(t, cmdObj.ShouldLog()) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.FAIL) + assert.True(t, cmdObj.ShouldSuppressOutputUnlessError()) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--all", "--no-write-fetch-head"}) }, }, diff --git a/pkg/commands/oscommands/cmd_obj.go b/pkg/commands/oscommands/cmd_obj.go index 96392dcb4..24d2ca511 100644 --- a/pkg/commands/oscommands/cmd_obj.go +++ b/pkg/commands/oscommands/cmd_obj.go @@ -22,6 +22,9 @@ type CmdObj struct { // see StreamOutput() streamOutput bool + // see SuppressOutputUnlessError() + suppressOutputUnlessError bool + // see UsePty() usePty bool @@ -123,6 +126,18 @@ func (self *CmdObj) StreamOutput() *CmdObj { return self } +// when you call this, the streamed output will be suppressed unless there is an error +func (self *CmdObj) SuppressOutputUnlessError() *CmdObj { + self.suppressOutputUnlessError = true + + return self +} + +// returns true if SuppressOutputUnlessError() was called +func (self *CmdObj) ShouldSuppressOutputUnlessError() bool { + return self.suppressOutputUnlessError +} + // returns true if StreamOutput() was called func (self *CmdObj) ShouldStreamOutput() bool { return self.streamOutput diff --git a/pkg/commands/oscommands/cmd_obj_runner.go b/pkg/commands/oscommands/cmd_obj_runner.go index 953937706..b964edce7 100644 --- a/pkg/commands/oscommands/cmd_obj_runner.go +++ b/pkg/commands/oscommands/cmd_obj_runner.go @@ -227,7 +227,13 @@ func (self *cmdObjRunner) runAndStreamAux( cmdObj *CmdObj, onRun func(*cmdHandler, io.Writer), ) error { - cmdWriter := self.guiIO.newCmdWriterFn() + var cmdWriter io.Writer + var combinedOutput bytes.Buffer + if cmdObj.ShouldSuppressOutputUnlessError() { + cmdWriter = &combinedOutput + } else { + cmdWriter = self.guiIO.newCmdWriterFn() + } if cmdObj.ShouldLog() { self.logCmdObj(cmdObj) @@ -267,6 +273,10 @@ func (self *cmdObjRunner) runAndStreamAux( self.log.Infof("%s (%s)", cmdObj.ToString(), time.Since(t)) if err != nil { + if cmdObj.suppressOutputUnlessError { + _, _ = self.guiIO.newCmdWriterFn().Write(combinedOutput.Bytes()) + } + errStr := stderr.String() if errStr != "" { return errors.New(errStr)