Nya*_*baa 1782 git version-control branch github feature-branch
我有很多Git分支.如何删除已合并的分支?是否有一种简单的方法可以删除它们而不是逐个删除它们?
Ada*_*ruk 2878
更新:
如果您的工作流将那些分支作为可能的祖先,您可以添加其他分支以排除master和dev.通常我分支出一个"sprint-start"标签和master,dev和qa不是祖先.
首先,列出在远程合并的所有分支.
git branch --merged
Run Code Online (Sandbox Code Playgroud)
您可能会看到几个不想删除的分支.我们可以添加一些参数来跳过我们不想删除的重要分支,如master或develop.以下命令将跳过master分支和其中包含dev的任何内容.
git branch --merged| egrep -v "(^\*|master|dev)"
Run Code Online (Sandbox Code Playgroud)
如果要跳过,可以将其添加到egrep命令,如下所示.该分支skip_branch_name
不会被删除.
git branch --merged| egrep -v "(^\*|master|dev|skip_branch_name)"
Run Code Online (Sandbox Code Playgroud)
要删除已合并到当前已检出分支的所有本地分支:
git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
您可以看到master和dev被排除在它们是祖先的情况下.
您可以删除合并的本地分支:
git branch -d branchname
Run Code Online (Sandbox Code Playgroud)
如果没有合并,请使用:
git branch -D branchname
Run Code Online (Sandbox Code Playgroud)
要在旧版本的Git中从远程删除它,请使用:
git push origin :branchname
Run Code Online (Sandbox Code Playgroud)
在更新版本的Git中使用:
git push --delete origin branchname
Run Code Online (Sandbox Code Playgroud)
从远程删除分支后,您可以修剪以删除远程跟踪分支:
git remote prune origin
Run Code Online (Sandbox Code Playgroud)
或者修剪个别远程跟踪分支,正如另一个答案所暗示的那样:
git branch -dr branchname
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
kub*_*oon 424
要删除已合并的远程所有分支:
git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin
Run Code Online (Sandbox Code Playgroud)
在更新版本的Git中
git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin
Run Code Online (Sandbox Code Playgroud)
rea*_*ate 178
只是简单地扩展了Adam的答案:
通过运行将其添加到您的Git配置中 git config -e --global
[alias]
cleanup = "!git branch --merged | grep -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d"
Run Code Online (Sandbox Code Playgroud)
然后你可以删除所有本地合并的分支做一个简单的git cleanup
.
Ism*_*reu 81
这也可以删除除master之外的所有合并分支.
git branch --merged | grep -v '^* master$' | grep -v '^ master$' | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
Gui*_*man 75
您将要从这些命令中排除master
&develop
分支.
本地git清除:
git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)
远程git清除:
git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin
Run Code Online (Sandbox Code Playgroud)
同步远程分支的本地注册表:
git fetch -p
Run Code Online (Sandbox Code Playgroud)
Kla*_*urn 47
对于那些在Windows上并且更喜欢PowerShell脚本的人来说,这里是删除本地合并分支的人:
function Remove-MergedBranches
{
git branch --merged |
ForEach-Object { $_.Trim() } |
Where-Object {$_ -NotMatch "^\*"} |
Where-Object {-not ( $_ -Like "*master" )} |
ForEach-Object { git branch -d $_ }
}
Run Code Online (Sandbox Code Playgroud)
edd*_*ies 39
多年来我一直使用亚当的答案.也就是说,在某些情况下,它没有像我预期的那样行事:
只需更改正则表达式,即可轻松解决1和2问题.3取决于您想要的上下文(即只删除尚未合并到master或当前分支的分支).4有可能是灾难性的(虽然可以恢复git reflog
),如果你无意中以独立的HEAD状态运行它.
最后,我希望这一切都在一个单行内容中,不需要单独的(Bash | Ruby | Python)脚本.
创建一个接受可选-f
标志的git别名"sweep" :
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
Run Code Online (Sandbox Code Playgroud)
并使用以下命令调用它:
git sweep
Run Code Online (Sandbox Code Playgroud)
要么:
git sweep -f
Run Code Online (Sandbox Code Playgroud)
我最简单的方法是使用一些分支和提交来创建一个示例git repo来测试正确的行为:
mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"
Run Code Online (Sandbox Code Playgroud)
git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar develop foo * master masterful notmaster
最初的正则表达式错过了"masterful"和"notmaster"的分支:
git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar
使用更新的正则表达式(现在不包括"开发"而不是"开发"):
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar masterful notmaster
echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"
Run Code Online (Sandbox Code Playgroud)
我当前的分支是foobar,如果我重新运行上面的命令列出我想删除的分支,即使它尚未合并到master中,也包含分支"foo":
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar foo masterful notmaster
但是,如果我在master上运行相同的命令,则不包括分支"foo":
git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar masterful notmaster
这只是因为git branch --merged
如果没有另外指定,则默认为当前分支的HEAD.至少对于我的工作流程,我不想删除本地分支,除非它们已经合并到master,所以我更喜欢以下变体:
git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar masterful notmaster
依赖于默认行为git branch --merged
在分离的HEAD状态中具有更显着的后果:
git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar foo foobar masterful notmaster
这将删除我刚才的分支,"foobar"和"foo",这几乎肯定不是理想的结果.但是,通过我们修订的命令:
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)bar masterful notmaster
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
Run Code Online (Sandbox Code Playgroud)
别名接受可选-f
标志.默认行为是仅删除已合并为master的-f
分支,但该标志将删除已合并到当前分支的分支.
git sweep
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Deleted branch bar (was 9a56952). Deleted branch masterful (was 9a56952). Deleted branch notmaster (was 9a56952).
git sweep -f
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Deleted branch foo (was 2cea1ab).
Tim*_*mmm 29
这里有很多不好的答案。这可能是您想要的:
git branch --delete $(git branch --merged master --no-contains master --format='%(refname:short)')
Run Code Online (Sandbox Code Playgroud)
这将选择已合并到master
(包括master
)且不是其后代master
(排除master
其自身)的所有本地分支。这--format
是必要的,因为默认情况下 Git 会为当前签出的分支打印星号。您也许也可以这样做,git for-each-ref
但它似乎更复杂(它也列出了远程分支)。
你不想要:
git branch --merged
(不带master
):这将列出已“合并”到您当前签出的提交(即HEAD
)中的分支,这可能是意外的,而不是您想要的。| grep -v master
: 没有这个必要;你可以只使用--no-contains
.| xargs
: 再说了,没必要。git branch --delete
可以删除多个分支。更新:我已经使用这个有一段时间了,效果很好。有两个小缺陷:
如果没有要删除的分支,则会出现错误。在我看来,这对于交互式使用来说很好。无论如何,您不应该在脚本中使用它,因为它是 Bash,并且 Bash不应该用于脚本编写。
它不会删除指向与 相同提交的分支master
。我有一个工具可以自动对所有分支进行变基,对于已合并的分支,它可以使它们保持这种状态。这对你来说可能并不重要。
Vik*_*iev 19
我最喜欢的简单脚本:
git branch --merged | grep -E -v "(master|main|develop|other)" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
Mar*_*ski 17
如果您使用的是 Windows,您可以使用带有Out-GridView 的Windows Powershell 或 Powershell 7来获得一个不错的分支列表,然后用鼠标选择要删除的分支:
git branch --format "%(refname:short)" --merged | Out-GridView -PassThru | % { git branch -d $_ }
Run Code Online (Sandbox Code Playgroud)
单击确定后 Powershell 会将这个分支名称传递给
git branch -d
命令并删除它们
dra*_*utb 16
使用Git版本2.5.0:
git branch -d `git branch --merged`
Run Code Online (Sandbox Code Playgroud)
Jör*_*des 14
您可以将提交添加到--merged选项.这样你就可以确保只删除合并到的分支,即origin/master
以下命令将从您的原点删除合并的分支.
git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete
Run Code Online (Sandbox Code Playgroud)
您可以测试将删除哪些分支替换git push origin --delete with echo
git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
Run Code Online (Sandbox Code Playgroud)
mmr*_*ins 12
我使用以下Ruby脚本删除已经合并的本地和远程分支.如果我正在为具有多个遥控器的存储库执行此操作并且只想从一个存储库中删除,我只需将一个select语句添加到遥控器列表中以仅获取我想要的遥控器.
#!/usr/bin/env ruby
current_branch = `git symbolic-ref --short HEAD`.chomp
if current_branch != "master"
if $?.exitstatus == 0
puts "WARNING: You are on branch #{current_branch}, NOT master."
else
puts "WARNING: You are not on a branch"
end
puts
end
puts "Fetching merged branches..."
remote_branches= `git branch -r --merged`.
split("\n").
map(&:strip).
reject {|b| b =~ /\/(#{current_branch}|master)/}
local_branches= `git branch --merged`.
gsub(/^\* /, '').
split("\n").
map(&:strip).
reject {|b| b =~ /(#{current_branch}|master)/}
if remote_branches.empty? && local_branches.empty?
puts "No existing branches have been merged into #{current_branch}."
else
puts "This will remove the following branches:"
puts remote_branches.join("\n")
puts local_branches.join("\n")
puts "Proceed?"
if gets =~ /^y/i
remote_branches.each do |b|
remote, branch = b.split(/\//)
`git push #{remote} :#{branch}`
end
# Remove local branches
`git branch -d #{local_branches.join(' ')}`
else
puts "No branches removed."
end
end
Run Code Online (Sandbox Code Playgroud)
Kon*_*kus 11
git branch --merged | %{git branch -d $_.Trim()}
Run Code Online (Sandbox Code Playgroud)
Elm*_*mer 11
我用这个:
git branch --delete $(git branch --format '%(refname:short)' --merged | grep --invert-match 'main\|master\|branch-to-skip')
Run Code Online (Sandbox Code Playgroud)
它以指定的格式列出所有合并的分支,然后将该列表提供给 gitbranch --delete。
psu*_*zzi 10
注意:我对以前的答案不满意(不适用于所有系统,不适用于远程,未指定 --merged 分支,未完全过滤)。所以,我添加我自己的答案。
主要有两种情况:
当地的
你想删除本地分支被已经合并到另一个地方分支。在删除过程中,您希望保留一些重要的分支,例如 master、develop 等。
git branch --format "%(refname:short)" --merged master | grep -E -v '^master$|^feature/develop$' | xargs -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)
注意事项:
git branch output --format
“..”是去除空格并允许精确的grep匹配grep -E
用于代替 egrep
,因此它也适用于没有 egrep 的系统(即:git for windows)。grep -E -v '^master$|^feature/develop$'
是指定我不想删除的本地分支xargs -n 1 git branch -d
: 执行删除本地分支(它不适用于远程分支)偏僻的
你想删除远程分支机构那些已经合并到另一个远程分支。在删除过程中,您希望保留一些重要的分支,例如 HEAD、master、releases 等。
git branch -r --format "%(refname:short)" --merged origin/master | grep -E -v '^*HEAD$|^*/master$|^*release' | cut -d/ -f2- | xargs -n 1 git push --delete origin
Run Code Online (Sandbox Code Playgroud)
注意事项:
-r
选项并提供完整的分支名称:origin/master
grep -E -v '^*HEAD$|^*/master$|^*release'
是匹配我们不想删除的远程分支。cut -d/ -f2-
: 删除不需要的“origin/”前缀,否则git branch
命令会打印出这些前缀。xargs -n 1 git push --delete origin
: 执行远程分支的删除。kuboon的回答错过了删除分支名称中包含master字样的分支.以下改进了他的答案:
git branch -r --merged | grep -v "origin/master$" | sed 's/\s*origin\///' | xargs -n 1 git push --delete origin
Run Code Online (Sandbox Code Playgroud)
当然,它不会删除"master"分支本身:)
Git中没有自动执行此操作的命令.但是你可以编写一个使用Git命令的脚本来为你提供所需的东西.这可以通过多种方式完成,具体取决于您使用的分支模型.
如果您需要知道某个分支是否已合并到master中,则如果已合并myTopicBranch,则以下命令将不会产生任何输出(即您可以将其删除)
$ git rev-list master | grep $(git rev-parse myTopicBranch)
Run Code Online (Sandbox Code Playgroud)
您可以使用Git branch命令并解析Bash中的所有分支,并for
在所有分支上执行循环.在此循环中,您可以使用上面的命令检查是否可以删除分支.
git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d
将删除除当前签出分支和/或之外的所有本地分支master
.
对于那些希望了解这些命令的人来说,这是一篇有用的文章:Git Clean:删除已经合并的分支,Steven Harman.
基于其中一些答案,我也制作了自己的 Bash 脚本来做到这一点!
它使用git branch --merged
和git branch -d
来删除已合并的分支,并在删除之前提示您输入每个分支。
merged_branches () {
local current_branch=$(git rev-parse --abbrev-ref HEAD)
for branch in $(git branch --merged | cut -c3-)
do
echo "Branch $branch is already merged into $current_branch."
echo "Would you like to delete it? [Y]es/[N]o "
read REPLY
if [[ $REPLY =~ ^[Yy] ]]; then
git branch -d $branch
fi
done
}
Run Code Online (Sandbox Code Playgroud)
你可以使用git-del-br
工具.
git-del-br -a
Run Code Online (Sandbox Code Playgroud)
您可以通过pip
使用安装它
pip install git-del-br
Run Code Online (Sandbox Code Playgroud)
PS:我是这个工具的作者.欢迎任何建议/反馈.
git branch --merged | grep -E -v "(master|test|dev)" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
其中grep -E -v
相当于egrep -v
使用-d
已删除合并分支机构或
-D
删除未合并分支
小智 5
如果您想删除已经合并到当前所在分支中的所有本地分支,那么根据先前的答案,我已经提出了一个安全的命令来执行此操作:
git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)
此命令不会影响您当前的分支或主分支。它还使用xargs的-t标志告诉您它在做什么之前。
我使用git-flow esque命名方案,因此这对我来说非常安全:
git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
它基本上会查找以string fix/
或feature/
。开头的合并提交。
别名版本的亚当更新答案:
[alias]
branch-cleanup = "!git branch --merged | egrep -v \"(^\\*|master|dev)\" | xargs git branch -d #"
Run Code Online (Sandbox Code Playgroud)
另外,请参阅此答案以获取有关转义复杂别名的方便提示.
尝试以下命令:
git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))
Run Code Online (Sandbox Code Playgroud)
通过使用git rev-parse
将获取当前分支名称以便排除它。如果出现错误,则意味着没有要删除的本地分支。
要对远程分支执行相同的操作(更改origin
为您的远程名称),请尝试:
git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)
Run Code Online (Sandbox Code Playgroud)
如果您有多个遥控器,请grep origin |
在前面添加cut
以仅过滤origin
.
如果上述命令失败,请尝试先删除合并的远程跟踪分支:
git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))
Run Code Online (Sandbox Code Playgroud)
然后git fetch
再次遥控并git push -vd
再次使用之前的命令。
如果您经常使用它,请考虑将其作为别名添加到您的~/.gitconfig
文件中。
如果您错误地删除了一些分支,请使用git reflog
来查找丢失的提交。
小智 5
以下查询对我有用
for branch in `git branch -r --merged | grep -v '\*\|master\|develop'|awk 'NR > 0 {print$1}'|awk '{gsub(/origin\//, "")}1'`;do git push origin --delete $branch; done
Run Code Online (Sandbox Code Playgroud)
这将过滤 grep 管道中的任何给定分支。
在 http 克隆上运行良好,但对于 ssh 连接效果不佳。
接受的解决方案非常好,但有一个问题,它还会删除尚未合并到远程的本地分支。
如果你看一下你的输出,你会看到类似的东西
$ git branch --merged master -v
api_doc 3a05427 [gone] Start of describing the Java API
bla 52e080a Update wording.
branch-1.0 32f1a72 [maven-release-plugin] prepare release 1.0.1
initial_proposal 6e59fb0 [gone] Original proposal, converted to AsciiDoc.
issue_248 be2ba3c Skip unit-for-type checking. This needs more work. (#254)
master be2ba3c Skip unit-for-type checking. This needs more work. (#254)
Run Code Online (Sandbox Code Playgroud)
分支bla
和issue_248
是将被静默删除的本地分支。
但是您也可以看到单词[gone]
,它表示已推送到远程(现在已消失)的分支,因此表示可以删除分支。
因此可以将原始答案更改为(拆分为多行以缩短行长)
git branch --merged master -v | \
grep "\\[gone\\]" | \
sed -e 's/^..//' -e 's/\S* .*//' | \
xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
保护尚未合并的分支。此外,不需要 master 的 grepping 来保护它,因为它在原点有一个遥控器并且不会显示为消失。
归档时间: |
|
查看次数: |
496194 次 |
最近记录: |