清理旧的远程git分支机构

Jay*_*esh 646 git git-branch

这是我的git工作流程.

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

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

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

git push origin :heads/devel

git branch -d devel
Run Code Online (Sandbox Code Playgroud)

现在如果我git branch -a在电脑A上做,我明白了

master
origin/HEAD
origin/master
Run Code Online (Sandbox Code Playgroud)

我现在去电脑B.做git fetch.我可以删除本地开发分支

git branch -d devel
Run Code Online (Sandbox Code Playgroud)

但我无法删除远程开发分支.

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
Run Code Online (Sandbox Code Playgroud)

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

如何清理机器B的远程入口?

Jak*_*ski 1170

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

其次,你已经删除heads/develorigin,这就是为什么你不能从机器B中删除它的原因.

尝试

git branch -r -d origin/devel
Run Code Online (Sandbox Code Playgroud)

要么

git remote prune origin
Run Code Online (Sandbox Code Playgroud)

要么

git fetch origin --prune
Run Code Online (Sandbox Code Playgroud)

并随意添加--dry-rungit语句的末尾,以查看运行它的结果,而无需实际运行它.

  • `git remote prune origin --dry-run`显示了实际上会删除的内容. (120认同)
  • `git remote prune origin`为我工作=>`*[pruned] origin/my-old-branch` (45认同)
  • `git fetch origin --prune`非常适合删除已删除的分支 (29认同)
  • 如果你有一个本地分支跟踪一个已经消失的遥控器,这将不会删除任何东西.对于那些,它看起来是`git branch -vv`后跟`git branch -D branchname`,最后修剪是最好的方法. (10认同)
  • `git branch -r -d origin/devel`为我工作.谢谢.既然我读了`git remote prune`的manpage,我想这也应该有效.下次会试试. (5认同)
  • 您可以通过设置以下选项将剪枝配置为自动执行拉取/取出:`git config remote.origin.prune true` (5认同)

Ari*_*rif 87

考虑运行:

git fetch --prune
Run Code Online (Sandbox Code Playgroud)

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

这可以进一步简化

git config remote.origin.prune true
Run Code Online (Sandbox Code Playgroud)

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

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

[fetch]
    prune = true
Run Code Online (Sandbox Code Playgroud)

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

git config --global fetch.prune true
Run Code Online (Sandbox Code Playgroud)

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

git config --system fetch.prune true
Run Code Online (Sandbox Code Playgroud)


Ale*_*yan 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
Run Code Online (Sandbox Code Playgroud)


wes*_*ton 11

这个命令将"干运行"删除所有remote(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
Run Code Online (Sandbox Code Playgroud)

如果它看起来不错,请删除--dry-run.另外,您可能希望首先在fork上测试它.


Ecu*_*dor 7

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

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

git fetch --prune
Run Code Online (Sandbox Code Playgroud)

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

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

git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}
Run Code Online (Sandbox Code Playgroud)

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

不太常见的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'
Run Code Online (Sandbox Code Playgroud)


Tim*_*art 6

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

git push --all --prune --dry-run
Run Code Online (Sandbox Code Playgroud)

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

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

git push --all --prune
Run Code Online (Sandbox Code Playgroud)

  • 这个命令似乎很危险......它设法删除了我想要的东西(并且不能用上面的至少四个答案来做)。但它也删除了其他四个开发分支。Git 真的很烂... (12认同)
  • 当然,您会希望很快恢复这些,因为 git 的垃圾收集器最终会删除分支未引用的提交。 (4认同)
  • 这些分支机构一定不是在您的本地。然而,一切都没有丢失。Git 提交,Git reflog,然后是 git reset --hard &lt;checksum&gt;。你可以用这个来进行任何提交(又名保存)和其他人。分支只是一个标签,删除标签不会删除保存...它将永远有一个校验和。让我知道我是否可以提供帮助 (3认同)

rye*_*nus 6

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

git branch -r | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd
Run Code Online (Sandbox Code Playgroud)

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

git branch -r --merged | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd
Run Code Online (Sandbox Code Playgroud)

这对于大型项目可能很有用,因为在这些项目中您不需要其他队友的功能分支,但是在初始克隆上有很多远程跟踪分支。

但是,仅此步骤是不够的,因为那些删除的远程跟踪分支将再次出现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/*
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我们只取masterdevelop释放分支机构,随时适应,因为你需要。