Add start point to worktree add subcommand
This commit is contained in:
@@ -9,6 +9,14 @@ __worktree_branches() {
|
||||
_describe 'branch' branches
|
||||
}
|
||||
|
||||
__worktree_start_points() {
|
||||
local -a refs
|
||||
refs=(
|
||||
${(fo)"$(git for-each-ref --format='%(refname:short)' refs/heads refs/remotes 2>/dev/null)"}
|
||||
)
|
||||
_describe 'start point' refs
|
||||
}
|
||||
|
||||
__worktree_active_branches() {
|
||||
local -a branches
|
||||
branches=(${(fo)"$(git worktree list --porcelain 2>/dev/null | \
|
||||
@@ -49,7 +57,9 @@ _worktree() {
|
||||
curcontext="${curcontext%:*:*}:worktree-cmd-$words[1]:"
|
||||
case $line[1] in
|
||||
(add)
|
||||
_arguments '1:: :__worktree_branches'
|
||||
_arguments \
|
||||
'1:: :__worktree_branches' \
|
||||
'2:: :__worktree_start_points'
|
||||
;;
|
||||
(cd)
|
||||
_arguments '1:: :__worktree_all_branches'
|
||||
|
||||
@@ -81,14 +81,17 @@ __worktree_find_in() {
|
||||
|
||||
worktree() {
|
||||
if [[ "$1" == "" ]]; then
|
||||
echo "usage: worktree {add,cd,list,remove,sync} <branch> [<branch>...]
|
||||
echo "usage: worktree add <branch> [<start-point>]
|
||||
worktree {cd,list,remove,sync} <branch> [<branch>...]
|
||||
worktree find [-i] <glob>"
|
||||
return 1
|
||||
elif [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
||||
echo "usage: worktree {add,cd,list,remove,sync} <branch> [<branch>...]
|
||||
echo "usage: worktree add <branch> [<start-point>]
|
||||
worktree {cd,list,remove,sync} <branch> [<branch>...]
|
||||
worktree find [-i] <glob>
|
||||
|
||||
Manage git worktrees by branch name."
|
||||
Manage git worktrees by branch name. A new branch starts from <start-point>,
|
||||
e.g. other/main, or origin/main by default."
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -114,10 +117,34 @@ Manage git worktrees by branch name."
|
||||
print -P "%F{red}error:%f missing <branch> argument"
|
||||
return 1
|
||||
fi
|
||||
if (( $# > 3 )); then
|
||||
print -P "%F{red}error:%f unexpected argument: $4"
|
||||
return 1
|
||||
fi
|
||||
local start=$3
|
||||
local root=$(git rev-parse --show-toplevel)
|
||||
local wt_dest=${root:h}/${root:t}@${branch}
|
||||
if ! git show-ref --verify --quiet refs/heads/"$branch" && \
|
||||
! git show-ref --verify --quiet refs/remotes/origin/"$branch"; then
|
||||
if [[ -n "$start" ]] && \
|
||||
! git rev-parse --verify --quiet "$start^{commit}" >/dev/null; then
|
||||
# A <remote>/<branch> start point that hasn't been fetched yet is
|
||||
# fetched now. Remote names can contain slashes, so the longest
|
||||
# matching remote wins.
|
||||
local remote= r
|
||||
for r in $(git remote); do
|
||||
[[ "$start" == "$r"/?* ]] && (( ${#r} > ${#remote} )) && remote=$r
|
||||
done
|
||||
if [[ -n "$remote" ]]; then
|
||||
local rbranch=${start#$remote/}
|
||||
git fetch "$remote" \
|
||||
"+refs/heads/${rbranch}:refs/remotes/${remote}/${rbranch}" || return 1
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$start" ]]; then
|
||||
# An explicit <start-point> always makes a new branch, so this fails
|
||||
# rather than silently ignoring it when the branch already exists.
|
||||
git branch "$branch" "$start" || return 1
|
||||
elif ! git show-ref --verify --quiet refs/heads/"$branch" && \
|
||||
! git show-ref --verify --quiet refs/remotes/origin/"$branch"; then
|
||||
git branch "$branch" origin/main || return 1
|
||||
fi
|
||||
git worktree add "$wt_dest" "$branch" || return 1
|
||||
|
||||
Reference in New Issue
Block a user