Git命令来移除上游已删除的本地分支?

gcxthw6b  于 2023-01-24  发布在  Git
关注(0)|答案(4)|浏览(162)

有很多类似的问题(eidogg. this onethis one),但公认的答案似乎没有回答我的确切问题。
Branch 1未合并到主服务器。计算机A和计算机B都指向同一个远程服务器。Branch 1存在于该远程服务器上。
在机器A上,我在本地删除Branch 1,然后将删除推送到远程,这样Branch 1和remotes/origin/Branch 1就从机器A中删除,Branch 1也从远程中删除。
在机器B上运行

  • git checkout Branch1然后
  • git checkout Branch2然后
  • git fetch --prune

git fetch --prune从计算机B上的本地存储库中删除remotes/origin/Branch 1。如果我随后通过运行git checkout Branch1返回Branch 1,则会收到错误消息
已切换到分支“Branch 1”
您的分支基于“origin/Branch 1”,但上游没有了。
(use“git分支--未设置-上游”到修复)
有没有git命令可以移除上游已删除的本地分支?

krcsximq

krcsximq1#

没有内置的方法可以做到这一点,但是使用以下代码 * 是 * 可能的:

git fetch -p && \
git for-each-ref --format '%(refname:short) %(upstream:track)' | \
  awk '$2 == \"[gone]\" {print $1}' | \
  xargs -r git branch -D

此命令由以下几部分组成:

  1. git fetch -p:确保远程分支是最新的
  2. git for-each-ref --format '%(refname:short) %(upstream:track)':这将以我们选择的格式返回git分支,其中我们既有本地分支名称,也有上游分支名称(对于删除了远程分支的分支,将为“[gone]”)
  3. awk '$2 == \"[gone]\" {print $1}':过滤远程状态为“[gone]”的分支,返回本地分支名称
  4. xargs -r git branch -D删除本地分支
    您甚至可以通过运行以下命令将上面的命令添加为git别名:
git config --global alias.gone "! git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '\$2 == \"[gone]\" {print \$1}' | xargs -r git branch -D"

一旦这个命令完成,你可以执行git gone,它将删除本地分支,远程分支已经被删除。
您可以在this blog post中阅读完整说明

4ioopgfo

4ioopgfo2#

Whymarrh的评论是正确的:没有内置的命令来执行此操作。
也有一个很好的理由不存在这样的内置机制,仅仅因为上游的远程跟踪分支已经被删除并不意味着你一定要放弃你自己的工作,在你的例子中,也许在git fetch --prune删除origin/Branch1之前,提交图看起来像这样:

...--o--o--o     <-- origin/Branch1
            \
             o   <-- Branch1

你在Branch1上做了一个很好的提交,并准备进行git push,但上周被中断了。现在origin/Branch1已经没有了,也许你想把那个好的提交复制到其他地方。但是现在origin/Branch1已经没有了,没有理由在图中保留这个扭结,Git能看到的就是:

...--o--o--o--o   <-- Branch1

它知道您的Branch1有一个配置的上游,但不知道配置的上游指向哪个提交,回到它存在的时候。
尽管如此,如果您非常确定要删除这样的分支,您可以通过一个简短的脚本来完成:

#! /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) || continue
    # 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

(the以上未经测试;它也不会删除 current 分支,因为你不能删除,所以你需要确定你在一个你不打算删除的分支上)。

uemypmqf

uemypmqf3#

git remote prune origin --dry-run
删除--dry-run以实际执行修剪。从docs
删除name下的所有过时的远程跟踪分支。这些过时的分支已从name引用的远程存储库中删除,但在“remotes/name“中仍然本地可用。

iaqfqrcu

iaqfqrcu4#

这个命令已经为我删除了在上游被删除的'foo'分支。

git branch -d foo

你必须在当地的主要分支,否则你会得到这个:error: Cannot delete branch 'foo' checked out at...

相关问题