从git中清除冗余分支

时间:2014-02-24 08:38:33

标签: git version-control github branching-and-merging git-pull

这是一个场景:有人有一个git存储库(在github上,如果重要的话),我已经分叉了。在我的分支机构中,我创建了许多分支,其中包含上游已经提取的更改。或者在某些情况下应用我的分支的差异而不是正确拉动分支。

我想要找到的是已完全合并到上游主分支的所有分支的列表。这样我就可以安全地删除那些分支,因为git branch和其他工具列出了30多个分支,它看起来很杂乱。

我认为我已经正确解释了为什么这个问题与链接的问题有所不同:或者在某些情况下应用了我的分支的差异,而不是正确拉动分支,例如git branch --merged不是一个完整的答案,但很好......

2 个答案:

答案 0 :(得分:4)

根据您希望的频率,您可能需要手动完成(首先说明)或编写脚本(之后解释)。

在下面假设有一个“上游”遥控器指向您分叉的复制品,例如:

$ git remote -v
origin git@github.com:you/repo.git (fetch)
origin git@github.com:you/repo.git (push)
upstream git://github.com/original/repo.git (fetch)
upstream git://github.com/original/repo.git (push)

列出合并的所有本地分支

获取已与上游主服务器合并的分支列表:

$ git fetch upstream
$ git branch --merged upstream/master
my-feature
my-other-feature
master

然后您可以删除它们:

$ git branch -d my-feature
$ git branch -d my-other-feature

如果手动应用更改,则它们可能不在上游历史记录中,因此可能不会列出具有等效代码更改的本地分支。应该手动检测出这种情况的分支。

删除对不存在的远程分支的本地引用

如果你有本地分支代表一个已被删除的远程分支(该分支用于拉取请求,并且在合并拉取请求后通过github的gui删除了分支),则有一个标准的git命令用于清理这些分支参考:

$ git remote prune origin

删除已合并的远程分支

要获取已合并的fork中的远程分支列表,与第一个命令类似 - 但使用-r开关(远程分支):

$ git branch -r --merged upstream/master
origin/my-feature
origin/my-other-feature
upstream/someone-elses-branch

删除已合并的自己的远程分支:

$ git push origin :my-feature
$ git push --delete origin my-other-feature # equivalent, just different syntax

脚本解决方案

小心使用脚本化解决方案,因为很容易意外删除您不想要的分支。也就是说,记住分支只是引用/名称 - 删除分支(意外)并不意味着内容丢失,它们很容易被恢复(例如,只需检查git reflog)。

以下脚本删除以“feature”开头的本地和远程分支 - 这是确保您自己的最新master分支的一种方法,例如,不会被意外删除。

#!/bin/bash
# E.g. save as ~/bin/git-cleanup, make executable and have ~/bin in your path
# call as `git cleanup`

echo -n "Fetching latest ... "
git fetch origin
git fetch upstream
echo "done"

echo "Deleting merged local feature branches ... "
branches=`git branch --no-color --merged upstream/master`
for branch in $branches;
do
    if [[ "$branch" =~ ^feature ]]; then
        git branch -d $branch;
    fi
done
echo "done"

echo "Deleting local refs to remote branches that don't exist ... "
git remote prune origin
git remote prune upstream
echo "done"

echo "Deleting merged remote feature and hotfix branches ... "
branches=`git branch -r --no-color --merged upstream/master`
for branch in $branches;
do
    if [[ "$branch" =~ ^(origin)\/(feature.*$) ]]; then
        remote=${BASH_REMATCH[1]};
        branch=${BASH_REMATCH[2]};
        git push $remote :$branch;
    fi
done

echo "done"

echo ""
echo "all finished"

答案 1 :(得分:1)

如果您使用上游仓库(您已经分叉的仓库)的最新提交更新了您的分支,则可以按照“How can I delete all git branches which are already merged?”。

git branch --merged | grep -v "\*" | xargs -n 1 git branch -d 

但是这只会列出合并的分支(例如通过拉请求),而不是挑选(当只有一个分支的差异应用于另一个分支时)。

对于第二类,您可能必须区分这些本地分支,看看它们是否仍然存在不属于主分支的差异。