如何删除所有已合并的 Git 分支?

问:

我有很多 Git 分支。如何删除已经合并的分支?有没有一种简单的方法可以将它们全部删除而不是一个一个删除?

答1:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

更新:

如果您的工作流将这些分支作为可能的祖先,您可以添加其他分支以排除,例如 master 和 dev。通常我从“sprint-start”标签分支出来,master、dev 和 qa 不是祖先。

首先,列出在远程合并的本地跟踪分支(您可以考虑使用 -r 标志列出所有远程跟踪分支,如其他答案中所建议的那样)。

git branch --merged

您可能会看到一些您不想删除的分支。我们可以添加一些参数来跳过我们不想删除的重要分支,例如 master 或 develop。以下命令将跳过 master 分支以及其中包含 dev 的任何内容。

git branch --merged| egrep -v "(^\*|master|main|dev)"

如果要跳过,可以将其添加到 egrep 命令中,如下所示。不会删除分支 skip_branch_name。

git branch --merged| egrep -v "(^\*|master|main|dev|skip_branch_name)"

删除所有已合并到当前签出分支的本地分支:

git branch --merged | egrep -v "(^\*|master|main|dev)" | xargs git branch -d

您可以看到 master 和 dev 被排除在外,以防它们是祖先。

您可以使用以下命令删除合并的本地分支:

git branch -d branchname

如果未合并,请使用:

git branch -D branchname

要从远程使用中删除它:

git push --delete origin branchname

git push origin :branchname    # for really old git

从远程删除分支后,您可以通过以下方式修剪以摆脱远程跟踪分支:

git remote prune origin

或修剪单个远程跟踪分支,正如另一个答案所暗示的那样,使用:

git branch -dr branchname

警告:如果您刚刚创建了一个分支,它也会删除该分支。在运行最上面的命令之前,请确保列表中没有新创建的分支。

与警告相反:reflog 会保存你的培根。所以不用担心。

请记住,第一个命令仅删除本地分支,因此它不像某些人指出的那样“危险”。

PowerShell 变体,以便下次我搜索答案时可以在这里找到它:git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_}

如果您没有应删除的分支,则会产生错误 fatal: branch name required。为避免这种情况,您可以将 -r 传递给 xargs,这样如果 stdin 为空,它就不会运行 git branch -d。 (根据手册页,这是一个 GNU xargs 扩展)。

答2:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

要删除远程上已合并的所有分支:

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 ...

迄今为止最好的答案。请注意,我的主分支名为 dev,所以我必须更改它

我必须在 grep -v master 之后添加 | grep origin 以防止将其他遥控器的分支推送到原点。强烈建议使用 git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo 事先测试输出

我也稍作修改以排除 develop 分支。 git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin。现在这竟然是我的别名。

使这成为我读过的最佳答案的原因是 -r 论点,我在其他任何地方都没有提到过。人们理所当然地认为,只有当地的分支机构才值得做一些家务。但是遥控器也充满了垃圾。

注意 - 刚刚意识到:这显然会发现分支合并到 当前分支,而不是主分支,因此如果您在 myFeatureBranch 上,它将擦除 origin/myFeatureBranch。可能最好先git checkout master。

答3:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

只是扩展亚当的答案一点:

通过运行 git config -e --global 将其添加到您的 Git 配置中

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 -r git branch -d"

然后您可以通过简单的 git cleanup 删除所有本地合并的分支。

第一个命令不应该是:git branch --merged master,因为您想查看已合并到 master 中的内容,而不是当前已签出的分支?

@JoePhilllips 有些人的主分支不是主分支,而是 develop 或 dev,在这种情况下,命令将因 fatal: malformed object name 而失败,最好有一个通用命令,您有责任运行它

@JoePhilllips 这个答案的重点是将亚当的答案(这个问题的最佳答案)打包成有用的 git 别名。亚当的回答没有你的建议,很多人发现这很有用,所以我倾向于不改变我的。如果您对此有强烈的感觉,我建议您开始讨论亚当的答案

将 -r 添加到 xargs 将防止在多次运行此别名或没有要删除的分支时出现不必要的错误 (branch name required)。我的别名如下所示:cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d"

当前命令不会过滤掉 master 和 development 分支

答4:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

您需要排除 master、main 和develop 这些命令的分支。

本地 git 清除:

git branch --merged | grep -v '\*\|master\|main\|develop' | xargs -n 1 git branch -d

远程 git 清除:

git branch -r --merged | grep -v '\*\|master\|main\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin

同步远程分支的本地注册表:

git fetch -p

+1 也适用于远程版本(但由于我们有远程 --prune,所以需要较少)。还值得注意的是,这些不适用于较旧的 git 版本

git config --global --add fetch.prune true 在获取或拉取时自动修剪。

请注意,修剪与远程清除不同。远程清除实际上删除了与您当前分支完全合并的远程分支。 Prune 仅清理已删除的远程分支的本地注册表。

完全这个词有点误导,因为一个分支将被认为是合并的,当它之前被合并时,但在合并之后有新的提交,这些提交没有被合并。

为了在一次调用中删除所有原始遥控器,我使用了这个:git branch -r --merged | grep -v '\*\|master\|develop' | grep '^\s*origin/' | sed 's/origin\///' | tr "\n" " " | xargs git push --delete origin

答5:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

这也适用于删除除 master 之外的所有合并分支。

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d

现在它不会删除任何包含 master 的分支。尝试 grep -v ^master$ 作为中间。

如果您不在 master 上,我也会让 | grep -v '^\*' 避免删除当前分支

这太好了,谢谢!任何人使用它的一个警告:请注意 grep -v '^ master$' 中有两个空格。如果您自己输入并漏掉了一个,如果您不在上面,您将删除 master。

@Mr.Polywhirl 你的编辑破坏了命令,你应该恢复它。这两个空格是必需的,因为如果不是当前签出的分支,git branch 将在新行中列出每个分支名称,并在左侧有两个空格。您基本上保证了运行此命令的任何人都会删除他们的主分支,除非它是当前签出的分支。

答6:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

对于那些在 Windows 上并且更喜欢 PowerShell 脚本的人,这里有一个删除本地合并分支的脚本:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object { $_ -NotMatch "^\*" } |
    Where-Object { -not ( $_ -Like "*master" -or $_ -Like "*main" ) } |
    ForEach-Object { git branch -d $_ }
}

或简短版本:

git branch --merged | %{$_.trim()}  | ?{$_ -notmatch 'dev' -and $_ -notmatch 'master' -and $_ -notmatch 'main'} | %{git branch -d $_.trim()}

出于好奇,这可以缩短为 git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()}

@IainBallard 当然,我可以使用别名。当您想最大限度地提高可读性时,不建议这样做。 github.com/darkoperator/PSStyleGuide/blob/master/English.md

当然。我发现您的回答非常有帮助 :-) 但是,有时长格式的 powershell 语法会妨碍块中发生的事情。但主要是,我提出了一些您可以一次性复制/粘贴或键入的内容。再次感谢。

这是一个用于 Windows cmd shell 的单行代码,它保留了 master 和您当前的分支:for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %B(叹气,用单引号替换双反引号,我不知道如何格式化包含反引号的文字)

答7:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

我多年来一直使用亚当的答案。也就是说,在某些情况下它的行为并不像我预期的那样:

包含单词“master”的分支被忽略,例如“notmaster”或“masterful”,而不仅仅是包含单词“dev”的master分支被忽略,例如“dev-test”,而不仅仅是dev分支删除从当前分支的 HEAD 可到达的分支(即不一定是 master)处于分离 HEAD 状态,删除从当前提交可到达的每个分支

