Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Delete stale branches of bitbucket repositories

Shaik Moulali December 24, 2021

Hi i wanted to delete the branches which are not in use since last six months. I wan to list it and delete it any suggestions

3 answers

2 votes
Caroline R
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
December 29, 2021

Hi, @Shaik Moulali! Welcome to the community! 

We currently don't have an option to bulk delete stale branches through UI nor through CLI. 

However, you can create a bash script locally to bulk delete those branches. We have a couple of suggestions that you can follow to achieve your goal: 

  1. If you have a list of branches that you can delete, you can run a setup bash script to run 'git push origin --delete <branch-name>' to delete the remote branch
  2. If you would like to get a list of branches with the last commit date, the following commands will help: 
    git clone --mirror <Repo-URL>
    cd <Repo-name>
    git for-each-ref --sort=committerdate refs/heads/ --format='(%(color:green)%(committerdate:relative)%(color:reset))  %(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname)'
    

    There's a sample script that you can use to bulk delete old branches:
    Source: https://www.digitalocean.com/community/questions/how-to-delete-old-remote-git-branches-via-git-cli-or-a-bash-script?answer=63906

  • We've modified the script if you are using mirror repo: 
    #!/bin/bash
    ##
    # Script to delete remote git branches
    ##
    # Fetch the remote resources
    git fetch
    # Loop through all remote merged branches
    for branch in $(git branch --merged | grep -v HEAD | grep -v develop | grep -v master | grep -v master | sed /\*/d); do
            if [ -z "$(git log -1 --since='Jun 15, 2020' -s ${branch})" ]; then
                    echo -e `git show --format="%ci %cr %an" ${branch} | head -n 1` \\t$branch
                    remote_branch=$(echo ${branch} | sed 's#origin/##' )
                    # To delete the branches uncomment the bellow git delete command
                    # git branch -D ${remote_branch}
            fi
    done
    
  • As described on the community page:
    • You can delete the `--merged` flag so that the script would delete all branches no matter if merged or not
    • The --since='Jun 15, 2020' date indicates the date since the branch has been last worked on. The above example will delete all branches that have been idle (eg. no commits or any other activity) since Jun 15, 2020. Update it with the date that matches your needs.
  • Once the script is completed, you can run 'git push origin' to push the latest changes back to Bitbucket

With that said, we also would like to share with you that we already have a feature request for our dev team to allow users to set a retention period for deleting unused branches. You can access this request here: 

I've linked this question to the feature. Please consider adding yourself as a watcher. This way you get updated as we make progress with this. If you are not familiar with our Feature Request Policy, you can read more about it here.

I hope this helps, but do let me know if you have any questions.

Kind regards,
Caroline

Shaik Moulali February 9, 2022

@Caroline R  why multiple grep for master and i used this code to list the branches it is not working

Caroline R
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
February 11, 2022

Hi, @Shaik Moulali

Could you please give us more details about what is failing? When you try to run the command to just list the branches, what shows up?

Thank you!

Kind regards,
Caroline

Phani Cherukuri August 31, 2022

Hi @Caroline R , i tried with this script but everytime it shows all the branches (for any given date, if i remove --merged) except for development and master. Can you help me here??

Caroline R
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
September 6, 2022

Hi @Phani Cherukuri

I would like to ask if you could please create a new question for your issue, providing details on the errors you see and also whether it concerns a Bitbucket Cloud or Bitbucket Server. 

We generally encourage users to create a new question for their issue instead of posting on someone else's question, because 1) the root cause and resolution may be different for each case 2) a question can become cluttered and difficult to follow if we try to troubleshoot multiple users' issues in it.

Please feel free to let me know if you have any questions. 

Kind regards,
Caroline 

0 votes
manoj reddy gajjala January 4, 2023

Below code works like champ. If it works Accept my answer.

import requests
import datetime
import json

# Constants
BITBUCKET_API_URL = "https://yourdomain.company.com"
projectKey = "enter_project_key"
repositorySlug = "enter_repo_name"

# Set up authentication
auth = (("username", "password"))

# Calculate the threshold date for deleting branches
six_months_ago = datetime.datetime.utcnow() - datetime.timedelta(days=180)

# Get a list of all branches in the repository
response = requests.get(f"{BITBUCKET_API_URL}/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/branches", auth=auth)
branches = response.json()["values"]
feature_branches = [branch for branch in branches if branch["displayId"].startswith("BK_")]
for branch in feature_branches:
branch_id = branch["displayId"]
response = requests.get(f"{BITBUCKET_API_URL}/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/commits?until={branch_id}&limit=0&start=0", auth=auth)
commits = response.json()["values"]
for commit in commits:
timestamp = int(commit['authorTimestamp']) / 1000 # Convert from milliseconds to seconds
commit_date = datetime.datetime.fromtimestamp(timestamp)
if commit_date < six_months_ago:
try:
payload = json.dumps({
"name": branch_id
})

headers = {
'Content-Type': 'application/json'
}

url = f"{BITBUCKET_API_URL}/rest/branch-utils/latest/projects/{projectKey}/repos/{repositorySlug}/branches"
print(f"Sending DELETE request to {url} with payload: {payload}")
response = requests.request("DELETE", url, headers=headers, data=payload, auth=auth)
print(response.text)
print(f"Response: {response.status_code} {response.reason}")
print(f"Deleting branch {branch_id}")
except Exception as e:
print(f"Failed to delete branch {branch_id}: {e}")
else:
print(f"Skipping branch {branch_id}")



0 votes
Aron Gombas _Midori_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 25, 2021

There are really good ideas in this topic:

https://stackoverflow.com/questions/13064613/how-to-prune-local-tracking-branches-that-do-not-exist-on-remote-anymore

I think that a good definition of a branch to delete would be a branch that has its head older than N days and not merged to master. The first one alone is not enough. Also you may want to delete feature/* and bugfix/* only, not everything. Be careful! 

(You should be able to modify those one-line Linux commands to delete branches remotely.)

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events