From e6a193e5d846950f1fef364092fb7613e24c4ba4 Mon Sep 17 00:00:00 2001 From: 3v0k4 Date: Mon, 16 Feb 2026 08:39:57 +0100 Subject: [PATCH 1/2] refactor --- .../repository_adapters/git_adapter.rb | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/knapsack_pro/repository_adapters/git_adapter.rb b/lib/knapsack_pro/repository_adapters/git_adapter.rb index 00eb9998..c28eccd0 100644 --- a/lib/knapsack_pro/repository_adapters/git_adapter.rb +++ b/lib/knapsack_pro/repository_adapters/git_adapter.rb @@ -43,20 +43,17 @@ def build_author private def git_commit_authors - if KnapsackPro::Config::Env.ci? && shallow_repository? - command = 'git fetch --shallow-since "one month ago" --quiet 2>/dev/null' - begin - Timeout.timeout(5) do - `#{command}` - end - rescue Timeout::Error - KnapsackPro.logger.debug("Skip the `#{command}` command because it took too long.") - end - end - + git_unshallow if KnapsackPro::Config::Env.ci? && shallow_repository? `git log --since "one month ago" 2>/dev/null | git shortlog --summary --email 2>/dev/null` end + def git_unshallow + command = 'git fetch --shallow-since "one month ago" --quiet 2>/dev/null' + Timeout.timeout(5) { `#{command}` } + rescue Timeout::Error + KnapsackPro.logger.debug("Skip the `#{command}` command because it took too long.") + end + def git_build_author `git log --format="%aN <%aE>" -1 2>/dev/null` end From 70624233a86e3c220b6a246a1385cd7b2e1972c7 Mon Sep 17 00:00:00 2001 From: 3v0k4 Date: Mon, 16 Feb 2026 09:51:52 +0100 Subject: [PATCH 2/2] fix: enforce timeout --- CHANGELOG.md | 2 ++ .../repository_adapters/git_adapter.rb | 32 ++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c7e70f..89f22b93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### Unreleased +* (patch) Fix 5-second timeout when unshallowing git repo (https://github.com/KnapsackPro/knapsack_pro-ruby/pull/328) + ### 9.2.2 * RSpec: Skip unneeded API call when queue is already initialized in `rake knapsack_pro:queue:rspec:initialize` and improve error handling (https://github.com/KnapsackPro/knapsack_pro-ruby/pull/326). diff --git a/lib/knapsack_pro/repository_adapters/git_adapter.rb b/lib/knapsack_pro/repository_adapters/git_adapter.rb index c28eccd0..0db77926 100644 --- a/lib/knapsack_pro/repository_adapters/git_adapter.rb +++ b/lib/knapsack_pro/repository_adapters/git_adapter.rb @@ -48,10 +48,34 @@ def git_commit_authors end def git_unshallow - command = 'git fetch --shallow-since "one month ago" --quiet 2>/dev/null' - Timeout.timeout(5) { `#{command}` } - rescue Timeout::Error - KnapsackPro.logger.debug("Skip the `#{command}` command because it took too long.") + args = ['git', 'fetch', '--quiet', '--shallow-since', 'one month ago'] + + begin + pid = Process.spawn(*args, [:out, :err] => File::NULL) + rescue StandardError => e + KnapsackPro.logger.debug("Failed to unshallow (#{args.join(' ')}): #{e.message}") + return + end + + begin + Timeout.timeout(5) { safe_waitpid(pid) } + rescue Timeout::Error + safe_kill(pid) + Timeout.timeout(1) { safe_waitpid(pid) } rescue Timeout::Error + KnapsackPro.logger.debug("Failed to unshallow (#{args.join(' ')}) in 5 seconds") + end + end + + def safe_waitpid(pid) + Process.waitpid(pid) + rescue Errno::ECHILD + nil + end + + def safe_kill(pid) + Process.kill('KILL', pid) + rescue Errno::ESRCH + nil end def git_build_author