Doug
Doug

Reputation: 7401

Can you delete multiple branches in one command with Git?

I'd like to clean up my local repository, which has a ton of old branches: for example 3.2, 3.2.1, 3.2.2, etc.

I was hoping for a sneaky way to remove a lot of them at once. Since they mostly follow a dot release convention, I thought maybe there was a shortcut to say:

git branch -D 3.2.*

and kill all 3.2.x branches.

I tried that command and it, of course, didn't work.

Upvotes: 609

Views: 293533

Answers (30)

50shadesofbae
50shadesofbae

Reputation: 4509

You can use git branch --list to list the eligible branches, and use git branch -D/-d to remove the eligible branches.

One liner example:

git branch -d `git branch --list '3.2.*'`

For Windows PowerShell

git branch -d (git branch --list '3.2.*').trim()

Upvotes: 451

Sachini Witharana
Sachini Witharana

Reputation: 116

So the easiest way would be to : git branch | grep -v "master" | xargs git branch -D

this will remove all the branches except for the master branch and current branch

Upvotes: 0

alchi baucha
alchi baucha

Reputation: 1040

You can also delete all the branches with names starting with 'JIRA-'.

git branch -D $(git branch --list 'JIRA-*')

Replace 'JIRA-' with the branch prefix.

Upvotes: 6

sidharth vijayakumar
sidharth vijayakumar

Reputation: 1581

I was able to delete many of my branches using the below shell script:

#!/bin/bash
# Get a list of remote branches matching the regex pattern
matching_branches=($(git ls-remote --heads | grep -E "/3.*" | awk -F'/' '{print $3}'))

# Loop through the matching branches and delete each one remotely
for branch in "${matching_branches[@]}"
do
  # Delete remotely
  git push --delete origin "$branch"
done

By running this I am able to delete multiple branches with some similar in the branch names. This is the output:

sidharth@Sidharths-Air test-repo % bash delete-branch.sh                                                  
From https://github.com/sidharthvijayakumar/test-repo.git
To https://github.com/sidharthvijayakumar/test-repo.git
 - [deleted]         3.0
To https://github.com/sidharthvijayakumar/test-repo.git
 - [deleted]         3.1
sidharth@Sidharths-Air test-repo % 

Upvotes: 0

Adrian
Adrian

Reputation: 570

If you want to remove all branches that are not, for example, master, foo or bar

git branch -D `git branch | grep -vE 'master|foo|bar'`

or via for-each-ref:

git for-each-ref --format='%(refname:short)' 'refs/heads' | grep -vE 'master|foo|bar' | xargs git branch -D

grep -vE 'something' is a matcher with inversion.

Upvotes: 32

mcvkr
mcvkr

Reputation: 3942

If you want to delete multiple branches for cleanup, this will work

 git branch -d branch1 branch2 branch3

also if you want to reflect the deletion action to remote, you can use this to push them to the origin

 git push origin --delete branch1 branch2 branch3

Upvotes: 24

user2205317
user2205317

Reputation: 129

Delete local branches with PowerShell

There many answers for BASH shell. Here is a variation for PowerShell.

Search the local branch and use Select-String to filter the list. Join the array into a space delimited string for a list of selected branches. Concatenate the branches to the git delete branch command. Invoke the expression.

iex "git branch -d$((git branch | Select-String MYSEARCHExpression) -join '')"

Upvotes: 1

David Roussel
David Roussel

Reputation: 5916

My specific case was not addressed, so I'm making a new answer...

Scenario:

  • Freshly cloned repo
  • No local branches created
  • Many remote branches (over 100 in my case)
  • I want to delete all the feature branches, feature/myfeature , from the remote

This is the command that I got to work:

git branch  -a | cut -c3- | grep 'origin\/feature' | sed 's/remotes\/origin\///' | xargs git push origin --delete

Thanks to @gwai for putting me on the right track.

Upvotes: 2

Saurish Kar
Saurish Kar

Reputation: 776

TL;DR

git branch -D $(git branch | grep '3\.2\..*')

Explanation

  1. git branch lists all the branches on your local system.
  2. grep '3\.2\..*' uses pattern matching to find all files in the current working directory starting with 3.2.. Using \ to escape . as it's a special character for grep.
  3. git branch | grep '3\.2\..*' will pass all the github branch names to the grep command which will then look for branch names starting with the string within the list supplied.
  4. $(git branch | grep '3\.2\..*') Anything enclosed within $() will run it as a separate shell command whose result can then be passed on to a separate command. In our case, we would want the list of files found to be deleted.
  5. git branch -D $(git branch | grep '3\.2\..*') This just does what is explained above in Point 4.

Upvotes: 10

Francis Bacon
Francis Bacon

Reputation: 4785

Here is a general solution:

git branch | grep "<pattern>" | xargs git branch -D

I would suggest running the following command line before executing the above for a preview of the branches that will be deleted.

git branch | grep "<pattern>"

In this case

git branch | grep "^3\.2\..*" | xargs git branch -D

Upvotes: 22

VonC
VonC

Reputation: 1329952

git branch -d branch1 branch2 branch3 already works, but will be faster with Git 2.31 (Q1 2021).
Before, when removing many branches and tags, the code used to do so one ref at a time.
There is another API it can use to delete multiple refs, and it makes quite a lot of performance difference when the refs are packed.

See commit 8198907 (20 Jan 2021) by Phil Hord (phord).
(Merged by Junio C Hamano -- gitster -- in commit f6ef8ba, 05 Feb 2021)

8198907795:use delete_refs when deleting tags or branches

