62

我发现下面的脚本按日期列出了分支。如何过滤它以排除较新的分支并将结果提供给 Git 删除命令?

for k in $(git branch | sed /\*/d); do 
  echo "$(git log -1 --pretty=format:"%ct" $k) $k"
done | sort -r | awk '{print $2}'
4

14 回答 14

66

使用--sinceand怎么样--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 或任何签出分支的分支。

于 2012-04-26T00:38:10.510 回答
38

穷人的方法:

按上次提交日期列出分支:

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

于 2018-04-24T09:37:33.060 回答
5

这对我有用:

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 可以工作了。

于 2016-09-01T17:03:32.147 回答
4

这类似于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
于 2015-08-20T06:29:16.573 回答
4

仅显示一个月前最后一次提交合并到主分支的本地分支的删除命令的安全方法。

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直接删除)

这是非常安全的。

于 2019-10-31T14:46:00.523 回答
2

上面的代码对我不起作用,但很接近。相反,我使用了以下内容:

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
于 2018-07-16T18:24:56.910 回答
1
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
于 2020-02-19T20:59:25.627 回答
1

删除 5 个最旧的远程分支

git branch -r --sort=committerdate | head -n 5 | sed 's/  origin\///' | xargs git push origin --delete
于 2021-04-23T15:27:28.830 回答
1

git 分支 --sort=committerdate | 头-n10 | xargs git 分支 -D

于 2021-09-17T12:10:28.263 回答
0

我假设您只想删除 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

于 2012-04-26T01:21:28.587 回答
0

基于@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

这可用于删除所有旧分支(合并或不合并)。这样做的动机是,一个月内未触及的分支不太可能腐烂并且永远无法掌握。自然,修剪旧分支的时间范围取决于主分支移动的速度。

于 2018-09-07T18:20:15.460 回答
0

有时它需要知道一个分支是否已合并到主分支。为此,可以使用以下脚本:

#!/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 上测试

于 2020-04-01T15:09:57.227 回答
0

实际上,由于本的评论,我发现接受的答案对我来说不够可靠。我一直在寻找清理旧的发布分支,所以有可能顶部提交已经被挑选出来并且有一个旧的提交日期......这是我的看法:

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

您可以根据需要轻松调整删除命令。小心使用它。

输出示例: 在此处输入图像描述

于 2021-09-29T15:11:52.623 回答
0

关于如何使用PowerShell:

  • 删除除 notMatch 模式之外的所有合并分支
git branch -r --merged | Select-String -NotMatch "(^\*|master)" | %{ $_ -replace ".*/", "" } | %{ git push origin --delete $_ }
  • 列出txt文件中所有合并的分支
git branch -r --merged | Select-String -NotMatch "(^\*|master)" | %{ $_ -replace ".*/", "" } | Set-Content -Path .\deleted-branches.txt
于 2022-01-21T13:36:02.690 回答