清理旧的远程 git 分支

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3184555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:40:54  来源:igfitidea点击:

Cleaning up old remote git branches

gitgit-branch

提问by Jayesh

I work from two different computers (A and B) and store a common git remote in the dropbox directory.

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

Let's say I have two branches, master and devel. Both are tracking their remote counterparts origin/master and origin/devel.

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

Now while on computer A, I delete branch devel, on local and remote.

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

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

Running git branch -aon computer A, I get the following list of branches.

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

  • master
  • origin/HEAD
  • origin/master
  • 掌握
  • 起源/头部
  • 起源/主人

Running git fetchon computer B, I can remove the local devel branch with git branch -d devel, but I can't remove the remote devel branch.

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

git push origin :heads/develreturns the following error messages.

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

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

git branch -astill lists origin/devel in the remote branches.

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

How can I clean up the remote branches from computer B?

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

回答by Jakub Nar?bski

First, what is the result of git branch -aon machine B?

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

Second, you have already deleted heads/develon origin, so that's why you can't delete it from machine B.

其次,您已经删除heads/develorigin,所以这就是您无法从机器 B 中删除它的原因。

Try

尝试

git branch -r -d origin/devel

or

或者

git remote prune origin

or

或者

git fetch origin --prune

and feel free to add --dry-runto the end of your gitstatement to see the result of running it without actually running it.

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

Docs for git remote pruneand git branch.

git remote prune和 的文档git branch

回答by Arif

Consider to run :

考虑运行:

git fetch --prune

On a regular basis in each repo to remove local branches that have been tracking a remote branch that is deleted (no longer exists in remote GIT repo).

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

This can be further simplified by

这可以进一步简化为

git config remote.origin.prune true

this is a per-reposetting that will make any future git fetch or git pullto automatically prune.

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

To set this up for your user, you may also edit the global .gitconfig and add

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

[fetch]
    prune = true

However, it's recommended that this is done using the following command:

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

git config --global fetch.prune true

or to apply it system wide (not just for the user)

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

git config --system fetch.prune true

回答by Alex Amiryan

Here is bash script that can do it for you. It's modified version of http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-gitscript. My modification enables it to support different remote locations.

这是可以为您完成的 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/* \(.*\)//')
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/\(.*\)\/\(.*\)//g' | sort -u`
# Remove remote branches
for remote in $remotes
do
        branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/: /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

回答by weston

This command will "dry run" delete all remote (origin) merged branches, apart from master. You can change that, or, add additional branches after master: grep -v for-example-your-branch-here |

此命令将“试运行”删除所有远程 ( 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

If it looks good, remove the --dry-run. Additionally, you may like to test this on a fork first.

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

回答by ryenus

If git branch -rshows a lot of remote-tracking branches that you're not interested in and you want to remove them only from local, use the following command:

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

git branch -r | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

A safer version would be to only remove the merged ones:

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

git branch -r --merged | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

This might be useful for large projects, where you don't need the feature branches of other teammates but there're lots of remote-tracking branches fetched upon the initial clone.

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

However, this step alone is not sufficient, because those deleted remote-tracking branches would come back upon next git fetch.

然而,仅仅这一步是不够的,因为那些被删除的远程跟踪分支会在 next 返回git fetch

To stop fetching those remote-tracking branches you need to explicitly specify the refs to fetch in .git/config:

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

In the above example we only fetch master, developand releasebranches, feel free to adapt as you need.

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

回答by Timothy L.J. Stewart

Deletion is always a challenging task and can be dangerous!!! Therefore, first execute the following command to see what will happen:

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

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

By doing so like the above, gitwill provide you with a list of what would happen if the below command is executed.

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

Then run the following command to remove all branches from the remote repo that are not in your local repo:

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

git push --all --prune

回答by coco

Here is how to do it with SourceTree (v2.3.1):
1. Click Fetch
2. Check "Prune tracking branches ..."
3. Press OK
4.

以下是如何使用 SourceTree (v2.3.1) 执行此操作:
1. 单击 Fetch
2. 选中“Prune tracking branch ...”
3. 按 OK
4.

enter image description here

在此处输入图片说明

回答by Ecuador

I'll have to add an answer here, because the other answers are either not covering my case or are needlessly complicated. I use github with other developers and I just want all the local branches whose remotes were (possibly merged and) deleted from a github PR to be deleted in one go from my machine. No, things like git branch -r --mergeddon't cover the branches that were not merged locally, or the ones that were not merged at all (abandoned) etc, so a different solution is needed.

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

Anyway, the first step I got it from other answers:

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

git fetch --prune

A dry run of git remote prune originseemed like it would do the same thing in my case, so I went with the shortest version to keep it simple.

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

Now, a git branch -vshould mark the branches whose remotes are deleted as [gone]. Therefore, all I need to do is:

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

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

As simple as that, it deletes everything I want for the above scenario.

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

The less common xargssyntax is so that it also works on Mac & BSD in addition to Linux. Careful, this command is not a dry run so it will force-delete all the branches marked as [gone]. Obviously, this being git nothing is gone forever, if you see branches deleted that you remember you wanted kept you can always undelete them (the above command will have listed their hash on deletion, so a simple git checkout -b <branch> <hash>.

不太常见的xargs语法是它除了 Linux 之外也适用于 Mac 和 BSD。请注意,此命令不是试运行,因此它会强制删除所有标记为 的分支[gone]。显然,这是 git nothing 已经一去不复返了,如果你看到删除的分支你记得你想保留,你可以随时取消删除它们(上面的命令将在删除时列出它们的哈希值,所以一个简单的git checkout -b <branch> <hash>.

回答by Jan Winter

# 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

Prune the same branches from local- and remote-refs(in my example from origin).

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