清理旧的远程 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
Cleaning up old remote git branches
提问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 -a
on computer A, I get the following list of branches.
git branch -a
在计算机 A 上运行,我得到以下分支列表。
- master
- origin/HEAD
- origin/master
- 掌握
- 起源/头部
- 起源/主人
Running git fetch
on 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/devel
returns 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 -a
still 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 -a
on machine B?
首先,git branch -a
在机器 B 上的结果是什么?
Second, you have already deleted heads/devel
on origin
, so that's why you can't delete it from machine B.
其次,您已经删除heads/devel
了origin
,所以这就是您无法从机器 B 中删除它的原因。
Try
尝试
git branch -r -d origin/devel
or
或者
git remote prune origin
or
或者
git fetch origin --prune
and feel free to add --dry-run
to the end of your git
statement to see the result of running it without actually running it.
并随意添加--dry-run
到git
语句的末尾以查看运行它的结果,而无需实际运行它。
Docs for git remote prune
and 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-repo
setting that will make any future git fetch or git pull
to 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 -r
shows 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
, develop
and releasebranches, feel free to adapt as you need.
在上面的例子中,我们只取master
,develop
并释放分支机构,随时适应,因为你需要。
回答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, git
will 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
回答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 --merged
don'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 origin
seemed 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 -v
should 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 xargs
syntax 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
)。