删除分支不在远程

时间:2013-05-16 14:27:26

标签: git git-branch

==> git branch -a
* master
  test
  remotes/origin/master
  remotes/origin/test

当有人删除remotes/origin/test时,我仍然可以在我的计算机上看到它。

我知道我可以执行此操作并删除test

==> git remote prune
==> git branch -d test
==> git branch -a
* master
  remotes/origin/master

但如果我有更多的本地分支,并且他们不在远程,那么我怎样才能快速删除它们?

8 个答案:

答案 0 :(得分:31)

这是我删除不再相关的本地分支的方法:

git branch --merged origin/master | xargs git branch -d

您可能需要根据您的特定配置进行调整,但管道之前的第一个命令应该为您提供已合并到主分支中的所有本地分支的列表。

答案 1 :(得分:18)

根据git-fetch手册页,git fetch -p将“取出后,删除遥控器上不再存在的任何远程跟踪分支。如果您有本地分支机构跟踪这些远程分支机构,可能需要手动修剪它们。

答案 2 :(得分:9)

简单的剪枝不会删除本地分支。

这是实现真正删除的另一种方法。一定要执行" git fetch -p"首先获取远程存储库的最新状态。

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

这将检查所有本地分支及其来源,并将删除其原始分支被删除的所有本地分支。

详细说明:

git branch -vv

将列出您的本地分支并显示有关远程分支的信息,如果它不再存在则说“已消失”。

grep ': gone]'

将获取与“gone”短语匹配的分支。

grep -v "\*"

将仅提取不包含星号的行。这将忽略您当前所在的分支,并且还会阻止“git branch -d”在末尾以“*”执行,这将导致删除所有本地分支

awk '{print $1}'

将获取输出,直到第一个空格,这将导致本地分支名称。

xargs git branch -d

将使用输出(分支名称)并将其附加到“git branch -d”命令以最终删除分支。如果您还想删除未完全合并的分支,可以使用大写“D”代替“d”强制删除。

答案 3 :(得分:3)

我为此编写了一个名为git-dangling-branches的简单shell脚本。如果您指定-D选项,则会删除所有不具有refs/remotes/origin/<branch_name>的本地分支机构。当然,你这样做时应该小心。

#!/bin/bash -e
if [[ "$1" == '-D' ]]; then
  DELETE=1
else
  DELETE=0
fi

REMOTE_BRANCHES="`mktemp`"
LOCAL_BRANCHES="`mktemp`"
DANGLING_BRANCHES="`mktemp`"
git for-each-ref --format="%(refname)" refs/remotes/origin/ | \
  sed 's#^refs/remotes/origin/##' > "$REMOTE_BRANCHES"
git for-each-ref --format="%(refname)" refs/heads/ | \
  sed 's#^refs/heads/##' > "$LOCAL_BRANCHES"
grep -vxF -f "$REMOTE_BRANCHES" "$LOCAL_BRANCHES" | \
  sort -V > "$DANGLING_BRANCHES"
rm -f "$REMOTE_BRANCHES" "$LOCAL_BRANCHES"

if [[ $DELETE -ne 0 ]]; then
  cat "$DANGLING_BRANCHES" | while read -r B; do
    git branch -D "$B"
  done
else
  cat "$DANGLING_BRANCHES"
fi
rm -f "$DANGLING_BRANCHES"

答案 4 :(得分:1)

你可以通过遍历refs来执行此操作,我使用以下命令删除没有远程分支的所有本地分支并且它工作。 警告:此操作强制删除非完全合并的分支,请小心使用。

git branch -D `git for-each-ref --format="%(fieldName)" refs/heads/<branch-name-pattern>`

%(fieldName) = refname:short)

如果分支名称中有公共前缀/后缀,则

refs/heads/ =可以加后缀 例如:refs/heads/*abc*

有关详细信息git-for-each-ref(1) Manual Page

,请参阅此处

答案 5 :(得分:1)

我最终得到了与kcm方法非常相似的东西。我想要一些能够清除跟踪远程分支的所有本地分支的东西,origin,远程分支已被删除(gone)。我不想删除从未设置为跟踪远程分支的本地分支(即:我的本地开发分支)。此外,我想要一个简单的单线程,只使用git或其他简单的CLI工具,而不是编写自定义脚本。我最后使用了一些grepawk来制作这个简单的命令,然后将其作为别名添加到我的~/.gitconfig中。

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D

这是一个git config --global ...命令,可以轻松将其添加为git prune-branches

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

注意:正如Matteo在他之前对另一个答案的评论中指出的那样,使用-D标志git branch可能非常危险。因此,在config命令中,我使用-d选项git branch而不是-D;我在实际配置中使用-D。我使用-D因为我不想听到Git抱怨未合并的分支,我只是希望它们消失。您可能也想要这个功能。如果是这样,只需在该config命令的末尾使用-D而不是-d

答案 6 :(得分:0)

首先,要做:

git fetch && git remote prune origin

然后:

git branch -a | grep -v ${$(git branch -a | grep remotes | cut -d/" -f3-)/#/-e} | xargs git branch -D

  • 列出所有没有远程/来源前缀的远程:git branch -a | grep remotes | cut -d'/' -f3-
  • 从git中删除所有列出的对象:git branch -a | grep v ${<all remotes without prefix>/#/-e}
  • 从本地需求-D中删除,因为不必全部都标记为已合并。例如,Github中的squash和merge不会将它们标记为已合并。

答案 7 :(得分:0)

快速

git fetch -p
git branch -v | grep "\[gone\]"

然后手动检查并删除输出中的分支。


详细

基于此线程和 here 中的答案的最简单的手动解决方案是删除远程上不再存在的所有远程跟踪引用

git fetch -p

然后查看已从远程跟踪中删除但仍在本地工作树中的内容

git branch -v

并手动删除输出中包含 [gone] 的分支。

要运行一个简洁的列表

git branch -v | grep "\[gone\]"