diff --git a/git-recent b/git-recent index bf24da1..9513c1e 100755 --- a/git-recent +++ b/git-recent @@ -19,7 +19,7 @@ if [[ "$1" == "--help" ]]; then echo "git-recent: Browse and checkout recently used Git branches." echo echo "Keybindings:" - echo " Enter: Checkout the selected branch" + echo " Enter: Checkout the selected branch (or jump to its worktree if open elsewhere)" echo " Ctrl-O: Show the diff of the selected branch against the main/master branch" echo " Ctrl-C: Exit" exit 0 @@ -55,6 +55,24 @@ elif command -v xsel >/dev/null; then copy_cmd="printf '%s' {} | xsel --clipboard" fi +_get_worktree_for_branch() { + local branch="$1" + local current_toplevel + current_toplevel=$(git rev-parse --show-toplevel 2>/dev/null) + + # Find the worktree path for the given branch, excluding the current one. + # Using substr to handle paths with spaces correctly. + git worktree list --porcelain | awk -v target="refs/heads/$branch" -v current="$current_toplevel" ' + /^worktree / { wt = substr($0, 10) } + /^branch / && $2 == target { + if (wt != current) { + print wt + exit + } + } + ' +} + YELLOW='\033[0;33m' DIM='\033[2m' NC='\033[0m' # No Color @@ -106,8 +124,20 @@ line_count=$(printf "%s" "$output" | wc -l) if [[ -n "$output" ]] && (( line_count == 0 )); then chosen_branch=$(echo "$output" | cut -d' ' -f1) - echo git checkout "$chosen_branch" - git checkout "$chosen_branch" + + wt_path=$(_get_worktree_for_branch "$chosen_branch") + + if [[ -n "$wt_path" ]]; then + echo "Branch '$chosen_branch' is open in worktree: $wt_path" + if [[ "$GIT_RECENT_AUTO_CD" == "1" ]]; then + echo "__CD__:$wt_path" + else + echo "To jump there, run: cd \"$wt_path\"" + fi + else + echo git checkout "$chosen_branch" + git checkout "$chosen_branch" + fi else echo "$output" fi diff --git a/man/man1/git-recent.1 b/man/man1/git-recent.1 index 0c26e63..fb9bccd 100644 --- a/man/man1/git-recent.1 +++ b/man/man1/git-recent.1 @@ -17,7 +17,7 @@ Display a help message. .SH KEYBINDINGS .TP .B Enter -Checkout the selected branch. +Checkout the selected branch. If the branch is already open in a separate git worktree, the script will provide instructions to jump there. (See README for automatic switching via a shell wrapper). .TP .B Up/Down arrow keys Navigate the branch list. diff --git a/readme.md b/readme.md index 0017330..bf897ce 100644 --- a/readme.md +++ b/readme.md @@ -37,6 +37,28 @@ Type or use arrow keys to navigate your list of branches. Hit `ctrl-o` to see the branch diff. +#### Worktree Support + +If a branch is already open in a separate git worktree, `git recent` will detect it and provide instructions to `cd` there. To enable **automatic** directory switching, add this wrapper function to your `.bashrc` or `.zshrc`: + +```bash +# Optional wrapper to enable automatic worktree jumping +git-recent() { + local output + # Set the flag to let the script know we can handle the CD + output=$(GIT_RECENT_AUTO_CD=1 command git-recent "$@") + + if echo "$output" | grep -q "^__CD__:"; then + local target=$(echo "$output" | grep "^__CD__:" | cut -d: -f2-) + cd "$target" + # Print the output but hide the control line + echo "$output" | grep -v "^__CD__:" + else + echo "$output" + fi +} +``` + -------------------------------- # `git recent-og`