Skip to content

Instantly share code, notes, and snippets.

@Drarig29
Last active April 20, 2024 11:51
Show Gist options
  • Save Drarig29/55925def35b7e3641de67c5b3e5880e9 to your computer and use it in GitHub Desktop.
Save Drarig29/55925def35b7e3641de67c5b3e5880e9 to your computer and use it in GitHub Desktop.
Git checkout with fuzzy search and automatic branch swap between worktrees
function swap_worktree_branch_with() {
# Run the command again to get the error message
error_message=$(git switch $1 2>&1)
culprit_worktree=$(echo $error_message | grep "is already used by worktree at" | cut -d "'" -f4)
if [ -z "$culprit_worktree" ]; then
return
fi
# Save the branch in current worktree, and detach the HEAD so that we can switch to this branch in the culprit worktree
branch_in_original_worktree=$(git branch --show-current)
echo "\033[0;33mDetaching HEAD in current worktree\033[0m"
git checkout --detach
# Switch to the culprit worktree
echo "\033[0;33mSwapping the branch with the other worktree\033[0m"
cd $culprit_worktree
git switch $branch_in_original_worktree
# Go back, and finally switch to the branch we wanted to switch to
cd -
echo "\033[0;32mBranches swapped!\033[0m"
git switch $1
}
function gck() {
branch=$(git for-each-ref --sort=-committerdate --format='%(refname:short)' --exclude=refs/{stash,tags,prefetch,remotes/origin} | fzf --no-sort)
git switch $branch || swap_worktree_branch_with $branch
}
@Drarig29
Copy link
Author

Drarig29 commented Apr 20, 2024

I used my gck function for a long time and I love it:

  • It lists all branches with the most recent first
  • And feeds that list into fzf for fuzzy search

But I recently got into git worktrees, and it's impossible to have a branch checked out in 2 worktrees at the same time, so I sometimes find myself having to go in the worktree which already has by branch checked out, switch it to a random branch, then go back and finally switch to the branch I wanted to work on.

I'm probably not rigorous enough when working with worktrees (instead I should probably go to that worktree which already has the branch I want... but I just want to quickly switch to my main branch in that instance of VSCode, please! 😩)

Solution: (output of the swap_worktree_branch_with() function above)

$ gck

fatal: 'main' is already used by worktree at '~/my-bare-repo.git/main'
Detaching HEAD in current worktree
HEAD is now at 1d6140f4 🐛 My awesome bug fix
Swapping the branch with the other worktree
Switched to branch 'corentin.girard/awesome-bug-fix'
Your branch is up to date with 'origin/corentin.girard/awesome-bug-fix'.
~/my-bare-repo.git/JIRA-12345
Branches swapped!
Previous HEAD position was 1d6140f4 🐛 My awesome bug fix
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment