Skip to content

fix(ux): improve fzf picker discoverability and empty state#139

Merged
helizaga merged 3 commits intomainfrom
fix/fzf-picker-ux
Feb 24, 2026
Merged

fix(ux): improve fzf picker discoverability and empty state#139
helizaga merged 3 commits intomainfrom
fix/fzf-picker-ux

Conversation

@helizaga
Copy link
Collaborator

@helizaga helizaga commented Feb 24, 2026

Summary

  • git gtr doctor now shows shell integration status alongside fzf detection, so users know both steps are needed for gtr cd
  • gtr cd with no worktrees now shows guidance instead of launching fzf with only the main repo

Before

$ git gtr doctor
[OK] fzf: 0.68.0 (interactive picker available)
# (no mention of shell integration requirement)

$ gtr cd  # with 0 worktrees
# launches fzf showing only main repo — confusing

After

$ git gtr doctor
[OK] fzf: 0.68.0 (interactive picker: gtr cd)
[OK] Shell integration: loaded (gtr cd available)
# or if not set up:
[i] Shell integration: eval "$(git gtr init zsh)" in .zshrc for gtr cd

$ gtr cd  # with 0 worktrees
No worktrees to pick from. Create one with: git gtr new <branch>

Test plan

  • git gtr doctor shows fzf + shell integration status
  • gtr cd with 0 worktrees shows guidance message
  • All 282 BATS tests pass
  • gtr cd with worktrees still launches fzf normally (manual)

Summary by CodeRabbit

  • Bug Fixes

    • Prevents launching the interactive picker when no worktrees exist; prints a clear error with guidance to create one.
    • Improves interactive picker messaging for clarity.
  • Chores

    • Enhanced health diagnostics to check shell integration and report loaded status or tailored initialization hints per shell (bash, zsh, fish).

- doctor: add shell integration check so users know they need
  eval "$(git gtr init <shell>)" in addition to installing fzf
- gtr cd: skip fzf and show guidance when no worktrees exist
  instead of launching picker with only the main repo listed
@helizaga helizaga requested a review from NatoBoram as a code owner February 24, 2026 21:22
@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

Warning

Rate limit exceeded

@helizaga has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 19 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between f595909 and 80ec74e.

📒 Files selected for processing (1)
  • lib/commands/doctor.sh

Walkthrough

Adds shell-integration detection and messages to the doctor health check and introduces a pre-check for available worktrees before launching the fzf picker in init, plus safer fzf input handling across bash, zsh, and fish.

Changes

Cohort / File(s) Summary
Health Check Enhancements
lib/commands/doctor.sh
Detects current shell (bash, zsh, fish), locates the shell RC file, checks for git gtr init presence, and prints either a loaded status or a shell-specific initialization hint. Also updates fzf availability messaging to "interactive picker: gtr cd".
Initialization Logic Guards
lib/commands/init.sh
Adds a pre-check that exits with a stderr message when no worktrees exist. Replaces direct piping into fzf with an intermediate _gtr_porcelain and uses printf to feed fzf across bash, zsh, and fish variants; applies guard for single/multiple lines and cd subpath handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I sniff the shells, one by one,
RCs checked before the fun,
No worktrees? I softly cry,
fzf waits while branches lie,
Hopping forward — init, bye-bye! 🚀

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main changes: improving fzf picker discoverability (shell integration status in doctor) and handling empty state (error message when no worktrees).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/fzf-picker-ux

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
lib/commands/init.sh (2)

