我非常喜欢git worktree命令。我的项目目录包含许多文件夹,这些文件夹指向我目前正在处理的分支。
.../project directory
├── bugfix
│ ├── IBD-15
│ ├── IBD-17
│ ├── IBD-18
│ ├── IBD-21
│ ├── IBD-22
│ └── IBD-23
...
├── main
└── story
├── logs
└── IBD-7
X directories 经过一段时间,我通过使用CI工具的合并请求(CI自动删除远程分支)关闭了一个特性。但是特性分支在项目文件夹中保持活动状态,我需要定期查看关闭的特性列表,并手动删除指向远程上不存在的分支的文件夹:
$ rm -rf bugfix/IBD-15
$ rm -rf bugfix/IBD-23
...
$ git worktree prune那么,是否有一种方法可以使工作树文件夹用于分支,这些分支在remote上已经不存在了(当然,如果'worktree‘文件夹不包含未推送、提交或未跟踪的本地更改)?
发布于 2022-10-29 10:25:07
我刚刚测试了git fetch --prune之后发生的关于现有工作树的事情。
一个git branch -avv将显示:
+ ee 60f5e46 (C:/Users/vonc/git/tests/b2/ee) [origin/ee: gone] Move...这意味着你可以做这样的事情:
git branch -avv|grep ": gone"|cut -f 2 -d '('|cut -f 1 -d ')'|xargs git worktree remove你所有过时的工作树都会消失。一条龙。
发布于 2022-11-01 10:38:35
我为周末编写了一个交互式bash脚本,它遍历所有的工作树文件夹,并要求用户删除该文件夹。脚本检查工作树文件夹中是否存在上游分支是否存在远程或未受惩罚的提交。您需要从任何工作树文件夹中运行脚本,它将完成它的工作。
#!/usr/bin/env bash
# filename: worktree-cleanup
#
# get rid 'worktree' folders which branches doesn't exists
# This script automatically walks through all wortree folders
# and ask for removing them
#
CUR_DIR=$(pwd)
function pushd {
command pushd "$@" > /dev/null
}
function popd {
command popd "$@" > /dev/null
}
function locate_git_tool {
for path in ${PATH//:/ }; do
[ -x "$path/git" ] && echo "$path/git" && break
done
echo ""
} # end of function locate_git_tool
function git_fetch {
$GIT_TOOL fetch --all
}
function contains_untracked_changes {
local dir=$1
pushd "$dir"
local status="$($GIT_TOOL status --short)"
popd
echo "$status"
} # end of function contains_untracked_changes
function is_git_dir {
local dir="$1"
pushd "$dir"
[ -d "$dir" ] && [ -d "$dir/.git" -o -e "$dir/.git" ]
popd
} #end of function is_git_dir
function is_dir_exist {
[ -e "$@" -a -d "$@" ]
} # end of function is_dir_exist
function is_current_dir {
[ "$CUR_DIR" == "$@" ]
}
function choose {
local default="$1"
local prompt="$2"
local choice_yes="$3"
local choice_no="$4"
local answer
read -p "$prompt" answer
[ -z "$answer" ] && answer="$default"
case "$answer" in
[yY1] ) eval "$choice_yes"
;;
[nN0] ) eval "$choice_no"
;;
* ) printf "%b" "Unexpected answer '$answer'!" >&2 ;;
esac
} # end of function choose
function contains_unpushed_commits {
pushd "$@"
local output=$(git log @{u}.. -p)
popd
echo "$output"
}
function is_upstream_branch_exists {
local path="$1"
local branch="$2"
pushd "$path"
local output=$(git ls-remote --heads --quiet | grep 'branch')
popd
echo "$output"
}
function cleanup_worktree_folder {
local path="$1"
choose "y" \
"Remove $path? (y or n)" \
"$GIT_TOOL worktree remove --force \"$path\"" \
":"
}
function check_and_cleanup_forlder {
local path="$1"
local branch="$2"
if [ ! -z "$(contains_untracked_changes $path)" ] ; then
printf "%s\n%s\n" "Warning: $path contains changes" "$(contains_untracked_changes $path)"
cleanup_worktree_folder "$path"
elif [ -z "$(is_upstream_branch_exists $path $branch)" ] ; then
printf "%s\n" "Warning: $path doesn't have upstream branch"
cleanup_worktree_folder "$path"
elif [ ! -z "$(contains_unpushed_commits $path)" ] ; then
printf "%s\n%s\n" "Warning: $path" "$(contains_unpushed_commits $path)"
else
cleanup_worktree_folder "$path"
fi
}
GIT_TOOL=$(locate_git_tool)
[ -x "${GIT_TOOL}" ] || { printf "%b" "Fatal: 'git' tool not found.\n" ; exit 1 ; }
[ -d "$CUR_DIR/.git" -o -e "$CUR_DIR/.git" ] || { printf "%b" "Fatal: not a git repository.\n" ; exit 1 ; }
git_fetch
IFS=$'\n'
for line in $($GIT_TOOL worktree list) ; do
path=$(echo $line | awk '{print $1}')
branch=$(echo $line | awk '{print $3}')
branch="${branch%]}"
branch="${branch#[}"
if ! $(is_dir_exist "$path") ; then
echo "$path not exists"
elif $(is_current_dir "$path") ; then
:
elif ! $(is_git_dir "$path") ; then
printf "%b" "Warning: not a git repository. Skip.\n"
else
check_and_cleanup_forlder "$path" "$branch"
fi
done
unset IFS您可以找到脚本这里
https://stackoverflow.com/questions/74244099
复制相似问题