不再在远程删除本地分支机构
有没有简单的方法来删除所有没有远程等效的本地分支机构?
例:
分支(本地和远程)
- 主
- 产地/主
- 产地/漏洞修复,一个
- 产地/漏洞修复-B
- 产地/漏洞修复-C
本地,我只有一个主分支。 现在我需要处理bug-fix-a ,所以我检查一下,处理它,然后将更改推送到远程。 接下来,我也使用bug-fix-b 。
分支(本地和远程)
- 主
- 漏洞修复,一个
- 漏洞修复-B
- 产地/主
- 产地/漏洞修复,一个
- 产地/漏洞修复-B
- 产地/漏洞修复-C
现在我有本地分支主 , bug-fix-a , bug-fix-b 。 主分支维护人员将我的更改合并到主,并删除他已经合并的所有分支。
所以现在的状态是:
分支(本地和远程)
- 主
- 漏洞修复,一个
- 漏洞修复-B
- 产地/主
- 产地/漏洞修复-C
现在我想调用一些命令来删除远程仓库中不再显示的分支(这里是bug-fix-a , bug-fix-b )。
这将是像现有的命令git remote prune origin
,但更像git local prune origin
。
git remote prune origin
跟踪不在远程的分支。
git branch --merged
列表已被合并到当前分支的分支。
xargs git branch -d
删除标准input中列出的分支。
小心删除由git branch --merged
列出的git branch --merged
。 该列表可以包括您不希望删除的master
或其他分支。
为了让自己有机会在删除分支之前编辑列表,您可以在一行中执行以下操作:
git branch --merged >/tmp/merged-branches && vi /tmp/merged-branches && xargs git branch -d </tmp/merged-branches
在命令之后
git fetch -p
删除远程引用,当你运行
git branch -vv
它会显示'已经'作为远程状态。 例如,
$ git branch -vv master b900de9 [origin/master: behind 4] Fixed bug release/v3.8 fdd2f4e [origin/release/v3.8: behind 2] Fixed bug release/v3.9 0d680d0 [origin/release/v3.9: behind 2] Updated comments bug/1234 57379e4 [origin/bug/1234: gone] Fixed bug
所以你可以写一个简单的脚本来删除远程的本地分支:
git fetch -p && for branch in `git branch -vv | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
这些答案中的大部分(包括前6名中的5个)实际上并没有回答原来的问题。 我看了一堆线程, 这个答案似乎是最干净的。 这是一个稍微更彻底的答案:
git fetch -p && git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
说明:
通过修剪您的跟踪分支,然后删除显示他们在git branch -vv
“走出去”的本地。
笔记:
只有本地的分支不会被触及。 已在远程删除但未合并的分支将显示通知,但不会在本地删除。 如果你想删除这些以及将-d
改为-D
。
似乎解决scheme在这里 – https://stackoverflow.com/a/1072178/133986
简而言之, git remote prune
做到这一点
我在这里find了答案: 如何删除已合并的所有git分支?
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
确保我们保持主人
您可以确保master
或任何其他分支在第一个之后添加另一个grep
不会被删除。 在这种情况下,你会去:
git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d
所以,如果我们想保持master
, develop
和staging
,我们会去:
git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d
使这个别名
由于时间有点长,您可能需要为您的.zshrc
或.bashrc
添加一个别名。 我叫gbpurge
( git branches purge
):
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
要么
. ~/.zshrc
删除所有已经合并到master中的分支,但不要尝试删除master本身:
git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)
或者添加一个别名:
alias gitcleanlocal="git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)"
说明:
git checkout master
结帐主分支
git pull origin master
确保本地分支已将所有远程更改合并
git fetch -p
删除对已被删除的远程分支的引用
git branch -d $(git branch master --merged | grep master -v)
删除已经合并到master的所有分支,但是不要尝试删除master本身
git fetch -p
这将删除所有未被远程跟踪的分支。
我不认为有一个内置的命令来做到这一点,但是可以安全地执行以下操作:
git checkout master git branch -d bug-fix-a
当你使用-d
,git会拒绝删除分支,除非它被完全合并到HEAD
或其上游的远程跟踪分支中。 所以,你总是可以遍历git for-each-ref
的输出,并尝试删除每个分支。 这种方法的问题是,我怀疑你可能不希望bug-fix-d
被删除,只是因为origin/bug-fix-d
包含它的历史logging。 相反,你可以创build一个如下所示的脚本:
#!/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
警告:我还没有testing过这个脚本 – 只能谨慎使用…
这将删除除本地主引用和当前正在使用的所有合并的本地分支:
git branch --merged | grep -v "*" | grep -v "master" | xargs git branch -d
这将删除已经从“ origin ”引用的远程存储库中删除的所有分支,但仍在本地“ remotes / origin ”中可用。
git remote prune origin
根据以上信息,这对我工作:
git br -d `git br -vv | grep ': gone] ' | awk '{print $1}' | xargs`
它在远程删除所有本地分支': gone] '
。
我不知道多久,但我现在使用git-up,这是照顾的。
我做git up
,它开始跟踪新的分支机构,并删除旧的。
只是要说清楚,这不是开箱即用的git命令 – https://github.com/aanand/git-up
顺便说一句,它也存储了肮脏的树,并使基地刚刚git up
。
希望这会对某人有用
我想出了这个bash脚本。 它始终保持分支的develop
, qa
, master
。
git-clear() { git pull -a > /dev/null local branches=$(git branch --merged | grep -v 'develop' | grep -v 'master' | grep -v 'qa' | sed 's/^\s*//') branches=(${branches//;/ }) if [ -z $branches ]; then echo 'No branches to delete...' return; fi echo $branches echo 'Do you want to delete these merged branches? (y/n)' read yn case $yn in [^Yy]* ) return;; esac echo 'Deleting...' git remote prune origin echo $branches | xargs git branch -d git branch -vv }
这是我用于鱼壳的解决scheme。 testing在Mac OS X 10.11.5
, fish 2.3.0
和git 2.8.3
。
function git_clean_branches set base_branch develop # work from our base branch git checkout $base_branch # remove local tracking branches where the remote branch is gone git fetch -p # find all local branches that have been merged into the base branch # and delete any without a corresponding remote branch set local for f in (git branch --merged $base_branch | grep -v "\(master\|$base_branch\|\*\)" | awk '/\s*\w*\s*/ {print $1}') set local $local $f end set remote for f in (git branch -r | xargs basename) set remote $remote $f end for f in $local echo $remote | grep --quiet "\s$f\s" if [ $status -gt 0 ] git branch -d $f end end end
一些注意事项:
确保设置正确的base_branch
。 在这种情况下,我使用develop
作为基本分支,但它可以是任何东西。
这部分是非常重要的: grep -v "\(master\|$base_branch\|\*\)"
。 它确保您不会删除主人或您的基本分支。
我使用git branch -d <branch>
作为额外的预防措施,以便不删除任何尚未与上游或当前HEAD完全合并的分支。
一个简单的方法来testing是用echo "will delete $f"
replacegit branch -d $f
echo "will delete $f"
。
我想我也应该补充一点:使用你自己的风险!
我使用这种方法,所以我可以有更多的控制。
git branch -D $(git branch | grep -v "master" | grep -v "develop")
这是删除没有命名的任何分支: master
或develop
。
这是要删除所有不在本地的远程分支(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('/')}` }