191-200: Same return-code guard needed here as in the bash block.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/commands/init.sh` around lines 191 - 200, The fzf invocation block needs
the same return-code guard as the earlier bash branch: after running fzf (the
command that assigns _gtr_selection via "_gtr_selection=\"$(... | fzf ... )\"")
check the exit status ($?) and if non-zero return immediately (or handle as the
bash block does) to avoid continuing on user cancel or error; update the fzf
selection handling around variable _gtr_selection to perform that check and
return on non-zero.

301-308: Same return-code guard needed here as in the bash block.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/commands/init.sh` around lines 301 - 308, The fish branch that runs fzf
(populating _gtr_selection from _gtr_porcelain) lacks the same return-code guard
as the bash branch; after invoking fzf add a check on the exit status (fish
$status) and return early if fzf was cancelled or failed (e.g. test $status -ne
0; return 0 or use "or return"). Update the block that sets _gtr_selection (the
fzf invocation) to verify $status and return before continuing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/commands/doctor.sh`:
- Around line 116-118: Replace the echo-based status message with the project's
logging helper: in the fzf presence check (the block using "command -v fzf" and
the call to "fzf --version"), call log_info instead of echo and keep the same
formatted message content (including the fzf version extraction via "fzf
--version | awk '{print $1}'" and the "(interactive picker: gtr cd)" suffix);
ensure the message uses log_info so user-facing output follows lib/ui.sh
conventions and error cases continue to use log_error where applicable.
- Around line 122-135: The shell-integration hint currently always suggests
using eval with the init command; update the message logic so when _shell_name
is "fish" (variable _shell_name used in the case statement) the hint instructs
to run `git gtr init fish | source` (pipe into source) instead of using eval,
while leaving the existing `eval "$(git gtr init $_shell_name)"` suggestion for
other shells; modify the conditional/echo that prints the hint (the else branch
that echoes the hint referencing ${_rc_file##*/}) to choose the fish-specific
string when _shell_name == "fish".

In `@lib/commands/init.sh`:
- Around line 85-94: The current code captures output of "git gtr list
--porcelain" into _gtr_porcelain but doesn't check for command failure, causing
a misleading "No worktrees" message; update the block that sets _gtr_porcelain
to test the exit status of "git gtr list --porcelain" (or run it separately),
and if it fails, print the actual error to stderr and return a non-zero status
before proceeding to the empty-state check; reference the variables/commands
_gtr_porcelain and the invocation "git gtr list --porcelain" in init.sh and
ensure failures are propagated rather than masked.

---

Duplicate comments:
In `@lib/commands/init.sh`:
- Around line 191-200: The fzf invocation block needs the same return-code guard
as the earlier bash branch: after running fzf (the command that assigns
_gtr_selection via "_gtr_selection=\"$(... | fzf ... )\"") check the exit status
($?) and if non-zero return immediately (or handle as the bash block does) to
avoid continuing on user cancel or error; update the fzf selection handling
around variable _gtr_selection to perform that check and return on non-zero.
- Around line 301-308: The fish branch that runs fzf (populating _gtr_selection
from _gtr_porcelain) lacks the same return-code guard as the bash branch; after
invoking fzf add a check on the exit status (fish $status) and return early if
fzf was cancelled or failed (e.g. test $status -ne 0; return 0 or use "or
return"). Update the block that sets _gtr_selection (the fzf invocation) to
verify $status and return before continuing.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 929026d and c9e8636.

📒 Files selected for processing (2)
  • lib/commands/doctor.sh
  • lib/commands/init.sh

…ells

- Updated the shell integration message to provide specific instructions for fish users and a general hint for other shells, improving clarity on how to initialize gtr cd.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
lib/commands/doctor.sh (1)

116-120: echo instead of log_info for fzf status message — already flagged.

The fzf detection block on line 117 still uses echo instead of log_info. This was raised in a prior review and remains unaddressed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/commands/doctor.sh` around lines 116 - 120, Replace the direct echo calls
in the fzf detection block (the conditional that uses "command -v fzf >/dev/null
2>&1") with the project's logging helper so the status message uses log_info
instead of echo; update both the success branch (currently printing the fzf
version) and the failure branch (currently printing the not-found hint) to call
log_info with the same messages so logging is consistent with other doctor
checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/commands/doctor.sh`:
- Around line 134-141: Replace the raw echo messages in the block that sets
_init_hint with project logging: call log_info instead of echo for the shell
integration hint (and any corresponding [OK] line) so messages follow lib/ui.sh
conventions; additionally, guard the empty _rc_file case by checking [ -n
"$_rc_file" ] before including "in ${_rc_file##*/}" in the hint—if _rc_file is
empty, either omit the "in ..." clause or rephrase the hint to not reference the
rc file (use _shell_name and _init_hint variables to build the alternate
message). Ensure you update the branches that set _init_hint (the fish and
fallback branches) and use log_info to emit the final message.

---

Duplicate comments:
In `@lib/commands/doctor.sh`:
- Around line 116-120: Replace the direct echo calls in the fzf detection block
(the conditional that uses "command -v fzf >/dev/null 2>&1") with the project's
logging helper so the status message uses log_info instead of echo; update both
the success branch (currently printing the fzf version) and the failure branch
(currently printing the not-found hint) to call log_info with the same messages
so logging is consistent with other doctor checks.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c9e8636 and f595909.

📒 Files selected for processing (1)
  • lib/commands/doctor.sh

@helizaga helizaga merged commit 584c17a into main Feb 24, 2026
4 checks passed
@helizaga helizaga deleted the fix/fzf-picker-ux branch February 24, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant