I have a bunch of remote branches that were deleted and now I want to remove the branches locally. I've tried:
git fetch -p
but it does not work.
If I do:
git branch -r
and
git branch
the lists are not the same because git branch
still lists deleted remote branches, even after I run git fetch -p
. I've seen this as the accepted answer to do this in quite a few questions on here, but it isn't working for me.
I'm not sure I've worded the problem correctly so here's another explanation. Say I have:
GitHub: (remote)
Branch A
Branch B
Branch CLocal:
Branch A ==> (remote) Branch A
Branch B ==> (remote) Branch B
Branch C ==> (remote) Branch C
Now somebody deletes a branch on GitHub, giving:
GitHub: (remote)
Branch A
Branch C
What I want my local repo to look like is:
Local:
Branch A ==> (remote) Branch A
Branch C ==> (remote) Branch C
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.
git fetch would prune remote references that do not exist (if you added that to your config file), and the rest of the command deletes local branches that have been merged.
Prune/Cleanup the local references to remote branch The command git remote prune origin --dry-run lists branches that can be deleted/pruned on your local. An option --dry-run is needed. Now go ahead and actually prune/cleanup the local references by running the command git remote prune origin .
To expand on hobbs' comment, git fetch -p
(or git remote prune
or any similar command) only deletes, from your repository, each "remote branch" that is no longer present on the remote.
If you've made a local branch, that label won't go away unless you delete it manually.
For instance, suppose on remote origin
, there was a branch named sparkly
:
$ git fetch
...
* [new branch] sparkly -> origin/sparkly
You don't have a branch named sparkly
at this point (unless you already had one!); you only have origin/sparkly
(which lives in a separate name-space, refs/remotes/
rather than refs/heads/
).
If you created your own branch named sparkly
earlier, it probably does not track this new origin/sparkly
. If you create your own branch named sparkly
now, though, it will track origin/sparkly
.
In both cases, though, nothing will delete it automatically. You have to do that manually.
One reason why: there's no guarantee that just because origin/sparkly
has gone away, you are done with it ("it" being the local branch you created, which may or may not track this remote branch). If git deleted your label along with the origin/
version, any commits you had been working on might become very hard to find.
So, the short answer is: you'll have to do this manually (or semi-manually, you could automate it as much as you like). Use:
git branch -d sparkly
to delete it only if that's "safe" (in git's opinion :-) ), or:
git branch -D sparkly
to delete it even if git thinks this is "unsafe".
To "forget" locally, removed remote branches you could do
git remote prune myRemote
(Edit to take the comment into account)
Now, to delete your local branches as well you could do
remote=origin
for branch in $(git branch | sed 's/\*//'); do
if [ -z "$(git branch --all | grep $remote | grep $branch)" ]; then
git branch -D $branch
fi
done
If you plan to do this kind of manipulation often, you could put this in a script in your PATH
, call it git-delete-local-to-sync
, and then, in your repo, just type git delete-local-to-sync
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