我发现下面的脚本按日期列出了分支。如何过滤它以排除较新的分支并将结果提供给 Git 删除命令?
for k in $(git branch | sed /\*/d); do
echo "$(git log -1 --pretty=format:"%ct" $k) $k"
done | sort -r | awk '{print $2}'
使用--since
and怎么样--before
?
例如,这将删除一周内未收到任何提交的所有分支:
for k in $(git branch | sed /\*/d); do
if [ -z "$(git log -1 --since='1 week ago' -s $k)" ]; then
git branch -D $k
fi
done
如果要删除超过一周的所有分支,请使用--before
:
for k in $(git branch | sed /\*/d); do
if [ -z "$(git log -1 --before='1 week ago' -s $k)" ]; then
git branch -D $k
fi
done
请注意,这也会删除未合并到 master 或任何签出分支的分支。
穷人的方法:
按上次提交日期列出分支:
git branch --sort=committerdate | xargs echo
这将列出分支,而 xargs echo
管道使其内联(谢谢Jesse)。
您将在开始时看到所有带有旧分支的分支:
1_branch 2_branch 3_branch 4_branch
复制前 n 个,它们已过时并粘贴在批量删除命令的末尾:
git branch -D 1_branch 2_branch
这将仅删除选定的那些,因此您可以更好地控制该过程。
要按创建日期列出分支,请使用Amy--sort=authordate:iso8601
建议的命令
使用
git branch -r --sort=committerdate | xargs echo
(说
kustomrtr)查看远程分支,而不是git push origin -d 1_branch 2_branch
删除合并的
分支(谢谢Jonas)。
这对我有用:
for k in $(git branch -r | sed /\*/d); do
if [ -z "$(git log -1 --since='Aug 10, 2016' -s $k)" ]; then
branch_name_with_no_origin=$(echo $k | sed -e "s/origin\///")
echo deleting branch: $branch_name_with_no_origin
git push origin --delete $branch_name_with_no_origin
fi
done
关键部分是分支名称(变量 $k)包含/origin/
部分例如origin/feature/my-cool-new-branch
但是,如果您尝试 git push --delete,它将失败并出现错误,例如:
无法删除 'origin/feature/my-cool- new-branch':远程引用不存在。
所以我们使用 sed 删除/origin/
部分,这样我们就剩下一个分支名称feature/my-cool-new-branch
,现在 git push --delete 可以工作了。
这类似于Daniel Baulig的回答,但也考虑了本的评论。它还通过给定的模式过滤分支,因为我们使用 try-XX 约定进行分支。
for k in $(git branch -r | awk -F/ '/\/YOUR_PREFIX_HERE/{print $2}' | sed /\*/d); do
if [ -z "$(git log -1 --since='Jul 31, 2015' -s origin/$k)" ]; then
echo deleting "$(git log -1 --pretty=format:"%ct" origin/$k) origin/$k";
git push origin --delete $k;
fi;
done
仅显示一个月前最后一次提交合并到主分支的本地分支的删除命令的安全方法。
for k in $(git branch --format="%(refname:short)" --merged master); do
if (($(git log -1 --since='1 month ago' -s $k|wc -l)==0)); then
echo git branch -d $k
fi
done
这除了输出如下内容外什么也没做:
git branch -d issue_3212
git branch -d fix_ui_search
git branch -d issue_3211
我直接复制粘贴(去掉echo直接删除)
这是非常安全的。
上面的代码对我不起作用,但很接近。相反,我使用了以下内容:
for k in $(git branch | sed /\*/d); do
if [[ ! $(git log -1 --since='2 weeks ago' -s $k) ]]; then
git branch -D $k
fi
done
for k in $(git branch -r | sed /\*/d); do
if [ -n "$(git log -1 --before='80 week ago' -s $k)" ]; then
git push origin --delete "${k/origin\//}"
fi
done
删除 5 个最旧的远程分支
git branch -r --sort=committerdate | head -n 5 | sed 's/ origin\///' | xargs git push origin --delete
git 分支 --sort=committerdate | 头-n10 | xargs git 分支 -D
我假设您只想删除 refs,而不是分支中的提交。要删除除最新分支之外的所有合并分支__X__
:
git branch -d `for k in $(git branch | sed /\*/d); do
echo "$(git log -1 --pretty=format:"%ct" $k) $k"
done | sort -r | awk 'BEGIN{ORS=" "}; {if(NR>__X__) print $2}'`
删除时间戳之前的所有分支__Y__
:
git branch -d `for k in $(git branch | sed /\*/d); do
echo "$(git log -1 --pretty=format:"%ct" $k) $k"
done | sort -r | awk 'BEGIN{ORS=" "}; {if($1<__Y__) print $2}'`
如果您还想删除尚未合并的分支,请将-d
选项替换为...但要小心,因为这会导致悬空提交在某些时候被垃圾收集。-D
基于@daniel-baulig 的回答和我提出的评论:
for k in $(git branch -r --format="%(refname:short)" | sed s#^origin/##); do
if [ -z "$(git log -1 --since='4 week ago' -s $k)" ]; then
## Info about the branches before deleting
git log -1 --format="%ci %ce - %H $k" -s $k;
## Delete from the remote
git push origin --delete $k;
## Delete the local branch, regardless of whether it's been merged or not
git branch -D $k
fi;
done
这可用于删除所有旧分支(合并或不合并)。这样做的动机是,一个月内未触及的分支不太可能腐烂并且永远无法掌握。自然,修剪旧分支的时间范围取决于主分支移动的速度。
有时它需要知道一个分支是否已合并到主分支。为此,可以使用以下脚本:
#!/usr/bin/env bash
read -p "If you want delete branhes type 'D', otherwise press 'Enter' and branches will be printed out only: " action
[[ $action = "D" ]] && ECHO="" || ECHO="echo"
for b in $(git branch -r --merged origin/master | sed /\*/d | egrep -v "^\*|master|develop"); do
if [ "$(git log $b --since "10 months ago" | wc -l)" -eq 0 ]; then
$ECHO git push origin --delete "${b/origin\/}" --no-verify;
fi
done
在 Ubuntu 18.04 上测试
实际上,由于本的评论,我发现接受的答案对我来说不够可靠。我一直在寻找清理旧的发布分支,所以有可能顶部提交已经被挑选出来并且有一个旧的提交日期......这是我的看法:
REMOTE_NAME=origin
EXPIRY_DATE=$(date +"%Y-%m-%d" -d "-4 week")
git fetch $REMOTE_NAME --prune
git for-each-ref --format='%(committerdate:short) %(refname:lstrip=3) %(refname:short)' --sort -committerdate refs/remotes/$REMOTE_NAME | while read date branch remote_branch; do
# protected branch
if [[ $branch =~ ^master$|^HEAD$ ]]; then
printf "%9s | %s | %50s | %s\n" "PROTECTED" $date $branch $remote_branch
elif [[ "$date" < "$EXPIRY_DATE" ]]; then
printf "%9s | %s | %50s | %s\n" "DELETE" $date $branch $remote_branch
#git push $REMOTE_NAME --delete $branch
fi
done
您可以根据需要轻松调整删除命令。小心使用它。
关于如何使用PowerShell:
git branch -r --merged | Select-String -NotMatch "(^\*|master)" | %{ $_ -replace ".*/", "" } | %{ git push origin --delete $_ }
git branch -r --merged | Select-String -NotMatch "(^\*|master)" | %{ $_ -replace ".*/", "" } | Set-Content -Path .\deleted-branches.txt