Git 获取原点—— prune 不删除本地分支?

我一度认为 git fetch origin --prune删除了服务器上不再存在的本地分支。不知为什么,这不是我现在的经历。

我运行了这个命令,本地分支没有被删除。它是 没有目前检出。我运行 git branch -vv检查这个信息,我看到

feature/MyGreatFeature           f30efc7 [origin/feature/MyGreatFeature: gone]

所以它似乎知道它已经消失了,为什么它不删除我的本地分支呢?

运行 git version 2.7.4 (Apple Git-66)

63503 次浏览

The command you want is

$ git remote prune origin

This question is almost word for word what you're looking for.

The various prune options (git remote update --prune, git remote prune, git fetch --prune) only delete remote-tracking branches.1

You'll need to manually delete local branches you no longer want, or change or remove their upstream setting if the remote-tracking branch no longer exists. Note that each local branch can record a remote and/or branch that do not now, or even never did, exist. In this case Git mostly acts as if those local branches have no upstream set, except that since version 1.8.5, several commands report the upstream as "gone" or otherwise invalid, and may suggest using --unset-upstream.


1More precisely, they delete destination refs after doing the refspec mapping from the command line or fetch lines from the configuration. Hence, for fetch mirrors, they can delete local branches. Most clones are not set up as fetch mirrors, though.

There were some recent bug fixes for complex mappings, to make sure that Git did not prune a mapped branch in some cases when it should not. For any normal repository—ordinary clone or pure fetch mirror—these fixes have no effect; they matter only if you have complicated fetch configurations.

The following command chain can be used to delete local branches:

git branch --v | grep "\[gone\]" | awk '{print $1}' | xargs git branch -D
  • git branch --v lists the local branches verbosely
  • grep "\[gone\]" finds all the branches whose remote branch is gone
  • awk '{print $1}' outputs only the name of the matching local branches
  • xargs git branch -D deletes all the matching local branches

This should work on MacOS as well as *nix environments.

For me this line works:

git branch -vv | grep "gone" | awk '{print $1}' | xargs git branch -D

This is how I do it with Powershell.

PS> git branch --v | ? { $_ -match "\[gone\]" } | % { -split $_ | select -First 1 } | % { git branch -D $_ }

You can then create an alias like:

PS> Function func_gitprune { git branch --v | ? { $_ -match "\[gone\]" } | % { -split $_ | select -First 1 } | % { git branch -D $_ } }


PS> Set-Alias -Name gitprune -Value func_gitprune

and execute it every time you need by running

PS> gitprune

In case people need the PowerShell version:

git branch --v | Select-String -Pattern ".*\[gone\].*" | ForEach-Object{($_ -split "\s+")[1]} | ForEach-Object{git branch -D $_}

In case you need the Windows Command Line version:

git fetch --all --prune
git branch --all --verbose | for /F "tokens=1" %i in ('findstr /c:"[gone]"') do git branch -D %i