827

我在两台不同的计算机(A 和 B)上工作,并将一个通用的 git 远程存储在 Dropbox 目录中。

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

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

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

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

  • 掌握
  • 原点/HEAD
  • 原产地/主人

在计算机 B 上运行git fetch,我可以使用 删除本地 devel 分支git branch -d devel,但无法删除远程 devel 分支。

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

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

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

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

4

9 回答 9

1443

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

其次,你已经在 上删除heads/develorigin,所以你不能从机器 B 上删除它。

尝试

git branch -r -d origin/devel

或者

git remote prune origin

或者

git fetch origin --prune

并随意添加--dry-run到语句的末尾git以查看运行它的结果而不实际运行它。

git remote prune和的文档git branch

于 2010-07-06T08:45:46.127 回答
143

考虑运行:

git fetch --prune

定期在每个 repo 中删除一直在跟踪已删除的远程分支的本地分支(远程 GIT repo 中不再存在)。

这可以进一步简化为

git config remote.origin.prune true

这是一个per-repo将使任何未来git fetch or git pull自动修剪的设置。

要为您的用户进行设置,您还可以编辑全局 .gitconfig 并添加

[fetch]
    prune = true

但是,建议使用以下命令完成此操作:

git config --global fetch.prune true

或在系统范围内应用它(不仅仅是为用户)

git config --system fetch.prune true
于 2017-05-23T08:35:36.003 回答
15

我必须在这里添加一个答案,因为其他答案要么没有涵盖我的情况,要么是不必要的复杂。我与其他开发人员一起使用 github,我只想从我的机器上一次性删除所有远程从 github PR 中(可能合并和)删除的本地分支。不,诸如git branch -r --merged不涵盖未在本地合并的分支或根本未合并(已放弃)的分支等,因此需要不同的解决方案。

无论如何,我从其他答案中得到的第一步:

git fetch --prune

在我的情况下,干运行git remote prune origin似乎会做同样的事情,所以我选择了最短的版本以保持简单。

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

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

就这么简单,它删除了我想要的上述场景的所有内容。

不太常见的xargs语法是,除了 Linux,它还可以在 Mac 和 BSD 上运行。小心,此命令不是空运行,因此它将强制删除所有标记为[gone]. 显然,这是 git nothing 永远消失了,如果你看到删除了你记得想要保留的分支,你可以随时取消删除它们(上面的命令将在删除时列出它们的哈希,所以一个简单的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'
于 2019-02-07T16:53:45.103 回答
14

这是可以为您执行此操作的 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
于 2012-03-16T14:24:46.173 回答
14

此命令将“试运行”删除所有远程 ( origin) 合并的分支,除了master. 您可以更改它,或者在 master 之后添加其他分支:grep -v for-example-your-branch-here |

git branch -r --merged | 
  grep origin | 
  grep -v '>' | 
  grep -v master | 
  xargs -L1 | 
  awk '{sub(/origin\//,"");print}'| 
  xargs git push origin --delete --dry-run

如果看起来不错,请删除--dry-run. 此外,您可能想先在 fork 上进行测试。

于 2016-10-24T19:51:05.903 回答
10

如果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

这对于大型项目可能很有用,在这些项目中您不需要其他队友的功能分支,但在初始克隆时会获取大量远程跟踪分支。

但是,仅此步骤是不够的,因为那些已删除的远程跟踪分支会在 next 上重新出现git fetch

要停止获取那些远程跟踪分支,您需要在.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/*

在上面的示例中,我们仅获取masterdevelop发布分支,您可以根据需要随意调整。

于 2017-11-07T17:16:42.447 回答
7

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

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

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

然后运行以下命令以从远程仓库中删除不在本地仓库中的所有分支:

git push --all --prune
于 2016-09-02T22:42:58.093 回答
3

以下是使用 SourceTree (v2.3.1) 的方法:
1. 单击 Fetch
2. 选中“Prune tracking branches ...”
3. 按 OK
4.

在此处输入图像描述

于 2016-06-06T10:04:02.493 回答
1
# First use prune --dry-run to filter+delete the local branches
git remote prune origin --dry-run \
  | grep origin/ \
  | sed 's,.*origin/,,g' \
  | xargs git branch -D

# Second delete the remote refs without --dry-run
git remote prune origin

从本地和远程引用中修剪相同的分支(在我的示例中origin)。

于 2019-11-27T14:52:28.467 回答