gitterminalgit-worktree

How to quickly checkout between git worktrees?


I have the following file structure

❯ tree -L 1
.
├── latex/
├── main/
├── simulator/
├── tscnn/

Each directory is a worktree. If I am on latex/, trying to to check out to another worktree yields

❯ git checkout main
fatal: 'main' is already checked out at '/path/to/main'

I want to quickly checkout to another worktree (that is, cd to another directory) without explicitly writing the path (e.g., in the previous example, /path/to/main)

How to do so?


Solution

  • There is no way to do that with Git but possible with a shell function that'd use additional Unix tools. This works for me:

    cd_worktree() {
        if [ $# -ne 1 ]; then
            echo "Usage: cd_worktree <branch>" >&2
            return 1
        fi
        path="$(git worktree list | grep -F "$1" | awk '{print $1}')"
        if [ -n "$path" ]; then
            cd "$path"
        else
            echo "Cannot find path for branch '$1'" >&2
            return 1
        fi
    }
    

    Usage:

    cd_worktree main
    

    For bash completion add this to your ~/.bashrc:

        _cd_worktree_comp() {
            local cur="${COMP_WORDS[COMP_CWORD]}"
            COMPREPLY=(`compgen -W "$(
                git worktree list | awk '{s=$3; gsub("[\\\\[\\\\]]", "", s); print s}'
            )" -- "$cur"`)
        }
    
        _cd_worktree_comp_loader() {
            _completion_loader git
            unset _cd_worktree_comp_loader
            complete -F _cd_worktree_comp cd_worktree
            return 124
        }
    
        complete -F _cd_worktree_comp_loader cd_worktree
    

    It relies on _completion_loader from package bash-completion.