Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the simplest way to display all branches that have not been committed to for more than 6 months?

Tags:

git

bash

shell

It seems like 1836 branches exist in one of the company's repos and I've been given a task to first display and then delete all branches that have not been committed to for 6 months.

I found this SO question and tried running (with both --until and --before and "month"):

#!/bin/bash
branches_to_delete_count=0
for k in $(git branch -a | sed /\*/d); do
  if [ -n "$(git log -1 --before='6 month ago' -s $k)" ]; then
    echo "NOT REALLY DELETING, git branch -D $k"
  fi
  ((branches_to_delete_count=branches_to_delete_count+1))
done
echo "Found $branches_to_delete_count branches to delete!"

But to no avail, I get the same number of branches to delete each time which is 1836.

What am I doing wrong? How can I list all branches that haven't been committed for more than 6 months?

like image 925
Itai Ganot Avatar asked Oct 24 '25 02:10

Itai Ganot


1 Answers

The reason why all your branches show up : git log branch does not look at branch's head only, it looks at its whole history.

git log -1 --before='6 month ago' branch will :

  • unroll the history of branch
  • keep only commits older than 6 month
  • keep the first of these commits

Since (in your company's repo) all branches have a commit that is at least 6 month old in their history, git log -1 --before='6 month ago' branch will always show one line.


You can instruct git log to list only the commits you provide on the command line, and not list their ancestors: git log --no-walk

The following command will show a one line summary for all branches (local and remote) that have a head commit older than 6 months:

git log --oneline --no-walk --before="6 months ago" --branches --remotes

You can use the format option to print only the branch names :

git log --format="%D" --no-walk --before="6 months ago" --branches --remotes

technical note:
if several branches point to the same commit, the above command will print several names separated by a coma, so you could technically see something like:

origin/branch1
origin/branch2, origin/branch3
origin/branch4
...

for scripting purposes, you may add ... | sed -e 's/, /\n/g' to be sure to have 1 branch name per line)


note: updated from my original answer, which suggested to run:

git for-each-ref --format="%(refname) %(creatordate)" --sort='-creatordate' refs/heads/

and use a second command to check the date

like image 168
LeGEC Avatar answered Oct 25 '25 18:10

LeGEC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!