Delete all branches that are more than X days/weeks old

Safe way to show the delete commands only for local branches merged into master with the last commit over a month ago.

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

This does nothing but to output something like:

git branch -d issue_3212
git branch -d fix_ui_search
git branch -d issue_3211

Which I copy and paste directly (remove the echo to delete it directly)

This is very safe.


The poor man's method:

List the branches by the date of last commit:

git branch --sort=committerdate | xargs echo

this will list the branches while xargs echo pipe makes it inline (thx Jesse).

You will see all your branches with old ones at the beginning:

1_branch 2_branch 3_branch 4_branch

Copy the first n ones, which are outdated and paste at the end of the batch delete command:

git branch -D 1_branch 2_branch

This will delete the selected ones only, so you have more control over the process.

To list the branches by creation date, use the --sort=authordate:iso8601 command as suggested by Amy

Remove remote branches

Use git branch -r --sort=committerdate | xargs echo (says kustomrtr) to review the remote branches, than git push origin -d 1_branch 2_branch to delete the merged ones (thx Jonas).


This is what worked for me:

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

The crucial part is that the branch name (variable $k) contains the /origin/ part eg origin/feature/my-cool-new-branch However, if you try to git push --delete, it'll fail with an error like:
unable to delete 'origin/feature/my-cool-new-branch': remote ref does not exist.
So we use sed to remove the /origin/ part so that we are left with a branch name like feature/my-cool-new-branch and now git push --delete will work.


How about using --since and --before?

For example, this will delete all branches that have not received any commits for a week:

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

If you want to delete all branches that are more than a week old, use --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

Be warned though that this will also delete branches that where not merged into master or whatever the checked out branch is.

Tags:

Shell

Git