1& 2 很容易解决,只需更改正则表达式。 3 取决于您想要的上下文(即仅删除尚未合并到主分支或当前分支的分支)。如果您无意中以分离的 HEAD 状态运行它,则 4 可能会造成灾难性的后果(尽管可以使用 git reflog 恢复)。

最后,我希望这一切都在一个不需要单独的(Bash|Ruby|Python)脚本的单行程序中。

TL;博士

创建一个接受可选 -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'

并调用它:

git sweep

或者:

git sweep -f

长而详细的答案

对我来说,创建一个带有一些分支和提交的示例 git repo 来测试正确的行为是最简单的:

使用单个提交创建一个新的 git 存储库

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 * 高手 高手 非大师

期望的行为:选择所有合并的分支,除了:master、develop 或 current

原来的正则表达式错过了分支“masterful”和“notmaster”:

git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"

酒吧

使用更新的正则表达式(现在不包括“develop”而不是“dev”):

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"

酒吧大师

切换到分支 foo,进行新的提交,然后签出一个基于 foo 的新分支 foobar:

echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"

我当前的分支是 foobar,如果我重新运行上面的命令来列出我要删除的分支,即使它还没有合并到 master 中,分支“foo”也会被包括在内:

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"

bar foo masterful notmaster

但是,如果我在 master 上运行相同的命令,则不包括分支“foo”:

git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"

酒吧大师

这仅仅是因为 git branch --merged 如果没有另外指定,则默认为当前分支的 HEAD。至少对于我的工作流程,我不想删除本地分支,除非它们已合并到主分支,所以我更喜欢以下变体 using git rev-parse:

git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"

酒吧大师

分离的 HEAD 状态

依赖 git branch --merged 的默认行为在分离 HEAD 状态下会产生更严重的后果:

git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"

bar foo foobar 高超的 notmaster

这将删除我刚才所在的分支,“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 别名“sweep”:

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)。删除了 masterful 分支(原为 9a56952)。删除了分支 notmaster(原为 9a56952)。

git sweep -f

删除了分支 foo(原为 2cea1ab)。

为什么需要创建函数? git config 不是原子的吗?

处理可选的“-f”参数(如果我正确理解您的问题)

但它有什么帮助?我的意思是表达式的开头,!f(){ git branch ...。这是一个函数声明,对吧?为什么不直接从 git branch ... 开始?

你是绝对正确的。相应地编辑了我的答案。谢谢指点!

以下内容与非强制模式不一样吗? git checkout master && git branch -d git branch --merged && git checkout - 除了它会删除 develop,但可能是一种更简单的方法。

答8:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

Git Sweep 在这方面做得很好。

现在,这个项目不再维护。请参阅github.com/arc90/git-sweep/pull/43

答9:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

使用 Git 2.5.0 版:

git branch -d `git branch --merged`

这可以删除 master 分支顺便说一句!

真的。我只在确定自己在 master 上时才使用它。

git branch -d $(git branch --merged | grep -v master)

如果您有流程,这很危险,假设您有 master <- stage <- dev。还是最简单的解决方案imo

这会删除当前用户或任何用户合并的所有分支吗?

答10:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

如果您使用的是 Windows,则可以使用带有 Out-GridView 的 Windows Powershell 或 Powershell 7 来获得一个不错的分支列表,然后用鼠标选择要删除的分支:

git branch --format "%(refname:short)" --merged  | Out-GridView -PassThru | % { git branch -d $_ }

https://i.stack.imgur.com/78H7G.png

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

答11:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

您可以将提交添加到 --merged 选项。这样,您可以确保只删除合并到的分支,即源/主

以下命令将从您的来源中删除合并的分支。

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

您可以测试将删除哪些分支,将 git push origin --delete 替换为 echo

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo

我喜欢测试选项

原文链接:https://www.huntsbot.com/qa/6LXW/how-can-i-delete-all-git-branches-which-have-been-merged?lang=zh_CN&from=csdn

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值