Jake A. Smith
Jake A. Smith

Reputation: 2328

Delete multiple remote branches in git

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?

Upvotes: 156

Views: 87285

Answers (24)

wmba
wmba

Reputation: 1

This can be very handy

  1. First, get all remotes branches under features branch
readarray -t branches <<< $(git branch -r | grep -Eo 'origin/features/.*')
  1. Then delete them
for b in ${branches[@]}; do git branch -r -D $b; done;

Note: To see which branches will be deleted before running step 2, do this

echo ${branches[@]}

Upvotes: 0

Ankit Jindal
Ankit Jindal

Reputation: 4030

Delete multiple branches following a specified pattern:

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 branches with prefix prefix_name, you need to type

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

Hope this works for you!!

Upvotes: 0

Chau Giang
Chau Giang

Reputation: 1554

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 :{} 

Upvotes: 0

Naren
Naren

Reputation: 1702

This may be a duplicate answer but below tested and worked for me perfectly.

  1. Delete local branch forcefully

    git branch -D branch-name
    
  2. Delete Remote branch

    git push origin --delete branch-name
    
  3. Delete more than 1 local branch

    git branch -D branch-name1 branch-name2
    
  4. Delete more than 1 remote branch

    git push origin --delete branch-name1 branch-name2
    
  5. Delete local branch with prefix. For example, feature/*

    git branch -D $(git branch --list 'feature/*')
    
  6. List remote branch with prefix.

    git branch -r | grep -Eo 'feature/.*'
    
  7. Delete remote branch with prefix

    git branch -r | grep -Eo 'feature/.*' | xargs -I {} git push origin :{}
    
  8. Undo/revert the last commit from remote

    git reset HEAD^
    git push origin +HEAD
    

Upvotes: 60

NoName
NoName

Reputation: 1

git branch -r | grep 'PATTERN' | cut -c 10- | xargs git push origin --delete

Upvotes: 0

TrentP
TrentP

Reputation: 4682

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!

Upvotes: 2

Reta110
Reta110

Reputation: 19

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_branchname_of_the_branch

Upvotes: 1

tmaj
tmaj

Reputation: 34987

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/'

enter image description here

Upvotes: 0

dubwise
dubwise

Reputation: 21

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 {}

Upvotes: 0

Damodar Bashyal
Damodar Bashyal

Reputation: 941

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.

Upvotes: 1

Tobias Ernst
Tobias Ernst

Reputation: 4634

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

Upvotes: 4

minoseah629
minoseah629

Reputation: 119

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.

Upvotes: 9

Ashish Sajwan
Ashish Sajwan

Reputation: 704

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

Upvotes: 9

void.pointer
void.pointer

Reputation: 26345

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.

Upvotes: 6

andrewmart.in
andrewmart.in

Reputation: 1703

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

Upvotes: 7

Kirby
Kirby

Reputation: 3107

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.

Upvotes: 17

Alex
Alex

Reputation: 71

Github also has a nice UI and mechanism for quickly deleting branches, that's if you'd rather use a UI

Upvotes: 1

user3416278
user3416278

Reputation: 61

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.

Upvotes: 5

Patrick Desjardins
Patrick Desjardins

Reputation: 140793

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.

Upvotes: 1

Atish Narlawar
Atish Narlawar

Reputation: 680

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 :{}

Upvotes: 0

lack
lack

Reputation: 133

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

Upvotes: 13

jfeston
jfeston

Reputation: 1562

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.

Upvotes: 126

Dmytro
Dmytro

Reputation: 5701

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 :{}

Upvotes: 53

neevek
neevek

Reputation: 12138

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}'

Upvotes: 192

Related Questions