我有很多 Git 分支。如何删除已经合并过的分支?有没有一种简单的方法来删除它们,而不是一个一个地删除它们?
更新。
如果你的工作流程中有可能的祖先,你可以添加其他分支来排除,比如master和dev。通常情况下,我从"sprint-start"标签分支,master、dev和qa都不是祖先。
首先,列出所有被远程合并的分支。
git branch --merged
你可能会看到一些你不想删除的分支。我们可以添加一些参数来跳过我们不想删除的重要分支,如master或develop。下面的命令将跳过master分支和任何含有dev的分支。
git branch --merged| egrep -v "(^\*|master|dev)"
如果你想跳过,可以像下面这样在egrep命令中添加它。分支 skip_branch_name
将不会被删除。
git branch --merged| egrep -v "(^\*|master|dev|skip_branch_name)"
要删除所有已经合并到当前签出分支的本地分支。
git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
你可以看到,master和dev被排除在外,因为它们是一个祖先。
你可以用以下方法删除一个合并的本地分支。
git branch -d branchname
如果它没有被合并,可以用。
git branch -D branchname
在旧版本的Git中,要从远程端删除它,请使用。
git push origin :branchname
在较新版本的Git中使用
git push --delete origin branchname
一旦你从远端删除了分支,你可以用修剪来摆脱远端跟踪分支。
git remote prune origin
或者像其他答案所建议的那样,用以下方法修剪单个远程跟踪分支。
git branch -dr branchname
希望这有帮助。
删除远程上所有已经合并的分支。
git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin
在Git的最新版本中
git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin
更新(由@oliver。 因为不适合放在评论里,但已经有足够的答案了)。) 如果你在分支ABC上,那么ABC将出现在`git branch -r --merged'的结果中,因为没有指定分支,所以分支默认为当前分支,而分支总是符合合并到自己的条件(因为分支和自己之间没有区别!)。
所以要么指定分支。
git branch -r --merged master | grep -v master ...
或第一结账高手。
git checkout master | git branch -r --merged | grep -v ...
你要从这些命令中排除 "master"&. "develop "分支。
develop
分支从这些命令中排除。
本地 git 清除。
git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d
远程git清除。
git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin
同步远程分支机构的本地注册表。
git fetch -p
对于那些在Windows上使用PowerShell脚本的用户,这里有一个删除本地合并分支的脚本。
function Remove-MergedBranches
{
git branch --merged |
ForEach-Object { $_.Trim() } |
Where-Object {$_ -NotMatch "^\*"} |
Where-Object {-not ( $_ -Like "*master" )} |
ForEach-Object { git branch -d $_ }
}
我'年来一直使用亚当'的答案。 说,那有一些情况下,它并没有像我预期的那样表现。
含有""dev". "一词的分支被忽略。 的分支被忽略,例如 而不是只忽略dev分支。
删除从当前分支的头部可以到达的分支(即不一定是主分支)。
在分离的HEAD状态下,删除当前提交所能到达的*个分支。
1 &
2是直接解决的,只需修改一下regex。
3 取决于你想要的上下文(例如
只删除没有被合并到master或针对你当前分支的分支)。)
4 有可能会造成灾难性的后果(虽然可以用git reflog
恢复),如果你无意中在分离的head状态下运行这个。
最后,我希望这一切都在一个单行本中,不需要单独的(Bash|Ruby|Python)脚本。
创建一个 git 别名 "sweep"
接受一个可选的-f
标志。
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
并调用它与。
git sweep
或。
git sweep -f
对我来说,最简单的方法是创建一个包含一些分支和提交的git repo来测试正确的行为。
mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"
git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
吧
发展 foo
- 主体
精湛
非主人
选择所有合并的分支,除了: 主分支、开发分支或*当前分支
原始的regex错过了分支"masterful"。 和"notmaster"。 :
git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
吧
使用更新的regex(现在排除了"develop" 而不是"dev")。)
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
吧
娴熟 gt;不是主人
echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"
我当前的分支是foobar,如果我重新运行上面的命令来列出我想删除的分支,分支"foo" 分支被包括在内,尽管它还没有被合并到主分支中。
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
吧
foo
精湛
非主人
但是,如果我在master上运行同样的命令,分支"foo" 分支没有被包含。
git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
吧
精湛
非主人
这只是因为git branch --merged
默认为当前分支的head,如果没有另外指定的话。
至少在我的工作流程中,我不想删除本地分支,除非它们已经被合并到主分支,所以我更喜欢下面的变体。
git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
吧
精湛
非主人
在分离的HEAD状态下,依赖git branch --merged
的默认行为会产生更严重的后果。
git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
吧
foo foobar
精湛
非主人
这将会删除我刚才所在的分支,"foobar"。 和"foo"一起删除,这几乎肯定不是我们想要的结果。 不过,随着我们修改后的命令。
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
吧
精湛
非主人
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
别名接受一个可选的-f
标志。
默认的行为是只删除已经合并到master的分支,但是-f
标志会删除已经合并到当前分支的分支。
git sweep
删去分支栏(原为9a56952)。 >.删除了分支 "精通"(原为9a56952)。 删除分支 "高手"(原为9a56952)。 删除分支notmaster(原为9a56952)。 删除分支notmaster(原为9a56952)。
git sweep -f
>.删除分支foo(原为2cea1ab)。 删除分支foo(原为2cea1ab)。
你可以在 --merged 选项中加入提交。 这样你就可以确保只删除合并到的分支,例如 的分支。
下面的命令将从您的原点删除合并的分支。
git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete
你可以用echo替换git push origin --delete来测试哪些分支会被删除。
git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
我使用下面的 Ruby 脚本来删除已经合并的本地和远程分支。如果我为一个有多个远程的版本库做这件事,而只想从其中一个删除,我只需在远程列表中添加一个选择语句,就可以只得到我想要的远程。
#!/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
git branch --merged | %{git branch -d $_.Trim()}
如果你想排除master或其他分支名,你可以用PowerShell的Select-String管子,像这样,然后把结果传给git branch -d
。
git branch -d $(git branch --merged | Select-String -NotMatch "master"
|%{$_.ToString().Trim()})
在Git中没有任何命令可以自动为你做这些事情。但你可以写一个脚本,使用Git命令来提供你需要的东西。这可以通过多种方式实现,取决于你所使用的分支模型。
如果你需要知道一个分支是否被合并到主干中,如果myTopicBranch已经被合并,下面的命令将不会产生任何输出(也就是说,你可以删除它
$ git rev-list master | grep $(git rev-parse myTopicBranch)
你可以使用Git分支命令,在Bash中解析出所有分支,并在所有分支上做一个for
循环。在这个循环中,你用上述命令检查是否可以删除该分支。