more helpers for git and tmux flow
This commit is contained in:
parent
cc79b2a6b2
commit
8ae9c6ecda
6 changed files with 123 additions and 18 deletions
|
|
@ -1,6 +1,48 @@
|
||||||
branch() {
|
branch() {
|
||||||
local branch_name=${1:-}
|
local branch_name=${1:-}
|
||||||
|
|
||||||
|
# helper: set tmux window name. If tmux is in auto mode, always rename.
|
||||||
|
# If tmux is manual but the current window name matches the previous branch,
|
||||||
|
# allow renaming from previous branch name to the new one.
|
||||||
|
_branch__maybe_set_tmux_name() {
|
||||||
|
if ! command -v tmux_window >/dev/null 2>&1; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local new_name prev_branch tmux_status tmux_cur
|
||||||
|
new_name=${1:-}
|
||||||
|
prev_branch=${2:-}
|
||||||
|
tmux_status=$(tmux_window status 2>/dev/null || true)
|
||||||
|
if [ "$tmux_status" = "auto" ]; then
|
||||||
|
tmux_window rename "$new_name" 2>/dev/null || true
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# tmux is manual. If the current tmux name matches the previous branch,
|
||||||
|
# we consider it safe to update it to the new branch name.
|
||||||
|
if [ -n "$prev_branch" ]; then
|
||||||
|
tmux_cur=$(tmux_window get 2>/dev/null || true)
|
||||||
|
if [ "$tmux_cur" = "$prev_branch" ]; then
|
||||||
|
tmux_window rename "$new_name" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# helper: revert tmux to automatic rename only if current tmux name matches previous branch
|
||||||
|
_branch__revert_tmux_auto() {
|
||||||
|
if ! command -v tmux_window >/dev/null 2>&1; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local prev_branch=${1:-}
|
||||||
|
if [ -z "$prev_branch" ]; then
|
||||||
|
tmux_window rename 2>/dev/null || true
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local tmux_cur
|
||||||
|
tmux_cur=$(tmux_window get 2>/dev/null || true)
|
||||||
|
if [ "$tmux_cur" = "$prev_branch" ]; then
|
||||||
|
tmux_window rename 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Determine repo root early so we can run branches inside it
|
# Determine repo root early so we can run branches inside it
|
||||||
local common_dir
|
local common_dir
|
||||||
if ! common_dir=$(git rev-parse --git-common-dir 2>/dev/null); then
|
if ! common_dir=$(git rev-parse --git-common-dir 2>/dev/null); then
|
||||||
|
|
@ -24,12 +66,11 @@ branch() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local branches_list_raw branches_list selection
|
local branches_list_raw branches_list selection
|
||||||
|
# Gather local and remote branches with fallbacks to ensure locals appear
|
||||||
|
branches_list_raw=""
|
||||||
if declare -f local_branches >/dev/null 2>&1; then
|
if declare -f local_branches >/dev/null 2>&1; then
|
||||||
branches_list_raw=$(local_branches 2>/dev/null || true; remote_branches 2>/dev/null || true)
|
branches_list_raw=$(cd "$repo_dir" && local_branches 2>/dev/null || true; cd "$repo_dir" && remote_branches 2>/dev/null || true)
|
||||||
else
|
|
||||||
branches_list_raw=$(git -C "$repo_dir" branch --format='%(refname:short)' 2>/dev/null || true; git -C "$repo_dir" branch -r --format='%(refname:short)' 2>/dev/null | sed 's#^.*/##' || true)
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
branches_list=$(printf "%s
|
branches_list=$(printf "%s
|
||||||
" "$branches_list_raw" | awk '!seen[$0]++')
|
" "$branches_list_raw" | awk '!seen[$0]++')
|
||||||
if [ -z "$branches_list" ]; then
|
if [ -z "$branches_list" ]; then
|
||||||
|
|
@ -37,13 +78,19 @@ branch() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
selection=$(printf "%s\n" "$branches_list" | fzf --height=40% --prompt="Select branch: ")
|
fzf_out=$(printf "%s\n" "$branches_list" | fzf --height=40% --prompt="Select branch: " --print-query)
|
||||||
if [ -z "$selection" ]; then
|
if [ -z "$fzf_out" ]; then
|
||||||
echo "No branch selected." >&2
|
echo "No branch selected." >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
branch_query=$(printf "%s\n" "$fzf_out" | sed -n '1p')
|
||||||
branch_name="$selection"
|
branch_selection=$(printf "%s\n" "$fzf_out" | sed -n '2p')
|
||||||
|
if [ -n "$branch_selection" ]; then
|
||||||
|
branch_name="$branch_selection"
|
||||||
|
else
|
||||||
|
# user typed something in fzf but didn't select: use that as new branch name
|
||||||
|
branch_name=$(printf "%s" "$branch_query" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local repo_base repo_hash default_branch
|
local repo_base repo_hash default_branch
|
||||||
|
|
@ -52,6 +99,10 @@ branch() {
|
||||||
|
|
||||||
default_branch=$(getdefault)
|
default_branch=$(getdefault)
|
||||||
|
|
||||||
|
# capture current branch name as seen by tmux so we can decide safe renames later
|
||||||
|
local prev_branch
|
||||||
|
prev_branch=$(git -C "$PWD" rev-parse --abbrev-ref HEAD 2>/dev/null || true)
|
||||||
|
|
||||||
# Special-case: jump to the main working tree on the default branch
|
# Special-case: jump to the main working tree on the default branch
|
||||||
if [ "$branch_name" = "default" ] || [ "$branch_name" = "master" ] || [ "$branch_name" = "$default_branch" ]; then
|
if [ "$branch_name" = "default" ] || [ "$branch_name" = "master" ] || [ "$branch_name" = "$default_branch" ]; then
|
||||||
if [ "$repo_dir" = "$PWD" ]; then
|
if [ "$repo_dir" = "$PWD" ]; then
|
||||||
|
|
@ -59,7 +110,10 @@ branch() {
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
echo "Switching to main working tree on branch '$default_branch'."
|
echo "Switching to main working tree on branch '$default_branch'."
|
||||||
|
# capture current branch name as seen by tmux so we only revert if it matches
|
||||||
|
prev_branch=$(git -C "$PWD" rev-parse --abbrev-ref HEAD 2>/dev/null || true)
|
||||||
cd "$repo_dir" || return 1
|
cd "$repo_dir" || return 1
|
||||||
|
_branch__revert_tmux_auto "$prev_branch" || true
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -69,6 +123,7 @@ branch() {
|
||||||
if [ -n "$existing" ]; then
|
if [ -n "$existing" ]; then
|
||||||
echo "Opening existing worktree for branch '$branch_name' at '$existing'."
|
echo "Opening existing worktree for branch '$branch_name' at '$existing'."
|
||||||
cd "$existing" || return 1
|
cd "$existing" || return 1
|
||||||
|
_branch__maybe_set_tmux_name "$branch_name" "$prev_branch" || true
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -91,6 +146,7 @@ branch() {
|
||||||
if [ -d "$wt_path" ]; then
|
if [ -d "$wt_path" ]; then
|
||||||
echo "Opening existing worktree at '$wt_path'."
|
echo "Opening existing worktree at '$wt_path'."
|
||||||
cd "$wt_path" || return 1
|
cd "$wt_path" || return 1
|
||||||
|
_branch__maybe_set_tmux_name "$branch_name" "$prev_branch" || true
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -122,11 +178,14 @@ branch() {
|
||||||
if [ "$local_exists" -eq 1 ]; then
|
if [ "$local_exists" -eq 1 ]; then
|
||||||
if git -C "$repo_dir" worktree add "$wt_path" "$branch_name" 2>/dev/null; then
|
if git -C "$repo_dir" worktree add "$wt_path" "$branch_name" 2>/dev/null; then
|
||||||
cd "$wt_path" || return 1
|
cd "$wt_path" || return 1
|
||||||
|
_branch__maybe_set_tmux_name "$branch_name" "$prev_branch" || true
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
if git -C "$repo_dir" worktree add -b "$branch_name" "$wt_path" "$branch_from" 2>/dev/null; then
|
if git -C "$repo_dir" worktree add -b "$branch_name" "$wt_path" "$branch_from" 2>/dev/null; then
|
||||||
cd "$wt_path" || return 1
|
cd "$wt_path" || return 1
|
||||||
|
_branch__maybe_set_tmux_name "$branch_name" "$prev_branch" || true
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
@ -137,6 +196,7 @@ branch() {
|
||||||
if git -C "$repo_dir" branch "$branch_name" "$start_sha" 2>/dev/null; then
|
if git -C "$repo_dir" branch "$branch_name" "$start_sha" 2>/dev/null; then
|
||||||
if git -C "$repo_dir" worktree add "$wt_path" "$branch_name" 2>/dev/null; then
|
if git -C "$repo_dir" worktree add "$wt_path" "$branch_name" 2>/dev/null; then
|
||||||
cd "$wt_path" || return 1
|
cd "$wt_path" || return 1
|
||||||
|
_branch__maybe_set_tmux_name "$branch_name" "$prev_branch" || true
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
git -C "$repo_dir" branch -D "$branch_name" 2>/dev/null || true
|
git -C "$repo_dir" branch -D "$branch_name" 2>/dev/null || true
|
||||||
|
|
|
||||||
|
|
@ -79,12 +79,22 @@ branchdel() {
|
||||||
if git -C "$repo_dir" worktree remove "$target_wt" 2>/dev/null; then
|
if git -C "$repo_dir" worktree remove "$target_wt" 2>/dev/null; then
|
||||||
rm -rf -- "$target_wt" 2>/dev/null || true
|
rm -rf -- "$target_wt" 2>/dev/null || true
|
||||||
echo "Removed worktree: $target_wt"
|
echo "Removed worktree: $target_wt"
|
||||||
|
# delete local branch if it exists
|
||||||
|
if git -C "$repo_dir" show-ref --verify --quiet "refs/heads/$branch"; then
|
||||||
|
git -C "$repo_dir" branch -D "$branch" 2>/dev/null || true
|
||||||
|
echo "Deleted local branch: $branch"
|
||||||
|
fi
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
# try with --force as a fallback
|
# try with --force as a fallback
|
||||||
if git -C "$repo_dir" worktree remove --force "$target_wt" 2>/dev/null; then
|
if git -C "$repo_dir" worktree remove --force "$target_wt" 2>/dev/null; then
|
||||||
rm -rf -- "$target_wt" 2>/dev/null || true
|
rm -rf -- "$target_wt" 2>/dev/null || true
|
||||||
echo "Removed worktree (forced): $target_wt"
|
echo "Removed worktree (forced): $target_wt"
|
||||||
|
# delete local branch if it exists
|
||||||
|
if git -C "$repo_dir" show-ref --verify --quiet "refs/heads/$branch"; then
|
||||||
|
git -C "$repo_dir" branch -D "$branch" 2>/dev/null || true
|
||||||
|
echo "Deleted local branch: $branch"
|
||||||
|
fi
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ with lib;
|
||||||
|
|
||||||
environment.shellInit = lib.concatStringsSep "\n\n" [
|
environment.shellInit = lib.concatStringsSep "\n\n" [
|
||||||
(builtins.readFile ./common.sh)
|
(builtins.readFile ./common.sh)
|
||||||
|
(builtins.readFile ./tmux_helpers.sh)
|
||||||
(builtins.readFile ./branch.func.sh)
|
(builtins.readFile ./branch.func.sh)
|
||||||
(builtins.readFile ./branchd.func.sh)
|
(builtins.readFile ./branchd.func.sh)
|
||||||
(builtins.readFile ./link_ignored.func.sh)
|
(builtins.readFile ./link_ignored.func.sh)
|
||||||
|
|
|
||||||
|
|
@ -103,11 +103,11 @@ forcepush () {
|
||||||
}
|
}
|
||||||
|
|
||||||
remote_branches () {
|
remote_branches () {
|
||||||
git branch -a | grep 'remotes' | grep -v -E '.*(HEAD|${DEFAULT})' | cut -d'/' -f 3-
|
git for-each-ref --format='%(refname:short)' refs/remotes 2>/dev/null | sed 's#^[^/]*/##' | grep -v '^HEAD$' || true
|
||||||
}
|
}
|
||||||
|
|
||||||
local_branches () {
|
local_branches () {
|
||||||
git branch -a | grep -v 'remotes' | grep -v -E '.*(HEAD|${DEFAULT})' | grep -v '^*' | cut -d' ' -f 3-
|
git for-each-ref --format='%(refname:short)' refs/heads 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
prunel () {
|
prunel () {
|
||||||
|
|
|
||||||
34
common/general/shell/tmux_helpers.sh
Normal file
34
common/general/shell/tmux_helpers.sh
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
tmux_window () {
|
||||||
|
cmd=${1:-}
|
||||||
|
case "${cmd}" in
|
||||||
|
rename)
|
||||||
|
if [ -z "${2:-}" ]; then
|
||||||
|
tmux setw automatic-rename
|
||||||
|
else
|
||||||
|
tmux rename-window "$2"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
get)
|
||||||
|
printf '%s' "$(tmux display-message -p '#W')"
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
out="$(tmux show-window-options automatic-rename 2>/dev/null || true)"
|
||||||
|
if printf '%s' "$out" | grep -q 'automatic-rename on'; then
|
||||||
|
printf 'auto'
|
||||||
|
elif printf '%s' "$out" | grep -q 'automatic-rename off'; then
|
||||||
|
printf 'manual'
|
||||||
|
else
|
||||||
|
# If tmux returns nothing (option not set), default to auto
|
||||||
|
if [ -z "$out" ]; then
|
||||||
|
printf 'auto'
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf 'Usage: tmux_window {rename [NAME]|get|status}\n' >&2
|
||||||
|
return 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
8
hosts/lio/flake.lock
generated
8
hosts/lio/flake.lock
generated
|
|
@ -1206,11 +1206,11 @@
|
||||||
"rust-overlay": "rust-overlay_2"
|
"rust-overlay": "rust-overlay_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1757954114,
|
"lastModified": 1758041510,
|
||||||
"narHash": "sha256-1Y6+uiLicKPARiiIjYY32asP9oKBW9z1LEBRYOR6ajI=",
|
"narHash": "sha256-vcK6ZwAWNfjdDFYKLVrWk+azva58AiDpm8nMfIniFWA=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "f1487458ea787031e00230b604e652464fd44139",
|
"rev": "b3dbdf3f7360747987bf38bcdd9baf01b4906929",
|
||||||
"revCount": 303,
|
"revCount": 304,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.joshuabell.xyz/ringofstorms/nvim"
|
"url": "https://git.joshuabell.xyz/ringofstorms/nvim"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue