Git分支未显示[已删除]以表示缺失的远程分支

8
我一直在尝试找到一种方法来删除没有上游分支的本地Git分支,但是链接问题中的所有答案都对我没有用。看起来它们都依赖于git branch -vv输出带有gone]的没有远程分支的分支,但是对我来说并不会出现这种情况,我也想不出原因。

例如,在运行get fetch --prune之后,git branch -vv显示的分支rsg/revert没有[gone]标签。

  rsg/revert                       af2c4ac81e Remove temporary debug logging

然而,没有相应的origin/rsg/revert分支(我已经在Github上删除了它)。有人知道为什么这不起作用吗?
编辑:我在Mac上使用git 2.15.0。我以前从未遇到过问题。

本地的 Git 如何知道远程服务器已经消失?我会先尝试执行 git fetch --all - 9000
我尝试了 git fetch --all,但没有任何变化。在运行 git branch -vv 之前,我已经获取并修剪了所有内容,只是为了看看它是否有帮助。 - Antimony
我在这个答案中没有看到任何涉及字符串"[gone]"的地方。你尝试过他们给出的命令了吗? - Code-Apprentice
你一定需要先执行 git fetch -p(或 --prune)。如果你的 Git 版本比较老,fetch -pgit remote prune 的行为会有所不同,其中一个可能更好用,因此如果你使用的是 Git 1.7 或类似版本,请尝试使用 git remote prune - torek
我有Git 2.15.0,但我为了确保尝试运行“git remote prune origin”。没有变化。 - Antimony
显示剩余2条评论
3个回答

6
你的Git已经更新到足够新的版本,并且运行了git fetch --prune命令,所以只有一种可能: rsg/revert 的上游设置错误或没有上游设置。
若要查看上游设置(如果没有,则会出现错误),请使用以下方式:git rev-parse(注意某些 shell 可能需要引用大括号)。
git rev-parse --abbrev-ref rsg/revert@{u}

例如:

$ git rev-parse --abbrev-ref master@{u}
origin/master
$ git rev-parse --abbrev-ref dev@{u}
fatal: no upstream configured for branch 'dev'

我的 master 的上游是 origin/master,但我的 dev 没有设置上游。
只有当以下两个条件都满足时,git branch -vv 命令的输出结果中才会用方括号标识出单词 gone
  • 该分支已经设置了上游;
  • 为该分支设置的上游不再引用一个有效的名称。
如果我不小心从自己的 Git 仓库中删除了 origin/master(可以使用各种 Git 维护命令或 git branch -d -r origin/master 命令),那么就会得到如下结果:
$ git branch -d -r origin/master
Deleted remote-tracking branch origin/master (was 08da6496b6).
$ git branch -vv
  dev             9c9b961d7e The sixth batch
* master          08da6496b6 [origin/master: gone] Eighth batch

然后我运行了git fetch命令,以获取新的提交并重新创建我的origin/master,现在它是f21f8f5d35而不是08da6496b6

假设您已经让GitHub删除了rsg/revert,然后运行了一个git fetch -p 命令来删除 origin/rsg/revert,那么您的rsg/revert分支必须存在其他内容或根本没有上游。


我收到了 fatal: no upstream configured for branch 'rsg/revert' 的错误信息。你有什么办法来解决这个上游问题吗?最终目标是能够使用链接问题中的命令来删除所有过时的本地分支。 - Antimony
您可以随时使用 git branch --set-upstream-to 命令手动设置任何分支的上游分支(在末尾的 -to 部分是因为有一个 --set-upstream 选项不再应该使用,它会使参数顺序混乱)。您也可以使用 git branch --unset-upstream 命令随时删除它。您还可以使用 git push --set-upstream 命令来自动设置成功 git push 后分支的上游分支,这可以缩写为 git push -u但是... - torek
1
在这种情况下,没有意义。你已经付出了所有的努力,并发现你想删除 rsg/revert,所以你最好直接删除它。你将会进行所有这些上游设置,只是为了被迫在 GitHub 上再次删除分支(如果你使用 git push -u),然后运行你的脚本搜索 gone 并删除本地分支名称。而且,如果 origin/rsg/revert 在你的仓库中不存在,git branch --set-upstream-to 将不允许你使用它,因为它不存在,所以你将被迫先在 GitHub 上创建它等等。 - torek
在我的情况下,我只需要运行 --prune 命令,所有的事情都得到了很好的更新。 - Mike Cheel

2

如果有人需要,我使用的解决方案是结合了在SO上找到的几个其他答案。

对于那些具有上游分支的分支,当前问题中链接的问题完美解决。

至于那些缺乏此类上游分支的分支,我采用了这个答案的变体。

以下是我使用的修改后的代码片段:

#! /bin/sh
#
# rm-if-gone: remove branches that have a configured upstream
# where the configured upstream no longer exists.  Run with
# -f to make it work, otherwise it just prints what it would
# remove.
force=false
case "$1" in
-f) force=true;;
esac

for branch in $(git for-each-ref --format='%(refname:short)' refs/heads); do
    # find configured upstream, if any
    remote=$(git config --get branch.$branch.remote) || true
    # if tracking local branch, skip
    if [ "$remote" = . ]; then continue; fi
    # if the upstream commit resolves, skip
    ucommit=$(git rev-parse "${branch}@{u}" 2>/dev/null) && continue
    # upstream is invalid - remove local branch, or print removal
    $force && git branch -D $branch || echo "git branch -D $branch"
done

修改发生在第一个||,当我们获取远程时。如果没有找到远程,则链接的答案将保持原样。这正是我们感兴趣的情况,我们希望抑制这些分支。因此,我们输出true,以便该行不会以退出代码结束。
请注意,此解决方案将抑制本地未连接到远程的任何分支(包括您启动但尚未推送的分支),因此请谨慎使用,并在没有-f选项的情况下首先运行。
希望这能帮助某人。

0

如其他答案所述,如果分支没有上游设置,则单词gone不会出现。

我通过检测]而不是gone来解决了这个问题。

注意:这也会删除提交消息中包含]的分支。因此,请确保您想要保留的分支中没有它。

git branch -vv | grep -v ']'|  grep -v "\*" | awk '{ print $1; }' | xargs git branch -d

如果您想删除未合并的分支,请在命令中将-d更改为-D

git branch -vv | grep -v ']'|  grep -v "\*" | awk '{ print $1; }' | xargs git branch -D

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