我遵循一个开发过程,为每个新功能或故事卡创建一个新的本地分支。完成后,我将分支合并到 master 然后推送。
由于懒惰或健忘,随着时间的推移往往会发生的情况是,我最终得到了大量本地分支,其中一些(例如尖峰)可能尚未合并。
我知道如何列出所有本地分支,也知道如何删除单个分支,但我想知道是否有 git 命令允许我删除所有本地分支?
以下是 git branch --merged
命令的输出。
user@machine:~/projects/application[master]$ git branch --merged
STORY-123-Short-Description
STORY-456-Another-Description
STORY-789-Blah-Blah
* master
所有尝试删除以 grep -v \*
列出的分支(根据下面的答案)都会导致错误:
error: branch 'STORY-123-Short-Description' not found.
error: branch 'STORY-456-Another-Description' not found.
error: branch 'STORY-789-Blah-Blah' not found.
我在用着:
git 1.7.4.1
ubuntu 10.04
GNU bash, version 4.1.5(1)-release
GNU grep 2.5.4
rm -rf /my_cool_repo
并重新克隆 repo。如果我没有一个活动分支,这是“清除所有本地分支”IMO 的最简单方法。如果您正在积极地在分支上工作,显然不是答案。
'git branch -d' 子命令可以删除多个分支。因此,简化@sblom 的答案,但添加一个关键的 xargs:
git branch -D `git branch --merged | grep -v \* | xargs`
或者,进一步简化为:
git branch --merged | grep -v \* | xargs git branch -D
重要的是,作为 noted by @AndrewC,不鼓励使用 git branch
编写脚本。为了避免它使用类似的东西:
git for-each-ref --format '%(refname:short)' refs/heads | grep -v "master\|main" | xargs git branch -D
删除需谨慎!
$ mkdir br
$ cd br; git init
Initialized empty Git repository in /Users/ebg/test/br/.git/
$ touch README; git add README; git commit -m 'First commit'
[master (root-commit) 1d738b5] First commit
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README
$ git branch Story-123-a
$ git branch Story-123-b
$ git branch Story-123-c
$ git branch --merged
Story-123-a
Story-123-b
Story-123-c
* master
$ git branch --merged | grep -v \* | xargs
Story-123-a Story-123-b Story-123-c
$ git branch --merged | grep -v \* | xargs git branch -D
Deleted branch Story-123-a (was 1d738b5).
Deleted branch Story-123-b (was 1d738b5).
Deleted branch Story-123-c (was 1d738b5).
删除所有分支但保留“develop”和“master”等其他分支的更简单方法如下:
git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
很有用 !
develop*
或 master*
分支也不会被删除)
我找到了一个更好的方法in a comment on this issue on github:
git branch --merged master --no-color | grep -v "master\|stable\|main" | xargs git branch -d
编辑:添加了无颜色选项并排除了稳定分支(根据需要添加其他分支)
error: branch 'my-branch-name' not found.
。使用 git 版本 1.8.3.4 (Apple Git-47)。知道为什么吗?
git for-each-ref --format '%(refname:short)' refs/heads/ | grep -v master | xargs git branch -d
fatal: malformed object name master, fatal: branch name required
。这是因为很多 github 项目不再有 master
分支。他们经常改用 main
。在这种情况下,将 git branch --merged master
替换为 git branch --merged main
。
不建议解析 git branch
的输出,对于 Stack Overflow 上的未来读者来说,这也不是一个好的答案。
git branch 是所谓的瓷器命令。 Porcelain 命令不是为机器解析而设计的,输出可能会在不同版本的 Git 之间发生变化。有一些用户配置选项会以难以解析的方式更改 git branch 的输出(例如,着色)。如果用户设置了 color.branch,那么您将在输出中获得控制代码,这将导致错误:找不到分支 'foo'。如果您尝试将其通过管道传输到另一个命令中。您可以使用 --no-color 标志绕过它到 git 分支,但谁知道其他用户配置可能会破坏事情。 git branch 可能会做其他令人讨厌的解析,比如在当前签出的分支旁边放一个星号
关于围绕 git branch
输出编写脚本的 maintainer of git has this to say
为了找出当前分支是什么,随意/粗心的用户可能已经围绕 git 分支编写了脚本,这是错误的。我们强烈反对在脚本中使用任何 Porcelain 命令,包括 git 分支,因为命令的输出可能会更改以帮助人类消费用例。
建议手动编辑 .git
目录中的文件(如 .git/refs/heads)的答案同样有问题(参考可能在 .git/packed-refs 中,或者 Git 将来可能会更改其内部布局)。
Git 提供 for-each-ref
命令来检索分支列表。
Git 2.7.X 将引入 --merged
选项,以便您可以执行以下操作来查找和删除合并到 HEAD
中的所有分支
for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/)
do
git branch -d ${mergedBranch}
done
Git 2.6.X 及更早版本,您将需要列出所有本地分支,然后单独测试它们以查看它们是否已合并(这将明显变慢并且稍微复杂一些)。
for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/)
do
git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch}
done
git branch --no-color 2>/dev/null
?
git branch
是一个瓷器命令,并且不能保证输出在某些未来版本的 git 中不会改变。
尝试以下 shell 命令:
git branch | grep -v "master" | xargs git branch -D
解释:
通过 git branch | 获取所有分支(master除外) grep -v "master" 命令
使用 xargs 命令选择每个分支
使用 xargs git branch -D 删除分支
master
和其他一些分支说 branchA
之外的所有其他分支?目前我做git branch | grep -v "master" | grep -v "branchA" | xargs git branch -D
git checkout master
:git checkout master; git branch | grep -v "master" | xargs git branch -D
要删除除您当前已签出的分支之外的每个分支:
for b in `git branch --merged | grep -v \*`; do git branch -D $b; done
我建议在前几次将 git branch -D $b
更改为 echo $b
以确保它删除了您想要的分支。
error:branch 'a_branch_name' not found.
我可以看到您要执行的操作,并且我一直在使用该命令,但由于某种原因,git 似乎不喜欢提供的分支名称...
git branch --merged
的一些示例输出会很有用
STORY-123-Short-Description
git branch --merged
时,您会得到一个列表,其中每行都有一个?
error:branch 'a_branch_name' not found.
吗?或者它是否抱怨上面 git branch
输出中的一个分支名称?
以下命令将删除除 master 分支之外的所有本地分支。
git branch | grep -v "master" | xargs git branch -D
上面的命令
列出所有分支 从列表中忽略主分支并取其余分支删除分支
git branch | grep -v "master" | xargs git branch -d
,这样我就不会删除未合并的分支。但很好的答案!
,@(git branch | Select-String -Pattern "[^(*?)\s? master]") | ForEach-Object{$_.Line.Trim()} | %{git branch -D $_}
请注意,我会升级到 git 1.7.10。您可能会在这里得到不适用于您的版本的答案。我的猜测是您必须在分支名称前加上 refs/heads/
。
注意,仅当您制作了工作文件夹和 .git 目录的副本时,才继续执行以下操作。
有时我会直接从 .git/refs/heads
中删除我不想要的分支。所有这些分支都是文本文件,其中包含它们指向的提交的 40 个字符的 sha-1。如果您为其中任何一个设置了特定跟踪,您的 .git/config
中将包含无关信息。您也可以手动删除这些条目。
删除 linux 中的所有本地分支,除了你所在的分支
// hard delete
git branch -D $(git branch)
我发现只使用文本编辑器和 shell 更容易。
在 shell 中输入 git checkout
而已。
在 Windows 命令行中,使用以下命令删除除当前签出分支之外的所有内容:
for /f "tokens=*" %f in ('git branch ^| find /v "*"') do git branch -D %f
.bat
或 .cmd
文件时,它会显示:f was unexpected at this time.
我需要更改有关 %f
参数的内容吗?
.cmd
文件中,您需要将 %f
替换为 %%f
for /f "tokens=*" %f in ('git branch ^| find "chore"') do git branch -D %f
如果要删除所有本地分支,请使用以下简单命令:
git branch -D `git branch`
注意:这将删除除当前签出分支之外的所有分支
我有类似的情况,最近发现以下命令很有用。
git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'`
如果你想保留多个分支,那么
git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`
希望这可以帮助某人。
git branch -D `git branch | awk '{ if ($0 !~ /master/) printf "%s", $0 }'`
——实际上我认为你最初确实有它们,但它们在 SO 格式中丢失了。
这是适用于在 Windows 机器上运行的任何人的 Powershell 解决方案
git checkout master # by being on the master branch, you won't be able to delete it
foreach($branch in (git branch))
{
git branch -D $branch.Trim()
}
foreach($branch in (git branch)) { if ($branch.trim().startswith("feature")) {git branch -D $branch.trim()} }
删除了我的所有功能。谢谢 :)
git branch -l |grep -v master | xargs git branch -D
但是在乎删除分支;如果它是一个小存储库,只需删除工作区并重新克隆它!
如果您不需要通过 Git 本身,您也可以手动或以编程方式删除 .git/refs/heads 下的头。以下内容应在 Bash 下进行最少的调整:
shopt -s extglob
rm -rf .git/refs/heads/!(master)
这将删除除您的主分支之外的每个本地分支。由于您的上游分支存储在 .git/refs/remotes 下,因此它们将保持不变。
如果您不使用 Bash,或者想一次递归大量 Git 存储库,您可以使用 GNU find 执行类似的操作:
find . \
-path remotes -path logs -prune -o \
-wholename \*.git/refs/heads/\* \! -name master -print0 |
xargs -0 rm -rf
find 解决方案可能更便携,但修剪路径和文件名很棘手,并且可能更容易出错。
没有一个答案完全满足我的需求,所以我们开始吧:
git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin
这将删除所有已合并并以 feature/
、bugfix/
或 hotfix/
开头的本地分支。之后上游远程 origin
被修剪(您可能必须输入密码)。
适用于 Git 1.9.5。
虽然这不是命令行解决方案,但我很惊讶 Git GUI 尚未被建议。
我 99% 的时间都使用命令行,但在这种情况下,它要么很慢(因此是原始问题),要么在使用一些冗长但巧妙的 shell 操作时,您不知道要删除什么。
UI 解决了这个问题,因为您可以快速检查要删除的分支,并提醒您要保留的分支,而无需为每个分支键入命令。
从 UI 转到 Branch -->删除 和 Ctrl+单击 要删除的分支,使它们突出显示。如果您想确保它们被合并到一个分支中(例如 dev
),请在 Delete Only if Merged Into 下将 Local Branch 设置为 dev
。否则,将其设置为 始终 以忽略此检查。
https://i.stack.imgur.com/18HfP.png
基于此处的多个答案的组合-如果您想保留远程存在的所有分支但删除其余分支,则以下 oneliner 将起到作用:
git for-each-ref --format '%(refname:short)' refs/heads | grep -Ev `git ls-remote --quiet --heads origin | awk '{print substr($2, 12)}'| paste -sd "|" -` | xargs git branch -D
删除所有本地 git 分支但保留 main
git branch | grep -v "main" | xargs git branch -D
如果您想保留 master、develop 和所有远程分支。删除 Github 上不再存在的所有本地分支。
$ git fetch --prune
$ git branch | grep -v "origin" | grep -v "develop" | grep -v "master" | xargs git branch -D
1] 它将删除远程存储库中不再使用的远程引用。
2] 这将获得所有分支的列表。从列表中删除包含 master、develop 或 origin(远程分支)的分支。删除列表中的所有分支。
警告 - 这也会删除您自己的本地分支。因此,当您合并分支并在合并、删除后进行清理时,请执行此操作。
git branch -d [branch name]
用于本地删除
git branch -D [branch name]
也用于本地删除,但强制删除
对于 powershell,这将起作用:
git branch --format '%(refname:lstrip=2)' --merged `
| Where-Object { $_ -ne 'master' } `
| ForEach-Object { git branch -d $_ }
我的盒子上没有 grep 或其他 unix,但这在 VSCode 的终端上有效:
git branch -d $(git branch).trim()
我使用小写的 d 所以它不会删除未合并的分支。
当我这样做时,我也在 master 上,所以 * master
不存在,所以它没有尝试删除 master。
master
上,此命令将删除 master
。
我建议一个更温和的答案。这里的许多答案都使用 -D
强制删除,无论更改是否已合并。这是一个单一的衬里,它使具有未合并更改的分支保持不变。
git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
或者您可以尝试列出的其他示例,但只需将 -D
更改为 -d
。我知道 OP 询问如何删除,但在大多数用例中,使用 -d
更安全。
为此,您可以使用 git-extras
$ git delete-merged-branches
Deleted feature/themes (was c029ab3).
Deleted feature/live_preview (was a81b002).
Deleted feature/dashboard (was 923befa).
一次删除多个本地分支
# delete all local unmerged branches
git branch --no-merged | egrep -v "(^\*|master|dev)" | xargs git branch -D
# delete all local branches (merged and unmerged).
git branch | egrep -v "(^\*|master|dev)" | xargs git branch -D
删除远程分支
# Deleting non-existent tracking branches
git remote prune <remote> --dry-run
# Deleting a single remote branch
git push <remote> --delete <branch>
# Deleting many remote branches at once
git branch -r --merged | egrep -v "(^\*|master|dev)" | sed 's/origin\///' | xargs -n 1 git push origin --delete
以下脚本删除分支。使用它并自行承担修改等风险。
基于这个问题的其他答案,我最终为自己编写了一个快速的 bash 脚本。我称它为“gitbd”(git branch -D),但如果你使用它,你可以将它重命名为你想要的任何名称。
gitbd() {
if [ $# -le 1 ]
then
local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"`
printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] "
read -n 1 -r # Immediately continue after getting 1 keypress
echo # Move to a new line
if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]]
then
echo $branches_to_delete | xargs git branch -D
fi
else
echo "This command takes one arg (match pattern) or no args (match all)"
fi
}
它将提供删除与模式参数匹配的任何分支(如果传入),或者在不带参数调用时删除所有本地分支。它还会为您提供确认步骤,因为您知道,我们正在删除内容,这很好。
这有点愚蠢——如果没有与模式匹配的分支,它就不会意识到这一点。
示例输出运行:
$ gitbd test
Matching branches:
dummy+test1
dummy+test2
dummy+test3
Delete? [Y/n]
我编写了一个 shell 脚本以删除除 develop
之外的所有本地分支
branches=$(git branch | tr -d " *")
output=""
for branch in $branches
do
if [[ $branch != "develop" ]]; then
output="$output $branch"
fi
done
git branch -d $output
不定期副业成功案例分享
error:branch 'STORY-123-Short-Description' not found.
用于列出的每个分支。error:branch 'STORY-123-Short-Description' not found.
错误,这可能是由于 git 颜色设置。这对我有用(注意--no-color
选项):git branch --no-color --merged | grep -v \* | xargs git branch -D
npx clear-branches
。fatal: branch name required