Issue
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?
Solution
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
Answered By - LeGEC Answer Checked By - David Marino (WPSolving Volunteer)