From 48c798958bf6775a424b71478e24b6e62d114c43 Mon Sep 17 00:00:00 2001 From: Otto Jongerius Date: Thu, 19 Feb 2026 11:46:49 +1300 Subject: [PATCH] Add worktree_clone fish function Adds a fish function that automates the bare-repo + worktree setup: - Clone a repo as bare into .bare/ - Create .git pointer file - Detect default branch and create a worktree for it Also symlinks fish/functions/ directory in install.sh and updates the do_fish bats test to verify the new symlink. --- fish/functions/worktree_clone.fish | 45 ++++++++++++++++++++++++++++++ install.sh | 1 + test_install.bats | 6 ++-- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 fish/functions/worktree_clone.fish diff --git a/fish/functions/worktree_clone.fish b/fish/functions/worktree_clone.fish new file mode 100644 index 0000000..97fa152 --- /dev/null +++ b/fish/functions/worktree_clone.fish @@ -0,0 +1,45 @@ +function worktree_clone --description "Clone a repo as a bare worktree setup" + if test (count $argv) -lt 1 + echo "Usage: worktree_clone [directory]" + return 1 + end + + set -l repo_url $argv[1] + + # Derive project name from URL (strip .git suffix and path) + if test (count $argv) -ge 2 + set -l dir_name $argv[2] + else + set -l dir_name (string replace -r '\.git$' '' (basename $repo_url)) + end + + if test -d $dir_name + echo "Error: directory '$dir_name' already exists" + return 1 + end + + mkdir -p $dir_name + echo "Cloning $repo_url into $dir_name/.bare ..." + git clone --bare $repo_url $dir_name/.bare; or begin + rm -rf $dir_name + return 1 + end + + # Point .git to the bare repo + echo "gitdir: ./.bare" >$dir_name/.git + + # Detect the default branch from the remote + set -l default_branch (git -C $dir_name/.bare symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | string replace 'refs/remotes/origin/' '') + if test -z "$default_branch" + set default_branch main + echo "Warning: could not detect default branch, falling back to 'main'" + end + + # Configure remote fetch so all branches are visible + git -C $dir_name/.bare config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" + + # Create the worktree for the default branch + git -C $dir_name worktree add $default_branch $default_branch + + echo "Done! cd $dir_name/$default_branch to get started." +end diff --git a/install.sh b/install.sh index 1e8c8f1..2f06e1c 100755 --- a/install.sh +++ b/install.sh @@ -102,6 +102,7 @@ do_fish() { echo "Working on Fish shell setup.." mkdir -p "$HOME/.config/fish" _symlink "$(realpath "$REPO_DIR/fish/config.fish")" "$HOME/.config/fish/config.fish" + _symlink "$(realpath "$REPO_DIR/fish/functions")" "$HOME/.config/fish/functions" _symlink "$(realpath "$REPO_DIR/starship/starship.toml")" "$HOME/.config/starship.toml" touch "$HOME/.extra.fish" diff --git a/test_install.bats b/test_install.bats index 08baf3c..6c18a4d 100644 --- a/test_install.bats +++ b/test_install.bats @@ -92,14 +92,15 @@ setup() { # --- do_fish tests --- -@test "do_fish symlinks fish config and starship config" { +@test "do_fish symlinks fish config, functions, and starship config" { local fake_home="$TEST_DIR/home" mkdir -p "$fake_home/.config" local repo="$TEST_DIR/repo" - mkdir -p "$repo/fish" "$repo/starship" + mkdir -p "$repo/fish/functions" "$repo/starship" echo "fish cfg" > "$repo/fish/config.fish" echo "starship cfg" > "$repo/starship/starship.toml" + echo "function test; end" > "$repo/fish/functions/test.fish" HOME="$fake_home" REPO_DIR="$repo" @@ -111,6 +112,7 @@ setup() { do_fish [ -L "$fake_home/.config/fish/config.fish" ] + [ -L "$fake_home/.config/fish/functions" ] [ -L "$fake_home/.config/starship.toml" ] [ -f "$fake_home/.extra.fish" ] }