4

I deleted a bunch of merged branches on Github.com, I did a git pull, and all my branches are still showing up.

Hence, I ran..

git remote prune origin

It showed that the branches were pruned in the output.

However, all my deleted branches show up when I run

git branch

I assume I did something different then I expected? What did I do? How do I delete my branches from local that are already deleted from GitHub?

In this post: git remote prune origin does not delete the local branch even if its upstream remote branch is deleted

It mentioned the same issue but I do not understand they mean, when they say it deletes stale remote branches from local.

user2012677
  • 5,465
  • 6
  • 51
  • 113

2 Answers2

6

It's not supposed to delete them.

Your local branches—which really should just be called "your branches"—are yours. Only your remote-tracking names, origin/* in this case, are not yours.1 So if origin had a branch named xyzzy earlier, but doesn't any more, git fetch --prune origin or git remote prune origin deletes your origin/xyzzy to match origin's lack-of-xyzzy.

It doesn't touch your branches, which are yours. If you are sure that they can go now, you'll have to delete them yourself. People have written scripts to do this, but said scripts tend to be dumb: they will often delete your xyzzy even if you have commits you forgot to push before mergiing, or meant to move to another branch, and once your xyzzy is deleted, it's often too late. So be careful with such scripts.

(It might be nice to have an option to these commands that tells them: If I have a local branch xyzzy that points to the same commit as origin/xyzzy, and you're deleting origin/xyzzy, delete my local xyzzy too. Moreover, if I have xyzzy, but origin/xyzzy does not match my xyzzy, complain and stop, so that I can figure out what to do about this. But they do not have such an option.)


1Technically, these are yours, too. It's just that your Git is set up so that when your Git calls up their Git—the one at origin—and gets branch names and hash IDs from them, your Git overwrites your own origin/master with their updated master. So while origin/master is a name in your Git repository's "name-to-hash-ID" database, it's not a name you would normally control yourself. You just let your Git mirror their Git, with their master becoming your origin/master.

Or, to say it shorter: your Git's origin/master is your Git's way of remembering their Git's master. So it's sort-of theirs.

torek
  • 448,244
  • 59
  • 642
  • 775
  • So how to I delete MY local branches that have been removed from GitHub? – user2012677 Mar 01 '19 at 20:31
  • Your branches *haven't* been removed from GitHub. Only GitHub's branches have been removed from GitHub! – torek Mar 01 '19 at 20:46
  • @torek I guess he meant : *how to remove the local branches now that their github counterparts are gone?* .... and the answer is likely "manually, one by one" : `git branch -d ` – Romain Valeri Mar 01 '19 at 20:48
  • @RomainValeri: just so. As I said, it might be nice if there were a Git command that would do this, but there isn't—and it also doesn't work if, on the GitHub side, whoever actually merges your pull request uses either of "rebase and merge" or "squash and merge". So it has limited usefulness (but would still be useful). – torek Mar 01 '19 at 21:57
0

As torek said already, the first key point is to prune your remote-tracking branches to make sure you're comparing against a fresh list of references. You can use

git fetch --prune

then spot the local "leftover" branches with :

 git for-each-ref --format='%(if)%(upstream:short)%(then)%(else)%(color:bold red)%(end)%(refname:short)' refs/heads

(they'll appear in red in the output)

or alternatively (assuming your remote is named origin) :

git branch -vv | grep -v origin/

...and the last phase is to manually delete them with

git branch -d <branch>

Since you have them displayed just handy, you should not suffer more than a couple of copy/pasting. If the number of stale branches is regularly massive or, let's say, important enough, then maybe something in the workflow could be put in place to avoid the recurring situation?

Romain Valeri
  • 19,645
  • 3
  • 36
  • 61