获取特定年龄的 git 分支
我的组织正在广泛使用 git 分支。结果,我们在过去的一年里已经生产了 2000 多个分支。我们现在正在尝试采取一种策略来清理所有具有一定年龄的旧分支。我知道如何删除分支,但我找不到一种简单的方法来列出具有给定年龄的头的所有分支。该计划是建立一个 cron 定期删除给定年龄的所有分支,除了某些列表中的分支。
以前有人尝试过类似的事情吗?
My organization is using git branching extensively. As a result, we have produced over 2000 branches in the past year. We are now trying to adopt a strategy for cleaning up all the old branches that are of some given age. I know how to delete branches, but I can't find a straightforward way to list all of the branches with heads of a given age. The plan is to set up a cron that periodically deletes all branches of a given age, except those that are on some list.
Has anyone tried anything like this before?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用提交者日期的答案是一个很好的方向......如果您想删除指向旧提交的分支。但您可能想删除实际上旧的分支;如果您今天创建一个分支指向去年的提交,您不希望它被擦除!
因此,您想检查转发日期。
您可以使用 git reflog show --date=local mybranch 获得人类可读的表单:(
您可能也喜欢
--date=relative
)顶部的条目是该分支上最近发生的事情,所以这就是我们关心的部分。不幸的是,没有仅用于日期的日志格式占位符,因此为了仅获取日期,我们做了一些工作:
当然,对于脚本编写来说,这不是很有用,所以让我们继续获取纪元时间:
现在我们已经取得进展了!
一个示例脚本!我使用
date
来转换人类可读的截止日期,然后对于每个分支,我检查引用日志的最后日期是否在截止日期之前,如果是,则删除该分支。您可以在其中添加针对白名单的检查,以避免意外删除您关心的内容。 (编辑:如果分支超过 90 天,这不会删除它们,因为它们的引用日志已经是空的...取决于您在这种情况下想要做什么,真的。您可以回退到检查提交者日期,此时应该非常安全。)编辑:这是另一种方法。在截止时间使 reflog 过期,然后删除 reflog 为空的分支。这里的问题是,如果截止时间早于您的引用日志已经过期的时间(90 天),它实际上只会删除早于 90 天的分支。当然,你可以解决这个问题。
The answers using committer dates are a good direction... if you want to delete branches that point to old commits. But you might want to delete branches which are actually old; if you create a branch today pointing to a commit from last year, you don't want it wiped!
So, you want to examine the reflog dates instead.
You can get a human-readable form with
git reflog show --date=local mybranch
:(You might also like
--date=relative
)The entry on the top is the most recent thing that happened on that branch, so that's the bit we care about. Unfortunately, there's no log format placeholder for just the date, so to grab out just the date, we do a little work:
Of course, for scripting, that's not very useful, so let's go ahead and get the epoch time instead:
Now we're getting somewhere!
An example script! I used
date
to convert a human-readable date for the cutoff, then for each branch, I checked if the reflog's last date was before the cutoff, and if so, deleted the branch. You could add in a check against a whitelist there, to save yourself from accidentally deleting something you care about. (Edit: if the branches are older than 90 days, this won't delete them, because their reflogs will already be empty... up to you what you want to do in that case, really. You could fall back to checking the committer date, which ought to be pretty safe at that point.)Edit: Here's another approach. Expire the reflogs at the cutoff time, then delete the branches whose reflogs are empty. The problem here is that if the cutoff time is older than the time when your reflogs already expire (90 days) it'll really just be deleting branches older than 90 days instead. You could work around that, of course.
更新:如 Jefromi 和 cebewee 在下面指出,此解决方案查看每个分支提示处提交的“提交者日期”,在某些情况下,这还不够好 - 如果您关心的话,请使用前者的示例最近基于更旧的分支创建的分支,您需要使用引用日志,如 Jefromi 的回答。我认为对于很多情况来说这已经足够好了,所以我留下答案而不是删除它......
我做了一个 最近关于此的博客文章,其中有一个脚本按上次提交日期的升序列出分支在那个分支上,我发现它对于与你的情况非常相似的情况很有用。该脚本基于 git for-each-ref --sort=committerdate :
Update: as Jefromi and cebewee point out below, this solution looks at the 'committer date' of the commit at each branch tip, and in some situations this wouldn't be good enough - to use the former's example, if you care about branches which were recently created based on much older branches, you'd need to use the reflog as in Jefromi's answer. I think that for plenty of situations this is good enough, though, so I'm leaving the answer rather than deleting it...
I did a blog post on this recently, with a script that lists branches in increasing order of the date of the last commit on that branch, which I've found useful for a very similar situation to yours. The script is based around
git for-each-ref --sort=committerdate
:您需要编写脚本,然后使用它来获取日期:
这应该为您提供可以订购的日期。
现在您只需要迭代分支:
希望这会有所帮助。
You will need to script it and then use this to grab the date:
this should give you date that you can order by.
Now you just need to iterate over the branches:
hope this helps.
我最终得到了这个解决方案:
它还按给定的模式过滤分支,因为我们使用 try-XX 约定进行分支。
I've ended up with this solution:
Also It filters branches by a given patter, since we're using try-XX convention for branching.
要查明分支上次更改的时间(相对于分支中上次提交的日期),您需要使用引用日志。
git reflogbranchName -1--date=relative
显示分支的最新引用日志条目以及上次更改分支的日期。有多种不同的日期格式,请选择一种易于解析以适合您的用例的格式。
此解决方案的一个问题是,reflog 默认在 IIRC 90 天后过期。因此,如果分支上的最后一次更改早于 90 天(并且您执行了 gc),则您不会获得有关该分支的任何信息。您可以通过更改引用日志的过期时间来规避此问题,请参阅 git-config 了解这一点。
To find out when a branch last changed (opposed to the date of the last commit in a branch), you need to utilize the reflog.
git reflog branchName -1--date=relative
displays for a branch the newest reflog entry and the date of the last change to the branch.There are various different date formats, choose one which is easy to parse for your use case.
A problem with this solution is that the reflog expires by default in IIRC 90 days. So, if the the last change on a branch is older then 90 days (and you dould a gc), you do not get any information about this branch. You circumvent this by changing the expire time for the reflog, see git-config for this.
一个非常简单的解决方案,但并不总是有效:
只需查看 .git/refs/heads/ 并按修改日期排序。
请注意,如果存储库较新或其他原因,这将不起作用,因为 git 根本不跟踪此类信息。但是,当您拥有一个不会发生太大变化的中央存储库时,它在未来可能会工作得很好。
A very simple solution, which does not always work:
Just look at
.git/refs/heads/
and sort by modification date.Note that this won't work if the repository is newer or something, as git simply doesn't track such information. But it might work very well in the future, when you have a central repository which otherwise doesn't change much.