They're unnecessary. In most cases, branches, especially branches that were related to a pull request that has since been accepted, serve no purpose. They're clutter. They don't add any significant technical overhead, but they make it more difficult for humans to work with lists of branches in the repository.
git fetch --prune is the best utility for cleaning outdated branches. It will connect to a shared remote repository remote and fetch all remote branch refs. It will then delete remote refs that are no longer in use on the remote repository.
Steps to delete remote Git branchesIssue the git push origin –delete branch-name command, or use the vendor's online UI to perform a branch deletion. After the remote branch is deleted, then delete the remote tracking branch with the git fetch origin –prune command.
Deleting a branch LOCALLY Delete a branch with git branch -d <branch> . The -d option will delete the branch only if it has already been pushed and merged with the remote branch. Use -D instead if you want to force the branch to be deleted, even if it hasn't been pushed or merged yet. The branch is now deleted locally.
First, what is the result of git branch -a
on machine B?
Second, you have already deleted heads/devel
on origin
, so that's why you can't delete it from machine B.
Try
git branch -r -d origin/devel
or
git remote prune origin
or
git fetch origin --prune
and feel free to add --dry-run
to the end of your git
statement to see the result of running it without actually running it.
Docs for git remote prune
and git branch
.
Consider to run :
git fetch --prune
On a regular basis in each repo to remove local branches that have been tracking a remote branch that is deleted (no longer exists in remote GIT repo).
This can be further simplified by
git config remote.origin.prune true
this is a per-repo
setting that will make any future git fetch or git pull
to automatically prune.
To set this up for your user, you may also edit the global .gitconfig and add
[fetch]
prune = true
However, it's recommended that this is done using the following command:
git config --global fetch.prune true
or to apply it system wide (not just for the user)
git config --system fetch.prune true
Here is bash script that can do it for you. It's modified version of http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git script. My modification enables it to support different remote locations.
#!/bin/bash
current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching merged branches...\n"
git remote update --prune
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
echo "No existing branches have been merged into $current_branch."
else
echo "This will remove the following branches:"
if [ -n "$remote_branches" ]; then
echo "$remote_branches"
fi
if [ -n "$local_branches" ]; then
echo "$local_branches"
fi
read -p "Continue? (y/n): " -n 1 choice
echo
if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
remotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u`
# Remove remote branches
for remote in $remotes
do
branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'`
git push $remote $branches
done
# Remove local branches
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
else
echo "No branches removed."
fi
fi
This command will "dry run" delete all remote (origin
) merged branches, apart from master
. You can change that, or, add additional branches after master: grep -v for-example-your-branch-here |
git branch -r --merged |
grep origin |
grep -v '>' |
grep -v master |
xargs -L1 |
awk '{sub(/origin\//,"");print}'|
xargs git push origin --delete --dry-run
If it looks good, remove the --dry-run
. Additionally, you may like to test this on a fork first.
I'll have to add an answer here, because the other answers are either not covering my case or are needlessly complicated.
I use github with other developers and I just want all the local branches whose remotes were (possibly merged and) deleted from a github PR to be deleted in one go from my machine. No, things like git branch -r --merged
don't cover the branches that were not merged locally, or the ones that were not merged at all (abandoned) etc, so a different solution is needed.
Anyway, the first step I got it from other answers:
git fetch --prune
A dry run of git remote prune origin
seemed like it would do the same thing in my case, so I went with the shortest version to keep it simple.
Now, a git branch -v
should mark the branches whose remotes are deleted as [gone]
.
Therefore, all I need to do is:
git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}
As simple as that, it deletes everything I want for the above scenario.
The less common xargs
syntax is so that it also works on Mac & BSD in addition to Linux.
Careful, this command is not a dry run so it will force-delete all the branches marked as [gone]
. Obviously, this being git nothing is gone forever, if you see branches deleted that you remember you wanted kept you can always undelete them (the above command will have listed their hash on deletion, so a simple git checkout -b <branch> <hash>
.
Edit: Just add this alias to your .bashrc/.bash_profile, the two commands made into one and I updated the second to work on all shells:
alias old_branch_delete='git fetch -p && git branch -vv | awk "/: gone]/{print \$1}" | xargs git branch -D'
If git branch -r
shows a lot of remote-tracking branches that you're not interested in and you want to remove them only from local, use the following command:
git branch -r | grep -Ev 'HEAD|master|develop' | xargs -r git branch -rd
A safer version would be to only remove the merged ones:
git branch -r --merged | grep -Ev 'HEAD|master|develop' | xargs -r git branch -rd
This might be useful for large projects, where you don't need the feature branches of other teammates but there're lots of remote-tracking branches fetched upon the initial clone.
However, this step alone is not sufficient, because those deleted remote-tracking branches would come back upon next git fetch
.
To stop fetching those remote-tracking branches you need to explicitly specify the refs to fetch in .git/config:
[remote "origin"]
# fetch = +refs/heads/*:refs/remotes/origin/* ### don't fetch everything
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/develop:refs/remotes/origin/develop
fetch = +refs/heads/release/*:refs/remotes/origin/release/*
In the above example we only fetch master
, develop
and release branches, feel free to adapt as you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With