我在两台不同的电脑(A和B)上工作,并在dropbox目录中存储了一个通用的git遥控器。

假设我有两个分支,master和devel。两者都在跟踪远程对应的origin/master和origin/devel。

现在在计算机A上,我删除分支devel,在本地和远程。

git push origin :heads/devel
git branch -d devel

在计算机A上运行git branch -a,我得到了下面的分支列表。

主 来源/头 来源/主

在计算机B上运行git取回,我可以用git branch -d devel删除本地devel分支,但我不能删除远程devel分支。

Git push origin:heads/devel返回以下错误消息。

错误:无法推送到不合格的目的地:heads/proxy3d 目标refspec既不匹配远程上现有的ref,也不以refs/开头,并且我们无法根据源ref猜测前缀。 致命的:对端意外挂机

Git branch -a仍然在远程分支中列出origin/devel。

如何清除计算机B上的远程分支?


当前回答

首先,git分支-a在机器B上的结果是什么?

其次,你已经在原点上删除了heads/devel,所以这就是为什么你不能从机器B上删除它。

Try

git branch -r -d origin/devel

or

git remote prune origin

or

git fetch origin --prune

并且可以在git语句的末尾添加——dry-run,以查看在不实际运行它的情况下运行它的结果。

文件的git远程修剪和git分支。

其他回答

删除一直是一个具有挑战性的任务,可能是危险的!!因此,首先执行以下命令,看看会发生什么:

git push --all --prune --dry-run

通过像上面那样做,git将为您提供一个列表,说明如果执行下面的命令将会发生什么。

然后执行以下命令,删除远程repo中不在本地repo中的所有分支:

git push --all --prune

我必须在这里加上一个答案,因为其他答案要么没有涵盖我的情况,要么是不必要的复杂。 我使用github与其他开发人员,我只是想要所有的本地分支机构,其远程(可能合并和)从一个github的PR删除从我的机器去删除。不,像git branch -r——merged这样的东西不包括没有在本地合并的分支,或者根本没有合并的分支(废弃的)等等,所以需要一个不同的解决方案。

不管怎样,我从其他答案中得到的第一步:

git fetch --prune

git remote prune origin的一个演练似乎在我的情况下会做同样的事情,所以我使用了最短的版本以保持简单。

现在,git分支-v应该将远程被删除的分支标记为[gone]。 因此,我所需要做的就是:

git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}

就像这样简单,它删除了上面场景中我想要的所有内容。

不太常见的xargs语法是,除了Linux,它还适用于Mac和BSD。 注意,这个命令不是一个演练,所以它将强制删除所有标记为[gone]的分支。显然,这是git什么都没有永远消失,如果你看到你想要保留的分支被删除,你可以随时取消删除它们(上面的命令将列出它们的哈希删除,所以一个简单的git checkout -b <branch> <hash>。

编辑:只需将这个别名添加到你的.bashrc/。bash_profile,这两个命令做成一个,我更新了第二个工作在所有的shell:

alias old_branch_delete='git fetch -p && git branch -vv | awk "/: gone]/{print \$1}" | xargs git branch -D'

这里有一个bash脚本可以为您做这件事。它是http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git脚本的修改版本。我的修改使它能够支持不同的远程位置。

#!/bin/bash

current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
  echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching merged branches...\n"

git remote update --prune
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
  echo "No existing branches have been merged into $current_branch."
else
  echo "This will remove the following branches:"
  if [ -n "$remote_branches" ]; then
echo "$remote_branches"
  fi
  if [ -n "$local_branches" ]; then
echo "$local_branches"
  fi
  read -p "Continue? (y/n): " -n 1 choice
  echo
  if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
    remotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u`
# Remove remote branches
for remote in $remotes
do
        branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'`
        git push $remote $branches 
done

# Remove local branches
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
  else
echo "No branches removed."
  fi
fi

如果git branch -r显示了很多你不感兴趣的远程跟踪分支,你只想从本地删除它们,使用以下命令:

git branch -r | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

一个更安全的版本是只删除合并的:

git branch -r --merged | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

这对于大型项目可能很有用,因为你不需要其他团队成员的功能分支,但在初始克隆中有许多远程跟踪分支。

但是,仅这一步是不够的,因为那些被删除的远程跟踪分支将在下次获取git时返回。

为了停止获取这些远程跟踪分支,你需要显式地在.git/config中指定要获取的引用:

[remote "origin"]
  # fetch = +refs/heads/*:refs/remotes/origin/*    ### don't fetch everything
  fetch = +refs/heads/master:refs/remotes/origin/master
  fetch = +refs/heads/develop:refs/remotes/origin/develop
  fetch = +refs/heads/release/*:refs/remotes/origin/release/*

在上面的例子中,我们只获取主分支,开发和释放分支,可以根据需要随意调整。

首先,git分支-a在机器B上的结果是什么?

其次,你已经在原点上删除了heads/devel,所以这就是为什么你不能从机器B上删除它。

Try

git branch -r -d origin/devel

or

git remote prune origin

or

git fetch origin --prune

并且可以在git语句的末尾添加——dry-run,以查看在不实际运行它的情况下运行它的结果。

文件的git远程修剪和git分支。