├── .github └── workflows │ └── main.yml ├── LICENSE ├── README.md ├── completions ├── _wt_completion ├── wt.fish └── wt_completion └── wt /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request: 6 | branches: 7 | - master 8 | 9 | name: "Shellcheck" 10 | env: 11 | VERSION: v0.9.0 12 | 13 | jobs: 14 | shellcheck: 15 | name: Shellcheck 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Install shellcheck 20 | run: | 21 | wget -q https://github.com/koalaman/shellcheck/releases/download/$VERSION/shellcheck-$VERSION.linux.x86_64.tar.xz \ 22 | -O shellcheck.tar.xz 23 | tar -xf shellcheck.tar.xz 24 | mv shellcheck-$VERSION/shellcheck . 25 | rm -rf shellcheck.tar.xz shellcheck-$VERSION 26 | 27 | - name: Run Shellcheck 28 | run: | 29 | ./shellcheck --version 30 | ./shellcheck -e SC2148 wt completions/_wt_completion completions/wt_completion 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Yankee Maharjan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Git worktree switcher :zap: 2 | Switch between git worktrees with speed. :zap: 3 | 4 | demo of switching between git worktrees 5 | 6 | ## Installation 7 | Download the script from the [Release section](https://github.com/yankeexe/git-worktree-switcher/releases). 8 | 9 | Make the script executable. 10 | 11 | ```bash 12 | $ chmod +x wt 13 | ``` 14 | 15 | Copy the executable to any directory in your `$PATH` 16 | 17 | ```bash 18 | $ sudo cp wt /usr/local/bin 19 | ``` 20 | 21 | ## Tab Autocompletion :zap: 22 | 23 | **For Bash** 24 | ```bash 25 | sudo cp completions/wt_completion /etc/bash_completion.d 26 | ``` 27 | 28 | **For ZSH** 29 | > Note: completion file for zsh has `_` prefix 30 | 31 | 32 | Find paths where you can store your completion 33 | ```bash 34 | print -rl -- $fpath 35 | ``` 36 | 37 | Copy completion script to one of that location and restart the shell. 38 | 39 | ```bash 40 | sudo cp completions/_wt_completion 41 | 42 | exec zsh 43 | ``` 44 | 45 | **For Fish** 46 | ```bash 47 | cp completions/wt.fish ~/.config/fish/completions 48 | ``` 49 | --- 50 | Tab autocompletion works for switching between your worktrees. 51 | ```bash 52 | wt 53 | 54 | # OR 55 | 56 | wt 57 | ``` 58 | 59 | ## Usage 60 | Switch between worktrees. 61 | You can do a text search to change to the worktree directory. 62 | 63 | ```bash 64 | $ wt 65 | ``` 66 | 67 | Go to root worktree directory 68 | 69 | ```bash 70 | $ wt - 71 | ``` 72 | 73 | List out all the worktrees. 74 | 75 | ```bash 76 | $ wt list 77 | ``` 78 | 79 | Show help message 80 | 81 | ```bash 82 | $ wt help 83 | ``` 84 | 85 | Update to the latest release 86 | 87 | ```bash 88 | $ wt update 89 | ``` 90 | 91 | Show the CLI version 92 | 93 | ```bash 94 | $ wt version 95 | ``` 96 | -------------------------------------------------------------------------------- /completions/_wt_completion: -------------------------------------------------------------------------------- 1 | #compdef wt 2 | 3 | # AUTOCOMPLETION FOR ZSH 4 | # Reference: https://zsh.sourceforge.io/Doc/Release/Completion-Widgets.html 5 | 6 | # wt list: list all the available worktrees 7 | # | awk '{ print $1; }': grab the first column of the output 8 | # | tr "\n" " ": replace line break character with space to put the worktrees on single line 9 | # separated by space 10 | 11 | list="$(wt list | awk '{ print $1; }' | tr "\n" " ")" 12 | declare -A opts 13 | 14 | # Create associative array with key same as its value 15 | # Completion keywords are taken as keys of arrays and the possible matches are their values 16 | # shwordsplit: iterate over a string separated by space (like sh/bash) 17 | setopt shwordsplit 18 | for item in $list; do 19 | base="$(basename -- "$item")" 20 | opts+=(["$base"]="$base") 21 | done 22 | unsetopt shwordsplit 23 | 24 | compadd -Qa opts 25 | -------------------------------------------------------------------------------- /completions/wt.fish: -------------------------------------------------------------------------------- 1 | # AUTOCOMPLETION FOR FISH 2 | # Reference: https://fishshell.com/docs/current/completions.html 3 | 4 | # wt list: list all the available worktrees 5 | # | awk '{ print $1; }': grab the first column of the output 6 | # | tr "\n" " ": replace line break character with space to put the worktrees on single line 7 | # separated by space 8 | 9 | set list (wt list | awk '{ print $1; }' | tr "\n" " ") 10 | set opts "" 11 | 12 | for item in (string split " " "$list") 13 | set -a opts (basename -- "$item") 14 | end 15 | 16 | complete -c wt -f -n '__fish_is_nth_token 1' -a "$opts" 17 | -------------------------------------------------------------------------------- /completions/wt_completion: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # AUTOCOMPLETION FOR BASH 4 | # Reference: https://www.gnu.org/software/bash/manual/html_node/A-Programmable-Completion-Example.html 5 | 6 | # wt list: list all the available worktrees 7 | # | awk '{ print $1; }': grab the first column of the output 8 | # | tr "\n" " ": replace line break character with space to put the worktrees on single line 9 | # separated by space 10 | 11 | _wt() { 12 | local cur opts 13 | COMPREPLY=() 14 | cur="${COMP_WORDS[COMP_CWORD]}" 15 | list="$(wt list | awk '{ print $1; }' | tr "\n" " ")" 16 | opts="" 17 | 18 | for item in $list; do 19 | opts+="$(basename -- "$item") " 20 | done 21 | 22 | # Only show suggestions for the root command (wt) 23 | # Pass autocompletion suggestion as "words (-W)" to `compgen` separated by space 24 | if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]]; then 25 | local cur=${COMP_WORDS[COMP_CWORD]} 26 | # shellcheck disable=SC2207 27 | COMPREPLY=($(compgen -W "$opts" -- "$cur")) 28 | fi 29 | } 30 | 31 | # complete 32 | # -F: take function as completion provider 33 | # _wt: name of the function 34 | # wt: name of the command this completion is meant for 35 | complete -F _wt wt 36 | -------------------------------------------------------------------------------- /wt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Switch between git worktrees with speed. 5 | 6 | args=("$@") 7 | VERSION="0.1.1" 8 | TMP_PATH=$(mktemp) 9 | BINARY_PATH=$(which wt) 10 | JQ_URL="https://stedolan.github.io/jq/download" 11 | RELEASE_URL="https://github.com/yankeexe/git-worktree-switcher/releases/latest" 12 | RELEASE_API_URL="https://api.github.com/repos/yankeexe/git-worktree-switcher/releases/latest" 13 | 14 | 15 | # Escape forward slash 16 | arg=$(echo "${args[0]}" | sed 's/\//\\\//g') 17 | 18 | # show worktree list 19 | worktree_list() { 20 | git worktree list 21 | } 22 | 23 | help_message() { 24 | echo -e "wt lets you switch between your git worktrees with speed.\n" 25 | echo "Usage:" 26 | echo -e "\twt : search for worktree names and change to that directory." 27 | echo -e "\twt list: list out all the git worktrees." 28 | echo -e "\twt update: update to the latest release of worktree switcher." 29 | echo -e "\twt version: show the CLI version." 30 | echo -e "\twt help: shows this help message." 31 | } 32 | 33 | goto_main_worktree() { 34 | main_worktree=$(git worktree list --porcelain | grep -E 'worktree ' | awk '{print $0; exit}' | cut -d ' ' -f2-) 35 | 36 | if [ -z "$main_worktree" ]; then 37 | : 38 | else 39 | echo Changing to main worktree at: "$main_worktree" 40 | cd "$main_worktree" 41 | exec $SHELL 42 | fi 43 | } 44 | 45 | download_latest_update() { 46 | download_url=$(curl -sL $RELEASE_API_URL | jq -r '.assets[0].browser_download_url') 47 | 48 | echo "Downloading latest version $fetched_tag_name" 49 | curl -sL -o "$TMP_PATH" "$download_url" 50 | 51 | echo "Updating to latest version..." 52 | chmod +x "$TMP_PATH" 53 | sudo mv "$TMP_PATH" "$BINARY_PATH" 54 | rm -f "$TMP_PATH" 55 | 56 | echo "You are using the latest version of worktree switcher: $fetched_tag_name" 57 | } 58 | 59 | check_release_version() { 60 | fetched_tag_name=$(curl -sL $RELEASE_API_URL | jq -r '.tag_name') 61 | 62 | if [ "$fetched_tag_name" == $VERSION ]; then 63 | echo "You have the latest version of worktree switcher!" 64 | echo "Version: $VERSION" 65 | else 66 | download_latest_update 67 | fi 68 | } 69 | 70 | update() { 71 | if [ -z "$(command -v jq)" ]; then 72 | echo "jq is required for updating worktree switcher via this command." 73 | echo -e "Install jq:\n$JQ_URL.\n" 74 | echo -e "Or visit:\n$RELEASE_URL" 75 | else 76 | check_release_version 77 | fi 78 | } 79 | 80 | if [ -z "${args[0]}" ]; then 81 | help_message 82 | exit 0 83 | fi 84 | 85 | case "${args[0]}" in 86 | list) 87 | worktree_list 88 | ;; 89 | update) 90 | update 91 | ;; 92 | help) 93 | help_message 94 | ;; 95 | version) 96 | echo Version: $VERSION 97 | ;; 98 | -) 99 | goto_main_worktree 100 | ;; 101 | *) 102 | directory=$(git worktree list --porcelain | grep -E 'worktree ' | awk '/'"$arg"'/ {print; exit}' | cut -d ' ' -f2-) 103 | ;; 104 | esac 105 | 106 | # Change worktree based on user argument. 107 | change_worktree() { 108 | echo Changing to worktree at: "$directory" 109 | cd "$directory" 110 | exec $SHELL 111 | } 112 | 113 | # If directory variable is not empty then change worktree 114 | if [ -z "$directory" ]; then 115 | : 116 | else 117 | change_worktree 118 | fi 119 | --------------------------------------------------------------------------------