得到一定年龄的git分支

Kal*_*erg 21 git version-control git-branch

我的组织广泛使用git分支.因此,我们在过去一年中已经生产了2000多个分支机构.我们现在正在尝试采取一种策略来清理所有特定年龄的旧分支.我知道如何删除分支,但我找不到一种简单的方法来列出具有给定年龄的所有分支.计划是建立一个定期删除给定年龄的所有分支的cron,除了某些列表中的分支.

以前有人试过这样的事吗?

Cas*_*bel 20

使用提交者日期的答案是一个很好的方向...如果你想删除指向旧提交的分支.但是你可能想要删除实际上很旧的分支; 如果你今天创建一个指向去年提交的分支,你不希望它被删除!

因此,您想要检查reflog日期.

您可以通过以下方式获得人类可读的表单git reflog show --date=local mybranch:

8b733bc mybranch@{Tue Mar 22 13:21:49 2011}: commit: foo
7e36e81 mybranch@{Tue Mar 22 13:21:25 2011}: commit: bar
99803da mybranch@{Tue Mar 22 13:20:45 2011}: branch: Created from otherbranch
Run Code Online (Sandbox Code Playgroud)

(你可能也喜欢--date=relative)

顶部的条目是该分支上发生的最新事情,所以我们关心的是这一点.不幸的是,日期没有日志格式占位符,所以为了抓住日期,我们做了一些工作:

git log -g -n 1 --date=local --pretty=%gd mybranch | sed 's/.*{\(.*\)}/\1/'
# Prints "Mon Mar 21 13:23:26 2011"
Run Code Online (Sandbox Code Playgroud)

当然,对于脚本来说,这不是很有用,所以让我们继续前进并获得大纪元时间:

git log -g -n 1 --date=raw --pretty=%gd mybranch | sed 's/.*{\(.*\) .*/\1/'
# Prints 1300731806
Run Code Online (Sandbox Code Playgroud)

现在我们到了某个地方!

#!/bin/bash
cutoff_date=$(date --date="July 23, 2010" +%s)
git for-each-ref refs/heads --format='%(refname)' | while read branch; do
    reflog_date=$(git log -g -n 1 --date=raw --pretty=%gd $branch -- | sed 's/.*{\(.*\) .*/\1/')
    if [ -n "$reflog_date" && "$reflog_date" -lt "$cutoff_date" ]; then
        git branch -D ${branch#refs/heads/}
    fi
done
Run Code Online (Sandbox Code Playgroud)

一个示例脚本!我曾经date为截止值转换一个人类可读的日期,然后对于每个分支,我检查了reflog的最后日期是否在截止之前,如果是,则删除分支.您可以在那里添加对白名单的检查,以避免意外删除您关心的内容.(编辑:如果分支超过90天,这将不会删除它们,因为他们的reflogs已经是空的......在这种情况下,你真正想要做什么.你可以回到检查提交日期,在那一点上应该是非常安全的.)

编辑:这是另一种方法.在截止时间使reflogs到期,然后删除reflog为空的分支.这里的问题是,如果截止时间早于您的reflogs已经过期的时间(90天),那么它实际上只是删除超过90天的分支.当然,你可以解决这个问题.

#!/bin/bash

# Git lets you use very readable time formats!
cutoff_time="1 year ago"
# other examples:
# cutoff_time="July 23, 2010"
# cutoff_time="yesterday"

git for-each-ref refs/heads --format='%(refname)' | egrep -v 'master|other-whitelisted-branch' |
while read branch; do
    git reflog expire --expire="$cutoff_time" $branch
    if [ "$(git reflog show -1 $branch | wc -l)" -eq 0 ]; then
        git branch -D ${branch#refs/heads/}
    fi
done
Run Code Online (Sandbox Code Playgroud)