Delete stale branches of bitbucket repositories
Asked by Shaik Moulali:

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


Answers:
author: Caroline R
body: Hi, [@Shaik Moulali](/t5/user/viewprofilepage/user-id/4685941)! 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 resourcesgit fetch# Loop through all remote merged branchesfor 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}        fidone
  ```

<!-- -->

* 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:

* <https://jira.atlassian.com/browse/BCLOUD-18311>

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](https://confluence.atlassian.com/support/implementation-of-new-features-policy-201294576.html).

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

Kind regards,   
Caroline

comments: author: Shaik Moulali
body: [@Caroline R](/t5/user/viewprofilepage/user-id/3934006) why multiple grep for master and i used this code to list the branches it is not working


author: Caroline R
body: Hi, [@Shaik Moulali](/t5/user/viewprofilepage/user-id/4685941),

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


author: Phani Cherukuri
body: Hi [@Caroline R](/t5/user/viewprofilepage/user-id/3934006) , 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??


author: Caroline R
body: Hi [@Phani Cherukuri](/t5/user/viewprofilepage/user-id/3546617),

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


author: manoj reddy gajjala
body: 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}")  

<br />

<br />


author: Aron Gombas _Midori_
body: 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.)


Tags: bitbucket-cloud

cloud