Please note this post details how to permanently delete branches from Git - make sure you’re comfortable/confident in doing this!

Gitlab has a big red button in the repository branch list to Delete merged branches which prompts you to be really sure you want to delete them, because there’s no way back.

Unfortunately if you have a backlog of stale branches - say, 500 - then you might be a little nervous about hitting this button…just in case.

Instead of having to click through 25 pages of branch listings, we can use the Gitlab API to pull out our branches, pipe them through jq and pick out the branches we want to delete. Branches can then be deleted from the git CLI and hopefully the branch backlog starts to get a little clearer.

You’ll need a couple of things to get started:

  • Personal Access Token to pass through the API - find it via the “Access Token” submenu from your “Settings” page (find this by clicking your profile menu in the top right). The token needs to have api permissions
  • Project ID for the project with the stale branches. This is shown Project ID: NNNNNNNN at the top of your repo’s front page or in “Settings > General”
  • Something to submit the API request and save the JSON response(s)
  • The jq utility to query the data
  • Git CLI to push branch deletions

Getting your branch list by API

It’s quite straight forward, but there’s a limit on how many branches are returned so you need to page through the results (the API returns Link fields in the header).

Using the Branch endpoint you can get your branch list with the following

curl --header "PRIVATE-TOKEN: <your_access_token>"<your_project_id>/repository/branches?per_page=100&page=1

100 seems to be the largest set we can get back, so inspect your Link field in the header to see how many you need to get and increment the page URL accordingly. For demonstration purposes, the JSON bodies of these requests can be saved to response-N.json where N is the page number.

Merging the JSON files

The jq tool can happily merge files:

jq -s '.[]' response-*.json > all.json

…Will merge the contents of each response array and put them into a single array under all.json. This makes it a bit easier to to query out.

Extracting the relevant fields

Because we’re looking to purge out really stale branches, we’ll pull out the branch name and committed date so we can sort the list

jq -r '.[] | .commit.committed_date + "," + .name' all.json | sort

This will create a list of oldest branches first - commit date and name separated by a comma. You can even add on a | pbcopy pipe if you’re on Mac and ready to paste these elsewhere.

Analysing stale branches

I’ve simply pasted these into a spreadsheet, split the text into columns and confirmed the dates and branches of names I want to delete. You can add a handy third column to generate the git command for you.

="git push origin --delete " & B2

This should yield a command git push origin --delete feature/name. Running this git command in your repo/directory will trigger a remote delete of the branch and you’re on your way to cleaning up your stale branch backlog.