Summary
The shadowing fix in #123 (commit d62e8c1) renamed local variables from default_branch to detected_branch / remote_default_branch, which resolved the specific case tested. However, those new names are now the dangerous ones. The pattern repeats across three functions.
Root cause
printf -v "$result_var" writes to the variable named by result_var in the current function's scope. If the caller passes a name that collides with a local variable in the function, printf -v silently writes to the function's local — which disappears on return — leaving the caller's variable unchanged.
| Function |
Shadowing local(s) |
gh_detect_default_branch |
detected_branch |
gh_repo_default_branch |
remote_default_branch, status |
gh_infer_repo_from_origin |
inferred_repo, remote_url |
Reproducer
source lib/bash/std/lib_std.sh
source lib/bash/gh/lib_gh.sh
repo_dir=... # any repo with a main branch
# Passes: 'branch' does not collide with locals
local branch=""
gh_detect_default_branch "$repo_dir" branch
echo "$branch" # → "main"
# Silent failure: 'detected_branch' collides with the function's local
local detected_branch=""
gh_detect_default_branch "$repo_dir" detected_branch
echo "$detected_branch" # → "" (caller variable was never set)
Fix
Rename all private intermediates to __-prefixed names in the three functions, consistent with the pattern used in lib_str.sh and lib_list.sh. For example:
gh_detect_default_branch() {
local repo_dir="$1"
local result_var="${2:-}"
local __gh_detect_branch__="" # was: detected_branch
...
printf -v "$result_var" '%s' "$__gh_detect_branch__"
}
Add regression tests for detected_branch, remote_default_branch, and inferred_repo as the result variable name (similar to the default_branch tests added in #123).
Summary
The shadowing fix in #123 (commit d62e8c1) renamed local variables from
default_branchtodetected_branch/remote_default_branch, which resolved the specific case tested. However, those new names are now the dangerous ones. The pattern repeats across three functions.Root cause
printf -v "$result_var"writes to the variable named byresult_varin the current function's scope. If the caller passes a name that collides with a local variable in the function,printf -vsilently writes to the function's local — which disappears on return — leaving the caller's variable unchanged.gh_detect_default_branchdetected_branchgh_repo_default_branchremote_default_branch,statusgh_infer_repo_from_origininferred_repo,remote_urlReproducer
Fix
Rename all private intermediates to
__-prefixed names in the three functions, consistent with the pattern used inlib_str.shandlib_list.sh. For example:Add regression tests for
detected_branch,remote_default_branch, andinferred_repoas the result variable name (similar to thedefault_branchtests added in #123).