I have a team member who inadvertently pushed over 150 of his local branches to our central repo. Thankfully, they all have the same prefix. Using that prefix, is there a git command or cool little shell script I can use that will delete all of those at once?
22 Answers
Use the following command to remove all branches with PREFIX
prefix on remote server.
git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}
You may want to do a dry-run first to see if it is the branches that you want to remove:
git branch -r | awk -F/ '/\/PREFIX/{print $2}'

- 11,760
- 8
- 55
- 73
-
2I like this because it's a one liner and I can do a dry run first. Unfortunately, it errors out with this message: `$ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'GIT_URL'` – Jake A. Smith May 11 '12 at 16:49
-
With `git branch -r | awk -F/ '/\/APR/{print $2}'`, could you see all the APR prefixed branch names listed? – neevek May 11 '12 at 17:04
-
1OK, it is because the `APR-04-DPH` branch was already deleted. Take a look at these answered questions: [this](http://stackoverflow.com/questions/3184555/cleaning-up-old-remote-git-branches) and [this](http://stackoverflow.com/questions/6783917/why-cant-i-delete-a-remote-git-branch-with-git-push-origin-branchname) and also [this](http://stackoverflow.com/questions/2895906/cannot-delete-a-remote-branch-created-unintentionally). Answers to those questions address the same problem, you may want to test the solutions yourself. – neevek May 11 '12 at 17:11
-
Oh, you're right. Thanks for the research and your awesome help! – Jake A. Smith May 11 '12 at 17:14
-
39if you have / in your branch names (if you're using git-flow or something), then print {$2"/"$3} instead – ajma Mar 09 '15 at 22:01
-
I don't know why it don't works for me. I found it works with `grep`. `git branch -r | grep -Eo 'PREFIX/.*' | xargs -I {} git push origin :{}` `branch -r` shows `origin/prefix/branchname`. So it will take `prefix/branchname`. – Kirby Jun 03 '15 at 11:49
-
5I am using msysgit in Windows, and the following command worked for me (in conjunction with @ajma's comment for branch names containing forward slashes: `git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %` – rikoe Oct 09 '15 at 10:54
-
@Artem Sure, you just need to use `git tag` to list the tags, the command line `git push origin :` applies to tags too. – neevek Dec 24 '15 at 05:37
-
I can do the dry run and see the expected branches but when I try to run the full command I get C:\Program Files (x86)\Gow\bin\xargs.exe: xml: No such file or directory any idea what might be the case? I've definitely used xargs in other scenario :( – Crhistian Ramirez Feb 21 '19 at 23:48
-
`C:\Program Files (x86)\Gow\bin\xargs.exe: xml`, Can you see that `xml`, I think it is complaining about that, not `xargs`, you must check that out, it may be related to the error you got. @CrhistianRamirez – neevek Feb 22 '19 at 00:33
-
This solution works regardless of how many folders you have: `git branch -r | grep PREFIX | sed 's/ origin\///'` – arlyon Jan 22 '21 at 08:54
-
I don't understand why this is so upvoted. It doesn't work for branches with multiple `/` and even with `{$2"/"$3}` it seems to find branches like /x/PREFIX/. Maybe it's me. – tymtam Feb 16 '22 at 01:36
If you like a simpler approach, for instance delete 3 or 4 branches:
git push origin --delete <branch1> <branch2> <branch3>
Important: Only works on Git v1.7.0 and above.

- 1,522
- 1
- 9
- 11
-
6I ended up using `git branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete` – Aram Kocharyan May 10 '16 at 00:45
-
this is a better solution than the above (accepted) answer as it batches all deletions in a single request, important in cases where you are deleting many branches. – Jai Mar 05 '23 at 17:56
-
Thanks to Neevek for great and elegant solution!
But i have some troubles with slashes in branch names (i'm using Git Flow), because of awk
field separator /
(-F
option)
So my solution is based on Neevek's, but correctly parses branch names with /
. In this case i presume that your remote called origin
.
Command for deleting remote branches with names staring with PATTERN
:
git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}
And don't forget to check what you are going to delete:
git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'
USEFUL TIP: If your branch names (without origin/
prefix) stored in a text file (one branch name per line), just run:
cat your_file.txt | xargs -I {} git push origin :{}

- 5,443
- 2
- 52
- 50
-
2Use `xargs -a file -L` instead of `cat file | xargs`. Even simpler `xargs -a file git push --delete origin`. – musiKk Sep 10 '15 at 06:16
-
When running with many remote branches that match the regex, this can take a while, since a single branch is deleted every time. In order to speed it up it's possible to run in parallel using the following command (the argument to -P chooses how many will run in parallel): `git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -n 1 -P 8 -I {} git push origin :{}` – DorHugi Jan 17 '21 at 09:57
This may be a duplicate answer but below tested and worked for me perfectly.
Delete local branch forcefully
git branch -D branch-name
Delete Remote branch
git push origin --delete branch-name
Delete more than 1 local branch
git branch -D branch-name1 branch-name2
Delete more than 1 remote branch
git push origin --delete branch-name1 branch-name2
Delete local branch with prefix. For example, feature/*
git branch -D $(git branch --list 'feature/*')
List remote branch with prefix.
git branch -r | grep -Eo 'feature/.*'
Delete remote branch with prefix
git branch -r | grep -Eo 'feature/.*' | xargs -I {} git push origin :{}
Undo/revert the last commit from remote
git reset HEAD^ git push origin +HEAD

- 1,504
- 16
- 19
-
2
-
-
1@Naren: the problem is that the markdown formatting turns your backticks into a styling command. I replaced them with a different command substitution method (e.g. "$(command)" is equivalent to \`command\` but doesn't get translated by markdown into something weird.) The other thing you could do is escape the backticks with '\' – Stabledog Jul 18 '19 at 13:21
-
For 7, when working with multiple remotes after fork, to delete remote branches with prefix `feature/` from remote `fork` use `git branch -r | grep -Po '(?<=fork/)feature/.*' | xargs -I {} git push fork :{}` – Nafiur Rahman Khadem Jul 14 '22 at 08:52
-
The same with grep:
git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}
.
branch -r
shows origin/prefix/branchname
. So it will take prefix/branchname
.

- 2,847
- 2
- 32
- 42
-
-
2@jojo, AFAIK, for `-i` it uses default replacement for `{}` but with `-I` you may declare your own one. ...just found in the manual: `-i ... the same as -I{}` – Kirby Jul 15 '19 at 12:27
Neevek's solution is elegant, but it can be better: the solution as proposed calls 'git push' once per branch, which means an additional network round-trip per branch to be deleted. Since you're using awk anyway, why not use it to prefix the ':' and then xargs can call 'git push' exactly once and delete all the branches at once:
Dry-run to list the branches that would be deleted:
git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'
Final solution to actually push the deletes:
git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin

- 113
- 1
- 5
-
2It works perfectly in the situation that you can't use "-I" option for xargs when you have a lower version bash or use a windows version git bash. – zchholmes Jan 23 '15 at 16:12
-
I had a `xargs: replstr may not be empty` with Neevek's solution, maybe git version.. `git version 1.9.5` But this worked great for me. Thanks to you both – iamface Mar 23 '15 at 23:12
resource https://coderwall.com/p/eis0ba
1 - List all your remote branches:
$ git branch -r
2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:
$ git branch -r | awk -F/ '/\/feature-/{print $2}'
3 - Pipe the last command to git push to delete them:
# **Edit** - Removed extra colon, which is not needed
$ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
4 - Grab a beer.
5 - Remove any local reference to those branches:
$ git remote prune origin

- 153
- 6

- 705
- 8
- 16
-
Thanks this worked for me. In mu case I could able to delete multiple local branches. Thanks! – Prashant Kabade Nov 27 '17 at 13:11
-
This answer on coderwall actually cites this stackoverflow page as its first source, so this is basically the accepted answer of @neevek – rturquier Mar 24 '22 at 10:32
Thanks to Steve and Neevek, I found a solution that worked pretty well for me I figured worth sharing:
Steve's solution worked for me with one minor adjustment. My remotes were named origin/feature/some-feature-name
so I trimmed your awk
:
git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}
It's now doing a nice little delete flow:
To github.com:project/project-name.git
- [deleted] feature/search-min-chars
To github.com:project/project-name.git
- [deleted] feature/search-placeholder
To github.com:project/project-name.git
- [deleted] feature/server-error-message
To github.com:project/project-name.git
- [deleted] feature/six-point-asterisk
Was wondering if anyone had any ideas for a more elegant solution, though, that might output something like this (my CLI scripting is pretty poor, so it'd take me awhile to figure this out):
git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk
This would result in a nice single output with one network request:
To github.com:project/project-name.git
- [deleted] feature/search-min-chars
- [deleted] feature/search-placeholder
- [deleted] feature/server-error-message
- [deleted] feature/six-point-asterisk

- 1,563
- 14
- 23
Everyone is using awk
, not sure why. I feel like that's more complex. Here is what I use to delete all remote branches on my fork
remote:
$ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork
Throw in a grep
between the xargs
and sed
if you need to filter the list down to only a subset of remote branches.

- 24,859
- 31
- 132
- 243
-
1Thanks a lot. This one actually worked for me amongst all the solutions.. grep was returning the full branch with remote name as well like `origin/blaprefix_anotherbla`. But using `sed` handled it well. Another advantage of this approach, is that I use bitbucket and I dont need to enter authentication password for every branch deletion manually. This one does delete all the branches in a single batch. – Madhur Bhaiya Oct 17 '19 at 13:43
-
To delete all greenkeeper branches `git branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}` – abhisekp Jul 19 '20 at 05:29
I realize this is for git command, but if you looking for an alternate solution to do the similar or same result:
You can do it from here (Git Remove Remote Branches):
Then select the branches you want:
Make sure you have the permissions to remove the remote branches.

- 2,478
- 7
- 23
- 35

- 79
- 1
- 4
-
-
-
@abhisekp It's the standard feature included in Git, which could be started by running `git gui`. – trolzen Nov 03 '22 at 16:16
-
-
@abhisekp `sudo apt install git-gui`. It's in the suggestions for the `git` package BTW. – trolzen Jan 09 '23 at 14:47
Thanks to Neevek. This worked well after reconfiguring it for my purpose:
git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}
I also needed take the folder structure into account. My feature-branches are in a folder structure like origin/feature/PREFIX-FEATURENUMBER. So i had to build up my pattern from $2=folder + $3= branchname.

- 114,604
- 39
- 168
- 219

- 61
- 1
- 3
Dry run:
git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}
Delete remote branches:
git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}
Delete only fully merged remote branches:
git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}
Explanation:
sed "s/origin\///"
will remove origin/
from the branch name. Without stripping that away I got: remote ref does not exist

- 4,214
- 1
- 32
- 30
All the responses so far require the remote repo to have been fetched or cloned locally. The branches to delete might represent gigabytes of additional data to download if the remote is fetched. Why do that, just to delete them?
It's possible to avoid that. git ls-remote
can produce a list of branches on a remote by querying the remote for the list. It doesn't download the commits, so it is much faster than a fetch.
The format will look like:
c7a0e482a175b632bfd5522bc6d5bfe7785ee9a9 refs/heads/5.0.x+fslc
We need to strip the hash, but the refs/heads/
is perfectly ok to pass to git push. Better actually, since it avoids a branch vs tag ambiguity.
Here's an example:
git push origin -d `git ls-remote --refs -h origin | cut -f2 | grep "pattern"`
That will delete all branches with pattern
in the name. One could use refs/heads/pattern
if pattern must at the start. Or another regex, like heads/v[234]\.
to delete all the old 2.x, 3.x, and 4.x kernel branches.
This can also delete tags. Change -h
to -t
and all the tags will be listed like this:
1b608b9c630e0795995670aaa10895772001c222 refs/tags/v5.0.3
839630dffddbb49137028da3a09b42a9b74c07bd refs/tags/v5.0.5
Other than that, it works exactly the same as deleting the branches.
A tag will keep a commits around on the server just as much as a branch, so you need to delete tags too to get extra commits out of a repo.
One can of course use another remote than origin
. Just add it with git remote add
. It's not necessary pull or fetch from it first before deleting the branches!

- 4,240
- 24
- 35
I was not able to use awk because we are using a slash structure for our branches' name.
git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i sh -c 'git push origin --delete {}'
This get all remote branch, get only the one for a single user, remote the "origin/" string and execute a delete on each of them.

- 136,852
- 88
- 292
- 341
Github also has a nice UI and mechanism for quickly deleting branches, that's if you'd rather use a UI

- 71
- 6
-
1Yes, it's documented [here](https://help.github.com/articles/viewing-branches-in-your-repository/), but you still must click once for each individual branch. The top-voted solution here is the best way to do many branches that you can write a regex to match. – thewoolleyman Oct 28 '16 at 23:04
Previous answers helped me to remove all release branches from 2018. I ran this on my windows 10 command prompt. I have installed clink, so Linux like commands works for me.
Dry Run:
git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}
If dry run shows branches that are not in remote/origin. Run below git prune command to fix and check again.
git remote prune origin
Delete once you are happy with the result above:
git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}
If you see: error: unable to delete 'release-...2018': remote ref does not exist
. Then run the previous prune command and try again.

- 931
- 3
- 17
- 31
Watch the remote braches to look the list that we are going to delete:
git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | grep -E 'fix_*'
→ fix_
is the word to filter
Result:
fix_01032022_2
fix_01042022
fix_01042022_1
fix_01042022_2
Deleting all of them:
git push origin -d `git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | grep -E 'fix_*'`
→ Again, fix_
is the word to filter.
Result:
- [deleted] fix_01032022_2
- [deleted] fix_01042022
- [deleted] fix_01042022_1
- [deleted] fix_01042022_2
Note:
This part is for the substring of the string: | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- |
Result:
origin/name_of_the_branch
→ name_of_the_branch
I tried to delete all origin/release/r1-1* remote branches, hence following command line worked nicely.
git branch -r | awk -Forigin/ '/\/*r1-1/ {print $2}' | xargs -I {} git push origin :{}

- 670
- 9
- 15
Good solution in case of multiple remotes where we can find few PREFIX combinations.
If you have many (let's say hundreds) branches that were created automatically for example such pattern: build/XXXX
. In addition, there is upstream
remote and forked origin
so that branch -r
returns origin/build/XXXX
and upstream/build/XXXX
as well.
You can use solution with command cut -f2- -d/
More: https://unix.stackexchange.com/a/354984
Dry run where one can combine safe regex patterns like: 33[1-3][0-9]
or [0-9]{4}
:
git branch -r | grep -Eo "upstream/build/33[0-9][0-9]" | cut -f2- -d/ | xargs -I {} echo {}
The same with real delete from the upstream:
git branch -r | grep -Eo "upstream/build/33[0-9][0-9]" | cut -f2- -d/ | xargs -I {} git push upstream --delete {}

- 21
- 3
I use this to remove unwanted branches in the remote from time to time:
git branch -r --list origin/some/prefix/* | sed 's/origin\///' | xargs git push origin --delete
where brnaches starting with some/prefix are the unwanted ones.
This:
- handles branches with (multiple)
/
in their names and - updates the list of remote branches (so
git remote update origin --prune
is not needed after running this)
Example:
git branch -r --list origin/bug/* | sed 's/origin\///' | xargs git push origin --delete
Deletes all branches starting with 'bug/'

- 31,798
- 8
- 86
- 126
git branch -r | grep 'PATTERN' | cut -c 10- | xargs git push origin --delete

- 1
-
2Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Dec 29 '22 at 18:48
Delete multiple remote branches except branches like main
, develop
, you can try this one:
git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | grep -v 'main\|develop' | xargs -I {} git push origin :{}

- 1,414
- 11
- 19