git 如何修剪不再存在于远程的本地跟踪分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13064613/
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
How to prune local tracking branches that do not exist on remote anymore
提问by Alex
With git remote prune origin
I can remove the local branches that are not on the remote any more.
随着git remote prune origin
我可以删除不在远程的本地分支。
But I also want to remove local branches that were created from those remote branches (a check if they are unmerged would be nice).
但我也想删除从这些远程分支创建的本地分支(检查它们是否未合并会很好)。
How can I do this?
我怎样才能做到这一点?
回答by Schleis
After pruning, you can get the list of remote branches with git branch -r
. The list of branches with their remote tracking branch can be retrieved with git branch -vv
. So using these two lists you can find the remote tracking branches that are not in the list of remotes.
修剪后,您可以使用git branch -r
. 可以使用 检索带有远程跟踪分支的分支列表git branch -vv
。因此,使用这两个列表,您可以找到不在远程列表中的远程跟踪分支。
This line should do the trick (requires bash
or zsh
, won't work with standard Bourne shell):
这一行应该可以解决问题(需要bash
或zsh
,不适用于标准的 Bourne shell):
git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
This string gets the list of remote branches and passes it into egrep
through the standard input. And filters the branches that have a remote tracking branch (using git branch -vv
and filtering for those that have origin
) then getting the first column of that output which will be the branch name. Finally passing all the branch names into the delete branch command.
该字符串获取远程分支列表并将其egrep
通过标准输入传递。并过滤具有远程跟踪分支的分支(使用git branch -vv
并过滤具有 的分支origin
),然后获取该输出的第一列,即分支名称。最后将所有分支名称传递给删除分支命令。
Since it is using the -d
option, it will not delete branches that have not been merged into the branch that you are on when you run this command.
由于它正在使用该-d
选项,因此当您运行此命令时,它不会删除尚未合并到您所在分支中的分支。
Also remember that you'll need to run git fetch --prune
first, otherwise git branch -r
will still see the remote branches.
还记得你需要运行的git fetch --prune
第一,否则git branch -r
仍然会看到远程分支。
回答by Hymanocnr
回答by twalberg
Amidst the information presented by git help fetch
, there is this little item:
在 提供的信息中git help fetch
,有一个小项目:
-p, --prune
After fetching, remove any remote-tracking branches which no longer exist on the remote.
So, perhaps, git fetch -p
is what you are looking for?
那么,也许,git fetch -p
这就是你要找的吗?
EDIT: Ok, for those still debating this answer 3 years after the fact, here's a little more information on why I presented this answer...
编辑:好的,对于那些在事实发生 3 年后仍在争论这个答案的人,这里有更多关于我为什么提出这个答案的信息......
First, the OP says they want to "remove also those local branches that were created from those remote branches [that are not any more on the remote]". This is not unambiguously possible in git
. Here's an example.
首先,OP 表示他们希望“还删除那些从远程分支创建的本地分支[不再在远程分支上]”。这在git
. 这是一个例子。
Let's say I have a repo on a central server, and it has two branches, called A
and B
. If I clone that repo to my local system, my clone will have local refs (not actual branches yet) called origin/A
and origin/B
. Now let's say I do the following:
假设我在中央服务器上有一个 repo,它有两个分支,称为A
和B
。如果我将该 repo 克隆到我的本地系统,我的克隆将具有名为origin/A
and 的本地引用(尚未实际分支)origin/B
。现在假设我执行以下操作:
git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>
The pertinent facts here are that I for some reason chose to create a branch on my local repo that has a different name than its origin, and I also have a local branch that does not (yet) exist on the origin repo.
这里的相关事实是,我出于某种原因选择在我的本地存储库上创建一个名称与其来源不同的分支,并且我还有一个本地分支(尚未)存在于来源存储库中。
Now let's say I remove both the A
and B
branches on the remote repo and update my local repo (git fetch
of some form), which causes my local refs origin/A
and origin/B
to disappear. Now, my local repo has three branches still, A
, Z
, and C
. None of these have a corresponding branch on the remote repo. Two of them were "created from ... remote branches", but even if I know that there used to be a branch called B
on the origin, I have no way to know that Z
was created from B
, because it was renamed in the process, probably for a good reason. So, really, without some external process recording branch origin metadata, or a human who knows the history, it is impossible to tell which of the three branches, if any, the OP is targeting for removal. Without some external information that git
does not automatically maintain for you, git fetch -p
is about as close as you can get, and any automatic method for literally attempting what the OP asked runs the risk of either deleting too many branches, or missing some that the OP would otherwise want deleted.
现在,让我们说我同时删除A
和B
树枝上的远程回购和更新我的本地回购(git fetch
某些形式的),这将导致我的本地裁判origin/A
和origin/B
消失。现在,我的本地 repo 仍然有三个分支A
,、Z
、 和C
。这些在远程仓库上都没有相应的分支。其中两个是“从......远程分支创建的”,但即使我知道曾经有一个分支B
在原点上调用,我也无法知道它Z
是从B
,因为它在此过程中被重命名,这可能是有充分理由的。所以,实际上,如果没有一些外部进程记录分支源元数据,或者没有了解历史的人,就不可能知道 OP 的目标是删除三个分支中的哪一个(如果有的话)。如果没有一些git
不会自动为您维护的外部信息,则git fetch -p
几乎是您所能获得的,并且任何从字面上尝试 OP 所要求内容的自动方法都存在删除太多分支或丢失 OP 可能会丢失的一些分支的风险想删除。
There are other scenarios, as well, such as if I create three separate branches off origin/A
to test three different approaches to something, and then origin/A
goes away. Now I have three branches, which obviously can't all match name-wise, but they were created from origin/A
, and so a literal interpretation of the OPs question would require removing all three. However, that may not be desirable, if you could even find a reliable way to match them...
还有其他场景,例如,如果我创建三个独立的分支origin/A
来测试对某事的三种不同方法,然后origin/A
就消失了。现在我有三个分支,它们显然不能全部匹配名称,但它们是从 中创建的origin/A
,因此对 OPs 问题的字面解释需要删除所有三个。但是,如果您甚至可以找到一种可靠的方法来匹配它们,那可能并不理想……
回答by wisbucky
This will delete the local branches for which the remote tracking branches have been pruned. (Make sure you are on master
branch!)
这将删除已修剪远程跟踪分支的本地分支。(确保你在master
分支上!)
git checkout master
git branch -vv | grep ': gone]' | awk '{print }' | xargs git branch -d
Details:
细节:
git branch -vv
displays "gone" for local branches that the remote has been pruned.mybranch abc1234 [origin/mybranch: gone] commit comments
-d
will check if it has been merged (-D
will delete it regardless)error: The branch 'mybranch' is not fully merged.
git branch -vv
对于远程已被修剪的本地分支,显示“gone”。mybranch abc1234 [origin/mybranch: gone] commit comments
-d
将检查它是否已合并(-D
无论如何都会删除它)error: The branch 'mybranch' is not fully merged.
回答by wedesoft
One can configure Git to automatically remove references to deleted remote branches when fetching:
可以将 Git 配置为在获取时自动删除对已删除远程分支的引用:
git config --global fetch.prune true
When calling git fetch
or git pull
afterwards, references to deleted remote branches get removed automatically.
调用时git fetch
或git pull
之后,对已删除远程分支的引用会自动删除。
回答by tzachs
There's a neat NPM package that does it for you (and it should work cross platform).
有一个简洁的 NPM 包可以为您完成(并且它应该跨平台工作)。
Install it with: npm install -g git-removed-branches
安装它: npm install -g git-removed-branches
And then git removed-branches
will show you all the stale local branches, and git removed-branches --prune
to actually delete them.
然后git removed-branches
将向您显示所有陈旧的本地分支,并git removed-branches --prune
实际删除它们。
回答by chris31389
Windows Solution
视窗解决方案
For Microsoft Windows Powershell:
对于 Microsoft Windows Powershell:
git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Explaination
说明
git checkout master
switches to the master branch
git checkout master
切换到主分支
git remote update origin --prune
prunes remote branches
git remote update origin --prune
修剪远程分支
git branch -vv
gets a verbose output of all branches (git reference)
git branch -vv
获取所有分支的详细输出(git reference)
Select-String -Pattern ": gone]"
gets only the records where they have been removed from remote.
Select-String -Pattern ": gone]"
仅获取已从远程删除的记录。
% { $_.toString().Split(" ")[0]}
get the branch name
% { $_.toString().Split(" ")[0]}
获取分支名称
% {git branch -d $_}
deletes the branch
% {git branch -d $_}
删除分支
回答by 027
It will list the local branches whose remote tracking branch is deleted from remote
它将列出远程跟踪分支从远程删除的本地分支
$ git remote prune origin --dry-run
If you want to de-reference these local branches from local which are un tracked
如果您想从未跟踪的本地取消引用这些本地分支
$ git remote prune origin
回答by johnshew
As @tzacks notes... there is an npm package that is handy for this. Just do:
正如@tzacks 指出的那样......有一个 npm 包可以方便地做到这一点。做就是了:
npx git-removed-branches --prune
(I would have commented but not enough reputation)
(我会评论但没有足够的声誉)
回答by Gnat
If using Windows and Powershell, you can use the following to delete all local branches that have been merged into the branch currently checked out:
如果使用 Windows 和 Powershell,则可以使用以下命令删除所有已合并到当前检出分支中的本地分支:
git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}
Explanation
解释
- Lists the current branch and the branches that have been merged into it
- Filters out the current branch
- Cleans up any leading or trailing spaces from the
git
output for each remaining branch name - Deletes the merged local branches
- 列出当前分支和已经合并到其中的分支
- 过滤掉当前分支
git
为每个剩余的分支名称清除输出中的任何前导或尾随空格- 删除合并的本地分支
It's worth running git branch --merged
by itself first just to make sure it's only going to remove what you expect it to.
值得git branch --merged
先单独运行,以确保它只会删除您期望的内容。
(Ported/automated from http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/.)