#!/bin/bash # 把当前分支 merge 进目标分支;目标已在其它 worktree 时直接在那边 merge set -euo pipefail usage() { cat <<'EOF' 用法: git merge2 [git merge 参数...] 把当前分支合进 ,然后留在当前分支。 若 已在其它 worktree 里 checkout,则在那个 worktree 里 merge, 不会在当前目录 checkout(避免 "already used by worktree")。 EOF } if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then usage exit 0 fi if [[ $# -lt 1 ]]; then usage >&2 exit 1 fi current="$(git symbolic-ref --short HEAD)" target="$1" shift if [[ "$current" == "$target" ]]; then echo "已经在 $target 上" >&2 exit 1 fi # porcelain 含主 worktree;%(worktreepath) 只填 linked worktree,不能用 worktree_for_branch() { local branch="$1" local wt="" local line while IFS= read -r line || [[ -n "$line" ]]; do case "$line" in worktree\ *) wt="${line#worktree }" ;; "branch refs/heads/${branch}") printf '%s\n' "$wt" return 0 ;; "") wt="" ;; esac done < <(git worktree list --porcelain) return 1 } # alias / 子进程会继承当前 worktree 的 GIT_DIR,必须清掉才能 git -C 到另一个 worktree merge_in_worktree() { local wt="$1" shift env -u GIT_DIR -u GIT_WORK_TREE git -C "$wt" merge "$@" } wt="$(worktree_for_branch "$target" || true)" if [[ -n "$wt" ]]; then echo "在 worktree 中 merge $current -> $target: $wt" merge_in_worktree "$wt" "$current" "$@" else git checkout "$target" git merge "$current" "$@" git checkout "$current" fi