清理旧的远程git分支

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

假设我有两个分支,master和devel。两者都在跟踪它们的远程对应物起源/主和起源/发展。

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

git push origin :heads/develgit branch -d devel

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

  • 大师
  • 来源/头部
  • 来源/主

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

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

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

git branch -a仍然在远程分支中列出起源/发展。

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

441062 次浏览

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

其次,您已经删除了origin上的heads/devel,这就是为什么您不能从机器B中删除它。

试试看

git branch -r -d origin/devel

git remote prune origin

git fetch origin --prune

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

git remote prunegit branch的文档。

这是可以为您完成的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" ]; thenecho "WARNING: You are on branch $current_branch, NOT master."fiecho -e "Fetching merged branches...\n"
git remote update --pruneremote_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" ]; thenecho "No existing branches have been merged into $current_branch."elseecho "This will remove the following branches:"if [ -n "$remote_branches" ]; thenecho "$remote_branches"fiif [ -n "$local_branches" ]; thenecho "$local_branches"firead -p "Continue? (y/n): " -n 1 choiceechoif [ "$choice" == "y" ] || [ "$choice" == "Y" ]; thenremotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u`# Remove remote branchesfor remote in $remotesdobranches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'`git push $remote $branchesdone
# Remove local branchesgit branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`elseecho "No branches removed."fifi

下面是如何使用SourceTree(v2.3.1):
1.点击Fetch
2.选中“修剪跟踪分支…”
3.按OK
4.😀

在此处输入图片描述

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

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

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

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

git push --all --prune

此命令将“空运行”删除除master之外的所有远程(origin)合并分支。您可以更改它,或者在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。此外,您可能希望首先在分叉上测试它。

考虑运行:

git fetch --prune

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

这可以进一步简化为

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

如果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 fetch时返回。

要停止获取这些远程跟踪分支,您需要显式指定要在. git/config服务配置中获取的引用:

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

在上面的示例中,我们只获取masterdevelop发布分支,请随时根据需要进行调整。

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

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

git fetch --prune

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

现在,git branch -v应该将删除远程对象的分支标记为[gone]。我们需要做的就是:

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

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

不太常见的xargs语法是这样的,它也适用于Mac和BSD以及Linux。小心,这个命令不是空运行的,所以它会强制删除所有标记为[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'
# First use prune --dry-run to filter+delete the local branchesgit remote prune origin --dry-run \| grep origin/ \| sed 's,.*origin/,,g' \| xargs git branch -D
# Second delete the remote refs without --dry-rungit remote prune origin

从本地和远程引用中删除相同的分支(在我的示例中来自origin)。