Acked-by: Elijah Newren
Signed-off-by: Phil Hord

'git tag -d'(man) accepts one or more tag refs to delete, but each deletion is done by calling delete_ref on each argv.
This is very slow when removing from packed refs.
Use delete_refs instead so all the removals can be done inside a single transaction with a single update.

Do the same for 'git branch -d'(man).

Since delete_refs performs all the packed-refs delete operations inside a single transaction, if any of the deletes fail then all them will be skipped.
In practice, none of them should fail since we verify the hash of each one before calling delete_refs, but some network error or odd permissions problem could have different results after this change.

Also, since the file-backed deletions are not performed in the same transaction, those could succeed even when the packed-refs transaction fails.

After deleting branches, remove the branch config only if the branch ref was removed and was not subsequently added back in.

A manual test deleting 24,000 tags took about 30 minutes using delete_ref.
It takes about 5 seconds using delete_refs.

Upvotes: 5

Carl Norum
Carl Norum

Reputation: 225272

Well, in the worst case, you could use:

git branch | grep '3\.2' | xargs git branch -D

Upvotes: 221

Ankit Jindal
Ankit Jindal

Reputation: 4050

To delete multiple branches based on a specified pattern do the following:

Open the terminal, or equivalent and type in following commands:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)

Remove all 3.2.x branches, you need to type

git branch | grep "3.2" | xargs git branch -D

That's all!

You are good to go!

Upvotes: 40

code4kix
code4kix

Reputation: 4197

If you had all the branches to delete in a text file (branches-to-del.txt) (one branch per line), then you could do this to delete all such branches from the remote (origin): xargs -a branches-to-del.txt git push --delete origin

Upvotes: 1

Imtiaz Shakil Siddique
Imtiaz Shakil Siddique

Reputation: 4340

Powershell Solution:

If you're running windows, you can use PowerShell to remove multiple branches at once...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.

You can also fine tune how the pattern matching should work using Powershell's Select-String command. Take a look at powershell docs.

Upvotes: 14

Daniel
Daniel

Reputation: 850

Keep "develop" and delete all others in local

    git branch | grep -v "develop" | xargs git branch -D 

Upvotes: 17

Alan Tweedie
Alan Tweedie

Reputation: 317

I put my initials and a dash (at-) as the first three characters of the branch name for this exact reason:

git branch -D `git branch --list 'at-*'`

Upvotes: 17

mdiin
mdiin

Reputation: 415

If you are using Fish shell, you can leverage the string functions:

git branch -d (git branch -l "<your pattern>" | string trim)

This is not much different from the Powershell options in some of the other answers.

Upvotes: -1

ILYAS_Kerbal
ILYAS_Kerbal

Reputation: 1445

Use the following command to remove all branches (checked out branch will not be deleted).

git branch | cut -d '*' -f 1 | tr -d " \t\r" | xargs git branch -d

Edit: I am using a Mac Os

Upvotes: 2

peiz
peiz

Reputation: 21

If you have installed Git GUI, which is a default add-on for Windows, then it's the simplest. You can use ctrl to choose multiple branches and delete them with one click.

Upvotes: 2

RainCast
RainCast

Reputation: 4511

I just cleaned up a large set of obsolete local/remote branches today.

Below is how I did it:

1. list all branch names to a text file:

git branch -a >> BranchNames.txt

2. append the branches I want to delete to command "git branch -D -r":

git branch -D -r origin/dirA/branch01 origin/dirB/branch02 origin/dirC/branch03 (... append whatever branch names)

3. execute the cmd

And this one works so much faster and reliable than "git push origin --delete".

This may not be the most smart way as listed in other answers, but this one is pretty straight forward, and easy to use.

Upvotes: 0

velastiqui
velastiqui

Reputation: 79

it works correctly for me:

git branch | xargs git branch -d

git branch | xargs git branch -D

delete all local branches

Upvotes: 3

Aakash Pahuja
Aakash Pahuja

Reputation: 480

git branch -D <branchName>

Upvotes: -5

Yulin
Yulin

Reputation: 667

If you really need clean all of your branches, try

git branch -d $(git branch)

It will delete all your local merged branches except the one you're currently checking in.

It's a good way to make your local clean

Upvotes: 12

codevision
codevision

Reputation: 5570

For pure souls who use PowerShell here the small script git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })

Upvotes: 8

Terry Truong
Terry Truong

Reputation: 321

You can use git gui to delete multiple branches at once. From Command Prompt/Bash -> git gui -> Remote -> Delete branch ... -> select remote branches you want to remove -> Delete.

Upvotes: 13

Hieu Dang
Hieu Dang

Reputation: 403

You can use this command: git branch -D $(printf "%s\n" $(git branch) | grep '3.2')

Upvotes: 1

Artur Owczarek
Artur Owczarek

Reputation: 1167

You can remove all the branches removing all the unnecessary refs:

rm .git/refs/heads/3.2.*

Upvotes: -5

K J Gor
K J Gor

Reputation: 760

Recently, I was looking for solution of same problem, finally i found one answer and it is working very well:

  1. Open the terminal, or equivalent.
  2. Type in git branch | grep " pattern " for a preview of the branches that will be deleted.
  3. Type in git branch | grep " pattern " | xargs git branch -D

This solution is awesome and if you want full explanation of each command and how it is working, its given here.

Upvotes: 48

Mo Valipour
Mo Valipour

Reputation: 13496

I you're on windows, you can use powershell to do this:

 git branch | grep 'feature/*' |% { git branch -D $_.trim() }

replace feature/* with any pattern you like.

Upvotes: 0

Related Questions