From a42d79f228b6e1ad8175b384f713366815c6f543 Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Fri, 2 Jan 2026 12:13:36 +0800 Subject: [PATCH] retry on ref lock errors during fetch/pull Extends the existing retry logic to handle transient lock-related errors beyond just .git/index.lock. This now also retries when encountering "cannot lock ref" or "cannot update ref" errors, which can occur intermittently during fetch/pull operations in large repositories. Related to #5124 Signed-off-by: majiayu000 <1835304752@qq.com> --- pkg/commands/git_cmd_obj_runner.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pkg/commands/git_cmd_obj_runner.go b/pkg/commands/git_cmd_obj_runner.go index fd98bc84f..668feef93 100644 --- a/pkg/commands/git_cmd_obj_runner.go +++ b/pkg/commands/git_cmd_obj_runner.go @@ -20,6 +20,13 @@ type gitCmdObjRunner struct { innerRunner oscommands.ICmdObjRunner } +// isRetryableError returns true if the error output indicates a transient +// lock-related error that may succeed on retry +func isRetryableError(output string) bool { + return strings.Contains(output, ".git/index.lock") || + strings.Contains(output, "cannot lock ref") +} + func (self *gitCmdObjRunner) Run(cmdObj *oscommands.CmdObj) error { _, err := self.RunWithOutput(cmdObj) return err @@ -32,12 +39,12 @@ func (self *gitCmdObjRunner) RunWithOutput(cmdObj *oscommands.CmdObj) (string, e newCmdObj := cmdObj.Clone() output, err = self.innerRunner.RunWithOutput(newCmdObj) - if err == nil || !strings.Contains(output, ".git/index.lock") { + if err == nil || !isRetryableError(output) { return output, err } - // if we have an error based on the index lock, we should wait a bit and then retry - self.log.Warn("index.lock prevented command from running. Retrying command after a small wait") + // if we have an error based on a lock, we should wait a bit and then retry + self.log.Warn("lock error prevented command from running. Retrying command after a small wait") time.Sleep(WaitTime) } @@ -51,12 +58,12 @@ func (self *gitCmdObjRunner) RunWithOutputs(cmdObj *oscommands.CmdObj) (string, newCmdObj := cmdObj.Clone() stdout, stderr, err = self.innerRunner.RunWithOutputs(newCmdObj) - if err == nil || !strings.Contains(stdout+stderr, ".git/index.lock") { + if err == nil || !isRetryableError(stdout+stderr) { return stdout, stderr, err } - // if we have an error based on the index lock, we should wait a bit and then retry - self.log.Warn("index.lock prevented command from running. Retrying command after a small wait") + // if we have an error based on a lock, we should wait a bit and then retry + self.log.Warn("lock error prevented command from running. Retrying command after a small wait") time.Sleep(WaitTime) }