From 1c52896a7fe9f899ca9f720a6942221ec1ac7a69 Mon Sep 17 00:00:00 2001 From: Amolith Date: Sun, 18 Jan 2026 11:04:08 -0700 Subject: [PATCH] fix(fetch): exit 0 on partial remote failure Previously exited non-zero if ANY remote failed, even when others succeeded. Now fetches each remote individually, prints warnings for failures, and exits 0 if at least one remote succeeded. Assisted-by: Claude Opus 4.5 via Amp --- src/wt/cmd/fetch.lua | 52 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/wt/cmd/fetch.lua b/src/wt/cmd/fetch.lua index 31e7f6b82915ab7e5c31e05fef88db4872376dd4..80e74c0cf6977f998252e91c7ee6eaeb2f946639 100644 --- a/src/wt/cmd/fetch.lua +++ b/src/wt/cmd/fetch.lua @@ -9,7 +9,25 @@ local git = require("wt.git") ---@class wt.cmd.fetch local M = {} ----Fetch all remotes with pruning +---Get list of configured remotes +---@param git_dir string +---@return string[] remotes +local function get_remotes(git_dir) + local output, code = shell.run_cmd("GIT_DIR=" .. git_dir .. " git remote") + if code ~= 0 then + return {} + end + local remotes = {} + for line in output:gmatch("[^\n]+") do + local trimmed = line:match("^%s*(.-)%s*$") + if trimmed and trimmed ~= "" then + table.insert(remotes, trimmed) + end + end + return remotes +end + +---Fetch all remotes with pruning, tolerating partial failures function M.cmd_fetch() local root, err = git.find_project_root() if not root then @@ -18,9 +36,35 @@ function M.cmd_fetch() end local git_dir = root .. "/.bare" - local output, code = shell.run_cmd("GIT_DIR=" .. git_dir .. " git fetch --all --prune") - io.write(output) - if code ~= 0 then + local remotes = get_remotes(git_dir) + + if #remotes == 0 then + shell.die("no remotes configured", exit.EXIT_USER_ERROR) + return + end + + local succeeded = 0 + local failures = {} + + for _, remote in ipairs(remotes) do + local output, code = shell.run_cmd("GIT_DIR=" .. git_dir .. " git fetch --prune " .. shell.quote(remote)) + if code == 0 then + succeeded = succeeded + 1 + io.write(output) + else + table.insert(failures, { remote = remote, output = output }) + end + end + + for _, f in ipairs(failures) do + io.stderr:write("warning: failed to fetch " .. f.remote .. "\n") + if f.output and f.output ~= "" then + io.stderr:write(f.output) + end + end + + if succeeded == 0 then + io.stderr:write("error: all remotes failed to fetch\n") os.exit(exit.EXIT_SYSTEM_ERROR) end end