协慌网

登录 贡献 社区

清理旧的远程 git 分支

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

假设我有两个分支,master 和 devel。两者都在跟踪其远程副本的原点 / 原点和原点 / 开发。

现在,在计算机 A 上时,我删除了本地和远程上的 branch devel。

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

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

  • 掌握
  • 来源 / 头
  • 起源 / 主人

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

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

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

git branch -a仍然列出远程分支中的起点 / 终点。

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

答案

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

其次,您已经删除origin上的heads/devel ,因此这就是为什么您不能从计算机 B 删除它。

尝试

git branch -r -d origin/devel

或者

git remote prune origin

或者

git fetch origin --prune

并随时在您的git --dry-run ,以查看运行它的结果,而无需实际运行它。

git remote prunegit branch文档。

考虑运行:

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

这是可以为您做的 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