清理旧的远程git分支机构

时间:2010-07-06 08:14:51

标签: git git-branch

这是我的git工作流程。

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

假设我有两个分支主人和开发人员。两者都在追踪他们的远程对手origin / master和origin / devel。

现在,在计算机A上,我删除了分支开发 - 本地和远程 - 如下:

git push origin :heads/devel

git branch -d devel

现在,如果我在计算机A上git branch -a,我就会

master
origin/HEAD
origin/master

我现在去电脑B.做git fetch。我可以通过

删除本地开发分支
git branch -d devel

但是我无法移除远程开发分支。

git push origin :heads/devel

error: unable to push to unqualified destination: heads/proxy3d
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
fatal: The remote end hung up unexpectedly

执行git branch -a仍会列出远程分支中的origin / devel。

如何清除机器B上的开发远程条目?

9 个答案:

答案 0 :(得分:1107)

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

其次,您已在heads/devel上删除origin,这就是您无法从机器B中删除它的原因。

尝试

git branch -r -d origin/devel

git remote prune origin

git fetch origin --prune

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

答案 1 :(得分:75)

考虑运行:

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

答案 2 :(得分: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

答案 3 :(得分:8)

此命令将"干运行"删除除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上测试它。

答案 4 :(得分:3)

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

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

通过这样做,git将为您提供如果执行以下命令将会发生什么的列表。

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

git push --all --prune

答案 5 :(得分:3)

如果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/*
  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并发布分支,随意添加你的。

答案 6 :(得分:2)

以下是如何使用SourceTree(v2.3.1)执行此操作:
 1.单击“获取”  2.选中“修剪跟踪分支......”  3.按OK
 4.

enter image description here

答案 7 :(得分:1)

我将不得不在此处添加一个答案,因为其他答案或者不能解决我的问题,或者不必要地复杂。 我将github与其他开发人员一起使用,我只希望将所有远程已从github PR(可能已合并并)从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语法是这样的,因此除了Linux外,它还可以在Mac和BSD上使用。 小心,此命令不是空运行,因此它将强制删除所有标记为[gone]的分支。显然,这是git,什么也不会永远消失,如果您看到删除的分支后还记得要保留它们,则可以始终取消删除它们(上面的命令将在删除时列出它们的哈希,所以很简单git checkout -b <branch> <hash>

答案 8 :(得分:0)

# 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)。