【问题标题】:Delete all branches that are more than X days/weeks old删除所有超过 X 天/周的分支
【发布时间】:2012-05-06 17:22:43
【问题描述】:

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

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

【问题讨论】:

  • 这不是有点违背版本控制系统的目的吗?
  • @haziz:删除分支并不意味着删除历史;分支只是提交时的命名指针。
  • 我们在本地运行 git,远程运行 svn,所以 git 只用于本地工作。

标签: git shell


【解决方案1】:

使用--since--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 或任何已签出分支的分支。

【讨论】:

  • 这个解决方案比我自己的更优雅。
  • 上面的代码很好,但我的测试只删除了过去一周收到提交的分支。我必须将 -n 更改为 -z 才能使其正常工作。另外,如果您想更安全一点,请将 -D 更改为 -d 以便它只会删除合并的分支。
  • 示例应该使用--before而不是--since。注意不要盲目运行!
  • 我不明白这是如何工作的。 --before 选项只返回早于给定日期的 any 提交。因此,除非您的项目刚刚创建,否则该条件将始终返回一些提交。我正在使用 OS X (zsh),上面的代码返回所有分支
  • 小心!第二个脚本“早于”将删除所有分支。我成功使用了这个脚本gist.github.com/AvnerCohen/b8a40c62f8097d8c7b14
【解决方案2】:

穷人的方法:

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

git branch --sort=committerdate | xargs echo

这将列出分支,而xargs echo 管道使其内联(thx 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).

【讨论】:

  • $ git --version git version 2.1.4 $ git branch --sort=committerdate error: unknown option 'sort=committerdate'
  • @user151841 那是因为它应该说--sort=-committerdate
  • 这对我来说是最好的。您可以通过 git branch --sort=committerdate | xargs echo 跳过在编辑器中将它们设为一行的部分。此外,关于在提交日期之前放置“-”的评论是错误的,它将最新的放在顶部。无论如何,您可以将它们复制到要删除的位置,然后将它们放在git branch -D ... 之后
  • git branch -r --sort=committerdate | xargs echo 以防万一有人想查看远程分支。
  • git push origin -d 1_branch 2_branch 删除远程分支。
【解决方案3】:

这对我有用:

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

【讨论】:

  • 当您使用 git branch -r 时,我认为您不需要 sed /\*/d - 它所做的只是删除指向您当前分支的 * 字符。 git branch -r 不行。
【解决方案4】:

这类似于 Daniel Baulig 的回答,但也考虑了 ben 的评论。它还按给定的模式过滤分支,因为我们使用 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

【讨论】:

    【解决方案5】:

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

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

    这是非常安全的。

    【讨论】:

      【解决方案6】:

      above code 对我不起作用,但很接近。相反,我使用了以下内容:

      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
      

      【讨论】:

        【解决方案7】:
        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
        

        【讨论】:

          【解决方案8】:

          删除 5 个最旧的远程分支

          git branch -r --sort=committerdate | head -n 5 | sed 's/  origin\///' | xargs git push origin --delete
          

          【讨论】:

            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

              我假设您只想删除 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...但要小心,因为这会导致悬空提交在某些时候被垃圾收集。

              【讨论】:

                【解决方案11】:

                根据@daniel-baulig 的回答和我想出的cmets:

                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
                

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

                【讨论】:

                  【解决方案12】:

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

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

                  【讨论】:

                    【解决方案13】:

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

                    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
                    

                    您可以根据需要轻松调整删除命令。请谨慎使用。

                    输出示例:

                    【讨论】:

                      【解决方案14】:

                      了解如何使用 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
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2018-08-24
                        • 2015-04-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多