git remote prune origin不会删除本地分支,即使其上游远程分支已被删除。

22
这是我常见的使用情况,我克隆一个存储库,检出一个分支,进行一些代码更改,进行多次提交,稳定后将其推送到远程,最终该分支被合并并删除,我留下了一个本地分支,上游已经消失。
我正在寻找一种安全的方法来删除所有这样的分支。从描述中看来,git remote prune origin 正好可以做到这一点。但它似乎对我不起作用。
根据以下行为,分支 encrdb_init 已从 remote 中删除,但 git remote prune origin 命令似乎没有修剪它。 我不确定为什么。
$ git branch
  bugfix/encrdb_init
  * master
$
$ git remote prune origin
$
$ git checkout bugfix/encrdb_init
  Switched to branch 'bugfix/encrdb_init'
  Your branch is based on 'origin/bugfix/encrdb_init', but the upstream 
  is gone.
  (use "git branch --unset-upstream" to fixup)
$
$ git branch
  bugfix/encrdb_init <<< shouldn't this have been pruned?
  * master

供参考,以下是git remote show origin的输出结果:

$ git remote show origin
* remote origin
  Fetch URL: <redacted>
  Push  URL: <redacted>
  HEAD branch: master
  Remote branches:
    SSL_test                                                  tracked
    addNodeFix                                                tracked
    autoprefix                                                tracked
    release/1.0.2                                             tracked
  Local branches configured for 'git pull':
    bugfix/encrdb_init          merges with remote bugfix/encrdb_init
    master                      merges with remote master
    release/1.0.2               merges with remote release/1.0.2
  Local refs configured for 'git push':
    master                 pushes to master                 (up to 
date)
    release/1.0.2          pushes to release/1.0.2          (up to 
date)

$ git branch -vv
* bugfix/encrdb_init          341a078c [origin/bugfix/encrdb_init: gone] <redacted comment>`

1
尝试使用 git remote prune origin --dry-run 命令检查过期的分支。 - Shubham Khatri
1
git remote prune origin --dry-run 的输出为空。 - saketrp
@ShubhamKhatri 返回空值是因为没有更多的远程跟踪分支可删除。而 bugfix/encrdb_init 是一个本地分支(分支名称中可以有斜杠)。 - VonC
谢谢,看起来这个命令只删除了remote中的分支,但没有删除本地分支,导致它们悬空。看起来这个命令不会删除本地分支,即使是那些上游已经不存在的分支。 - saketrp
@saketrp 是的,这就是 git remote 的全部意义:在 remotes 命名空间中更新或删除。而不是篡改本地分支。 - VonC
显示剩余3条评论
1个回答

17

git remote prune 命令只会删除在 remotes/origin 命名空间下的远程跟踪分支。

不会删除本地分支。
通常做法是只删除已合并的本地分支

即使使用 -vv 参数,git branch 也只显示本地分支。
分支名称中可以有斜杠。

远程跟踪分支位于remotes/origin命名空间下,记录了被获取的内容。
一个上游分支是与某个本地分支相关的远程分支,以便该本地分支知道推送到哪里。

git remote prune 可以正确删除远程跟踪分支,这恰好是本地bugfix/encrdb_init分支的上游分支。
这就是为什么你会看到 origin/bugfix/encrdb_init: gone:远程跟踪分支已经不存在了。


原帖作者补充道:

从描述来看,似乎git remote prune origin可以做到这一点。但是对我来说似乎不起作用。

不,描述没有提到本地分支。

删除<name>下所有已过期的远程跟踪分支。
这些已过期的分支已经从由<name>引用的远程仓库中删除,但仍然在“remotes/<name>”中可用。

这里的<name>是由git remote -v引用的远程仓库的名称。
通常是"origin"。
git remote prune将删除在remotes/origin(而不是“remote(s)”)中注册的分支。它不会删除本地分支。

要“安全”删除本地分支,您应该执行以下操作:

最后一种选项不太可靠:

  • 我更喜欢使用git branch -d而不是-D,以便仅删除已合并的分支。
  • 你可能会误删带有提交消息包含字符串“: gone”的分支。

更好的方法是列出这些分支

git branch --list --format "%(if:equals=[gone])%(upstream:track)%(then)%(refname)%(end)"

是的,分支bugfix/encrdb_init已经合并到主分支并在远程删除了,但是git不会删除它。 - saketrp
@saketrp 不,它不是。 - VonC
git branch 命令只会显示本地分支。它会展示一个本地分支,并提到它的上游分支已经不存在了。 - VonC
@saketrp 我得去上班了,稍后再聊。与此同时,我的回答依然有效。 - VonC
当然,但是本地分支与上游分支相同不就是跟踪分支吗?而且这个命令不是应该删除那些上游分支已经不存在的分支吗?如果不是,那么这个命令的确切目的是什么? - saketrp
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接