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?
18 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,340
- 8
- 53
- 71
-
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
-
34if 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,392
- 1
- 8
- 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
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,227
- 2
- 50
- 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/*')
git branch -D backticks $(git branch --list 'feature/*' backticks)
- 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 :{}
-
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
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,401
- 1
- 27
- 40
-
-
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
- 103
- 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
- 696
- 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,293
- 13
- 22
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.
- 98,925
- 29
- 148
- 200
- 61
- 1
- 3
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.
- 23,191
- 28
- 120
- 213
-
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,420
- 6
- 22
- 35
- 49
- 3
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.
- 131,236
- 84
- 290
- 340
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
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
- 3,488
- 1
- 28
- 26
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
- 16
- 31
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 :{}
- 590
- 6
- 14
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 --pruneis 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/'
- 24,269
- 5
- 71
- 101