是否有一种简单的方法可以删除所有远程对等分支不再存在的跟踪分支?
例子:
分支机构(本地和远程)
主人原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c
在本地,我只有一个主分支。现在我需要处理bug-fix-a,所以我检查它,处理它,并将更改推到远程。接下来,我对bug-fix-b做同样的操作。
分支机构(本地和远程)
主人bug-fix-abug-fix-b型原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c
现在我有本地分支机构master,bug-fix-a,bug--fix-b。主分支维护者将把我的更改合并到主分支中,并删除他已经合并的所有分支。
因此,当前状态为:
分支机构(本地和远程)
主人bug-fix-abug-fix-b型原始/主起源/bug-fix-c
现在我想调用一些命令来删除分支(在本例中为bug-fix-a、bug-fix-b),这些分支在远程存储库中不再表示。
它类似于现有命令git remote prune origin,但更类似于git local prune origin。
我在这里找到了答案:如何删除所有已合并的git分支?
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
确保我们留住主人
您可以通过在第一个grep之后添加另一个grep来确保master或其他分支不会被删除。在这种情况下,您可以:
git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d
因此,如果我们想保持主控、开发和登台,我们会:
git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d
将此设置为别名
由于它有点长,您可能需要在.zshrc或.bashrc中添加别名。我的别名称为gbpurge(用于git分支清除):
alias gbpurge='git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d'
然后重新加载.bashrc或.zshrc:
. ~/.bashrc
or
. ~/.zshrc
我认为没有内置命令来执行此操作,但可以安全地执行以下操作:
git checkout master
git branch -d bug-fix-a
当您使用-d时,git将拒绝删除分支,除非它完全合并到HEAD或其上游远程跟踪分支中。因此,您可以始终循环每个ref的git输出,并尝试删除每个分支。这种方法的问题是,我怀疑您可能不希望因为origin/bug-fix-d包含其历史而删除bug--fix-d。相反,您可以创建如下脚本:
#!/bin/sh
git checkout master &&
for r in $(git for-each-ref refs/heads --format='%(refname:short)')
do
if [ x$(git merge-base master "$r") = x$(git rev-parse --verify "$r") ]
then
if [ "$r" != "master" ]
then
git branch -d "$r"
fi
fi
done
警告:我尚未测试此脚本-请小心使用。。。
这将删除本地不存在的所有远程分支(在ruby中):
bs = `git branch`.split; bs2 = `git branch -r | grep origin`.split.reject { |b| bs.include?(b.split('/')[1..-1].join('/')) }; bs2.each { |b| puts `git push origin --delete #{b.split('/')[1..-1].join('/')}` }
解释:
# local branches
bs = `git branch`.split
# remote branches
bs2 = `git branch -r | grep origin`.split
# reject the branches that are present locally (removes origin/ in front)
bs2.reject! { |b| bs.include?(b.split('/')[1..-1].join('/')) }
# deletes the branches (removes origin/ in front)
bs2.each { |b| puts `git push origin --delete #{b.split('/')[1..-1].join('/')}` }
我已经用GitPython编写了一个Python脚本来删除远程不存在的本地分支。
import git
import subprocess
from git.exc import GitCommandError
import os
def delete_merged_branches():
current_dir = input("Enter repository directory:")
repo = git.Repo(current_dir)
git_command = git.Git(current_dir)
# fetch the remote with prune, this will delete the remote references in local.
for remote in repo.remotes:
remote.fetch(prune=True)
local_branches = [branch.name for branch in repo.branches]
deleted_branches = []
# deleted_branches are the branches which are deleted on remote but exists on local.
for branch in local_branches:
try:
remote_name = 'origin/'+ branch
repo.git.checkout(remote_name)
except GitCommandError:
# if the remote reference is not present, it means the branch is deleted on remote.
deleted_branches.append(branch)
for branch in deleted_branches:
print("Deleting branch:"+branch)
git_command.execute(["git", "branch", "-D",branch])
# clean up the work flow.
repo.git.checkout('master')
repo.git.pull()
if __name__ == '__main__':
delete_merged_branches()
希望有人觉得它有用,如果我错过了什么,请添加评论。