git 列出所有没有遥控器的本地分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15661853/
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
List all local branches without a remote
提问by JC Denton
Problem: I want a way of deleting all the local branches I have that do not have a remote. It's easy enough to pipe the names of the branches into a git branch -D {branch_name}
, but how do I get that list in the first place?
问题:我想要一种删除所有没有遥控器的本地分支的方法。将分支的名称通过管道传输到 a 中很容易git branch -D {branch_name}
,但是首先我如何获得该列表?
For example:
例如:
I create a new branch without a remote:
我创建了一个没有遥控器的新分支:
$ git co -b no_upstream
I list all my branches, and there's only one with a remote
我列出了我所有的分支,只有一个有遥控器
$ git branch -a
master
* no_upstream
remotes/origin/HEAD -> origin/master
remotes/origin/master
What command can I run to get no_upstream
as an answer?
我可以运行什么命令来获得no_upstream
答案?
I can run git rev-parse --abbrev-ref --symbolic-full-name @{u}
and that will show that it has no remote:
我可以运行git rev-parse --abbrev-ref --symbolic-full-name @{u}
,这将表明它没有遥控器:
$ git rev-parse --abbrev-ref --symbolic-full-name @{u}
error: No upstream configured for branch 'no_upstream'
error: No upstream configured for branch 'no_upstream'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
But as this is an error, it won't let me use it or pipe it to other commands. I'm intending to use this as either a shell script alias'd to git-delete-unbranched
or maybe make a super simple Gem like git-branch-delete-orphans
但由于这是一个错误,它不会让我使用它或通过管道将它传递给其他命令。我打算将它用作 shell 脚本的别名,git-delete-unbranched
或者制作一个超级简单的 Gem,例如git-branch-delete-orphans
回答by Jeremy Baker
I recently discovered git branch -vv
which is the "very verbose" version of the git branch
command.
我最近发现git branch -vv
这是命令的“非常冗长”版本git branch
。
It outputs the branches along with the remote branches if they exist, in the following format:
它以以下格式输出分支以及远程分支(如果存在):
25-timeout-error-with-many-targets 206a5fa WIP: batch insert
31-target-suggestions f5bdce6 [origin/31-target-suggestions] Create target suggestion for team and list on save
* 54-feedback-link b98e97c [origin/54-feedback-link] WIP: Feedback link in mail
65-digest-double-publish 2de4150 WIP: publishing-state
Once you have this nicely formatted output, it's as easy as piping it through cut
and awk
to get your list:
一旦你有了这个格式很好的输出,就像通过管道传递它cut
并awk
获取你的列表一样简单:
git branch -vv | cut -c 3- | awk ' !~/\[/ { print }'
Results in the following output:
结果如下:
25-timeout-error-with-many-targets
65-digest-double-publish
The cut
portion just normalizes the data by removing the first two characters (including *
) from the output before passing it to awk
.
该cut
部分只是通过在将数据*
传递给 之前从输出中删除前两个字符(包括)来规范化数据awk
。
The awk
portion prints the first column if there is no square bracket in the third column.
awk
如果第三列中没有方括号,该部分将打印第一列。
Bonus: Create an alias
奖励:创建别名
Make it easy to run by creating an alias in your global .gitconfig
file (or wherever):
通过在全局.gitconfig
文件(或任何地方)中创建别名,使其易于运行:
[alias]
local-branches = !git branch -vv | cut -c 3- | awk ' !~/\[/ { print }'
Important: The backslash needs to be escaped in the alias or else you will have an invalid gitconfig file.
重要提示:反斜杠需要在别名中转义,否则您将拥有无效的 gitconfig 文件。
Bonus: Remote Filtering
奖励:远程过滤
If for some reason you have multiple tracking remotes for different branches, it's easy enough to specify which remote you want to check against. Just append the remote name to the awk pattern. In my case, it's origin
so I can do this:
如果出于某种原因,您有多个跟踪不同分支的遥控器,则很容易指定要检查的遥控器。只需将远程名称附加到 awk 模式。就我而言,origin
我可以这样做:
git branch -vv | cut -c 3- | awk ' !~/\[origin/ { print }'
回答by VonC
git branch
(without any options) lists only local branches, but you don't know if they are tracking a remote branch or not.
git branch
(没有任何选项)仅列出本地分支,但您不知道它们是否正在跟踪远程分支。
Usually those local branches should be deleted once merged into master
(as seen in this issue of git-sweep):
通常,这些本地分支应在合并后删除master
(如本期 git-sweep 所示):
git branch --merged master | grep -v master | xargs git branch -d
This isn't as complete as you want, but it is a start.
这并不像您想要的那样完整,但它是一个开始。
With
--merged
, only branches merged into the named commit (i.e. the branches whose tip commits are reachable from the named commit) will be listed.
使用
--merged
,只会列出合并到命名提交中的分支(即可以从命名提交访问其提示提交的分支)。
回答by Karl Wilbur
I have a similar issue. I want to remove all local branches that were tracking remote branches that are now deleted. I am finding that git remote prune origin
was insufficient to remove the branches that I want gone. Once the remote is deleted, I want the local to go away too. Here is what worked for me:
我有一个类似的问题。我想删除所有跟踪现在已删除的远程分支的本地分支。我发现这git remote prune origin
不足以删除我想要的分支。删除遥控器后,我也希望本地也消失。这是对我有用的:
From my ~/.gitconfig
:
从我的~/.gitconfig
:
[alias]
prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print }' | xargs -r git branch -d
Here is a git config --global ...
command for easily adding this as git prune-branches
:
这是一个git config --global ...
可以轻松将其添加为的命令git prune-branches
:
git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print }'"'"' | xargs -r git branch -d'
NOTE: I changed the -d
to -D
in my actual configuration, because I don't want to hear Git complain about unmerged branches. You maywant this functionality as well. If so, simply use -D
instead of -d
at the end of that command.
注意:我在实际配置中更改了-d
to -D
,因为我不想听到 Git 抱怨未合并的分支。您可能也需要此功能。如果是这样,只需在该命令的末尾使用-D
而不是-d
。
Also, FWIW, your global configuration file would almost always be ~/.gitconfig
.
此外,FWIW,您的全局配置文件几乎总是~/.gitconfig
.
(OS X Fix)
(OS X 修复)
As written, this does not work on OS X because of the use of xargs -r
(thanks, Korny).
正如所写,这在 OS X 上不起作用,因为使用了xargs -r
(谢谢,Korny)。
The -r
is to prevent xargs
from running git branch -d
without a branch name, which will result in an error message "fatal: branch name required
". If you don't mind the error message, you can simply remove the -r
argument to xargs
and you're all set.
这-r
是为了防止xargs
在git branch -d
没有分支名称的情况下运行,这将导致错误消息“ fatal: branch name required
”。如果您不介意错误消息,您可以简单地删除-r
参数,xargs
就可以了。
However, if you don't want to see an error message (and really, who could blame you) then you'll need something else that checks for an empty pipe. If you might be able to use ifnefrom moreutils. You would insert ifne
before xargs
, which will stop xargs
from running with empty data. NOTE: ifne
considers anythingto be not empty, this includes blank lines, so you may still see that error message. I've not tested this on OS X.
但是,如果您不想看到错误消息(实际上,谁会责怪您),那么您将需要其他东西来检查空管道。如果您可以使用moreutils 中的ifne。您将插入ifne
before xargs
,这将停止xargs
运行空数据。注意:ifne
认为任何内容都不是空的,这包括空行,因此您可能仍会看到该错误消息。我没有在 OS X 上测试过这个。
Here is that git config
line with ifne
:
这是那条git config
线ifne
:
git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print }'"'"' | ifne xargs git branch -d'
回答by jthill
Late edit:
后期编辑:
Better is
更好的是
git for-each-ref --format='%(refname:short) %(upstream)' refs/heads \
| awk ' !~/^refs\/remotes/'
On GNU/anything
关于 GNU/任何东西
for b in `git branch|sed s,..,,`; do
git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done
If more than a handful of branches were likely, there'd be better ways, using comm -23
on the output of git branch|sed|sort
and git config -l|sed|sort
.
如果超过了一把树枝很可能有会是更好的方式,使用comm -23
上的输出git branch|sed|sort
和git config -l|sed|sort
。
回答by ebr
This works for me:
这对我有用:
git branch -vv | grep -v origin
git branch -vv | grep -v origin
(if your remote is named anything other than origin, substitute that).
(如果您的遥控器命名为 origin 以外的任何名称,请替换它)。
This will list all the branches that aren't tracking a remote, which sounds like what you're looking for.
这将列出所有未跟踪遥控器的分支,这听起来像您要查找的内容。
回答by fiorentinoing
I synthetise my own Git command to get the origin/***: gone
branches:
我合成了自己的 Git 命令来获取origin/***: gone
分支:
git remote prune origin && git branch -vv | cut -c 3- | grep ': gone]' | awk '{print }' | xargs -n1 -r echo git branch -d
git remote prune origin && git branch -vv
will print branches in verbose mode.
git remote prune origin && git branch -vv
将以详细模式打印分支。
cut -c 3-
will remove very first characters.
cut -c 3-
将删除第一个字符。
grep ': gone]'
will print only the goneremote branches.
grep ': gone]'
将只打印消失的远程分支。
awk '{print $1}'
will print the branch name.
awk '{print $1}'
将打印分支名称。
xargs -n1 -r echo git branch -d
will print the git branch -d
command to remove branches (-n1 will manage one command per time, -r to avoid issuing command if no branch is present).
xargs -n1 -r echo git branch -d
将打印git branch -d
删除分支的命令(-n1 将每次管理一个命令,-r 以避免在不存在分支时发出命令)。
HINT:remove the "echo" command to runthe commands instead of print only, I left this in the command to check commands before issuing to git.
提示:删除“echo”命令以运行命令而不是仅打印,我将其留在命令中以在向 git 发出之前检查命令。
HINT 2:issue git branch -D
if and only if you are sure you want to remove unmerged branches
提示 2:git branch -D
当且仅当您确定要删除未合并的分支时才发出
回答by grahamesd
Here is something I have used in PowerShell with comments to explain what it's doing. In an attempt to make it clear what's going on, I've not used any abbreviated PowerShell commands (aliases). Feel free to compress it to your desired level of crypticness :)
这是我在 PowerShell 中使用的一些注释来解释它在做什么。为了弄清楚发生了什么,我没有使用任何缩写的 PowerShell 命令(别名)。随意将其压缩到您想要的神秘程度:)
$verboseList = @(git branch -vv)
foreach ($line in $verboseList)
{
# Get the branch name
$branch = [regex]::Match($line, "\s(\S+)\s").Captures.Groups[1].Value
# Check if the line contains text to indicate if the remote is deleted
$remoteGone = $line.Contains(": gone]")
# Check if the line does not contain text to indicate it is a tracking branch (i.e., it's local)
$isLocal = !($line.Contains("[origin/"))
if ($remoteGone -or $isLocal)
{
# Print the branch name
$branch
}
}
回答by nbergen
Rough PowerShell implementation (if origin is your only remote):
粗略的 PowerShell 实现(如果 origin 是你唯一的远程):
@($branches = git br -r; git branch | %{ echo $_ | sed 's/..//' }) `
| %{ if (($branches | ss "origin/$_") -eq $null) { `
echo "git branch -D $_" `
} `
}
回答by Reid
Combining a few of the existing answers:
结合一些现有的答案:
[alias]
branch-local = !git branch -vv | cut -c 3- | egrep '([0-9a-f]{7} [^[])|(: gone\])' | sed -E 's/(^.+[0-9a-f]{7} (\[.+\])?).*$/\1/'
E.g.:
例如:
$ git branch-local
autogen_autoreconf fcfb1c6 [github/autogen_autoreconf: gone]
autotools_documentation 72dc477 [github/autotools_documentation: gone]
cray-mpich-messy 2196f4b
epel-sphinx cfda770
lammps 07d96a7 [github/lammps: gone]
lark-error 9ab5d6c [github/lark-error: gone]
no-root2 c3894d1
openmpi-cray 69326cf [github/openmpi-cray: gone]
shellcheck-cleanup 40d90ec
travis-python36 cde072e
update_vagrant_default 4f69f47 [github/update_vagrant_default: gone]
web-docs e73b4a8