From bfb0e05ffa993652206e113d1d234dec2359a7e2 Mon Sep 17 00:00:00 2001 From: Matthew Boston Date: Fri, 31 Oct 2025 12:08:03 -0600 Subject: [PATCH] fix(git-prompt): improve branch name resolution using symbolic-ref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: In worktrees, enabling reftable caused the gitfast prompt to sometimes show “.invalid” for the branch name, e.g. `git:(.invalid|SPARSE)`. The cause was gitfast’s __git_ps1 reading $GIT_DIR/HEAD (and sequencer head-name files) directly and attempting to derive the ref name by string slicing. That approach is brittle with worktrees and newer ref backends like reftable. What changed: - Prefer `git symbolic-ref --short HEAD` to resolve the branch name. - Also use `--short` when HEAD is a symlink. - Keep existing fallbacks (describe/detached SHA) unchanged. Why this is correct: - Delegates ref resolution to Git’s ref API, which understands: - multiple worktrees (`.git/worktrees//HEAD`) - all ref storage backends (loose, packed, reftable) - edge cases around in-progress operations and symlinks - Avoids parsing internal files that can legitimately be non-canonical or transient (e.g., head-name during rebase, or placeholders that appear as “.invalid” with reftable+worktrees). Impact: - Correct branch names in worktrees regardless of ref backend (fixes “.invalid”). - Detached HEAD behavior remains: still falls back to describe/short SHA. - `|SPARSE` logic unchanged and still driven by `core.sparseCheckout`. - Backwards-compatible: older Git that supports `symbolic-ref --short` works; fallbacks still apply if not a branch. Rationale: Ref backends like reftable decouple refs from the filesystem layout that gitfast was implicitly depending on. Using Git’s plumbing for branch resolution is the robust, future-proof approach. --- plugins/gitfast/git-prompt.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/gitfast/git-prompt.sh b/plugins/gitfast/git-prompt.sh index 76ee4ab1e..611f6640d 100644 --- a/plugins/gitfast/git-prompt.sh +++ b/plugins/gitfast/git-prompt.sh @@ -474,9 +474,12 @@ __git_ps1 () if [ -n "$b" ]; then : + # Prefer symbolic-ref short name resolution (works well with worktrees) + elif symref_short="$(git symbolic-ref --quiet --short HEAD 2>/dev/null)" && [ -n "$symref_short" ]; then + b="$symref_short" elif [ -h "$g/HEAD" ]; then # symlink symbolic ref - b="$(git symbolic-ref HEAD 2>/dev/null)" + b="$(git symbolic-ref --short HEAD 2>/dev/null)" else local head="" if ! __git_eread "$g/HEAD" head; then