自从 GitHub 引入Squash 和 Merge以来,我工作场所的所有酷孩子在合并拉取请求时都在使用它。有没有办法清理“Squash and Merge”分支?
以下命令来自如何删除所有已合并的 git 分支?不适用于“Squash and Merge”:
git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
自从 GitHub 引入Squash 和 Merge以来,我工作场所的所有酷孩子在合并拉取请求时都在使用它。有没有办法清理“Squash and Merge”分支?
以下命令来自如何删除所有已合并的 git 分支?不适用于“Squash and Merge”:
git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
这是一个脚本,它将删除所有已被 squash 合并到 master 的本地分支:
git checkout -q master && git for-each-ref refs/heads/ "--format=%(refname:short)" | while read branch; do mergeBase=$(git merge-base master $branch) && [[ $(git cherry master $(git commit-tree $(git rev-parse "$branch^{tree}") -p $mergeBase -m _)) == "-"* ]] && git branch -D $branch; done
如果你想运行一个空运行,你可以运行这个:
git checkout -q master && git for-each-ref refs/heads/ "--format=%(refname:short)" | while read branch; do mergeBase=$(git merge-base master $branch) && [[ $(git cherry master $(git commit-tree $(git rev-parse "$branch^{tree}") -p $mergeBase -m _)) == "-"* ]] && echo "$branch is merged into master and can be deleted"; done
然后,您可以像这样设置别名:
alias gprunesquashmerged='git checkout -q master && git for-each-ref refs/heads/ "--format=%(refname:short)" | while read branch; do mergeBase=$(git merge-base master $branch) && [[ $(git cherry master $(git commit-tree $(git rev-parse "$branch^{tree}") -p $mergeBase -m _)) == "-"* ]] && git branch -D $branch; done'
资源:
没有简单的方法可以自动化,至少不能完全自动化。(可以处理一些特殊情况。)相反,最好的办法是将此分支删除委托给拉取请求已被压缩合并的人。有几个很好的理由:
他们是唯一可以确保合并正确完成的人。
例如,假设为了 squash-merge 一系列六个提交,进行 squash-merge 的人必须或选择在一两行的某处更改几个字符,出于某种原因是好是坏. 那一行或两行意味着最终提交中的整体更改与六次提交中六次更改的总和不同。
但总体结果正确吗? 如果您自己没有进行任何更改,您怎么知道?
他们是唯一知道他们是否打算继续在该分支上开发的人。
仅仅因为六个提交feature/tall
被压缩为一个提交添加devel
并不意味着这feature/tall
一切都完成了。他们可能还要添加几个提交;他们可能想要再次变基feature/tall
,devel
放弃六个压缩提交以支持一个六提交-壁球,但保留他们即将添加的另外三个提交。
可能还有更多的案例。这些可能都很罕见;它们可能永远不会出现在您的项目中;但这里的重点是分支feature/tall
是他们的分支,而不是你的分支,所以他们——不管他们是谁——应该是在完成后删除它的人。
请注意,当您拿起时,feature/tall
您有自己的 Git 将其重命名为origin/feature/tall
(假设您的遥控器名为origin
)。如果您正在试验它,并且git checkout feature/tall
,您的 Git 会为您制作一个副本。一旦他们删除feature/tall
并且你运行git fetch origin --prune
,你的 Git 就会删除你的origin/feature/tall
. 所以现在问题更简单并且可以自动化:找到“上游”消失的分支,并删除那些. (这个答案中的单行脚本有一些小缺陷;请参阅评论;更高级的人会使用git for-each-ref
并使用 查找每个分支的上游设置git rev-parse
,但这可能有点矫枉过正。)
工具git-delete-merged-branches允许方便地删除分支。我特别喜欢交互模式。
安装(需要python3
):
pip install git-delete-merged-branches
然后执行
git-delete-merged-branches --effort=3 --branch main
--effort=3
对于删除压扁的分支很重要。--branch main
是必需的(否则master
使用)npx @teppeis/git-delete-squashed
。支持main
分支。main
缺少分支的功能.. @teppeis/git-delete-squashed 基于此。如果您更喜欢带有 TUI(基于文本的用户界面)的交互式工具,我编写了一个名为 git xcleaner 的工具。它可以找到合并的分支、重新定位的分支(使用相同的提交消息提交)、修剪的分支或手动选择的分支。
这篇文章中的答案也很有用https://medium.com/opendoor-labs/cleaning-up-branches-with-githubs-squash-merge-43138cc7585e
稍作调整以允许任何来源名称并防止删除流行的分支我使用这个:
git fetch --all
REMOTE=$(git remote)
comm -12 <(git branch | sed 's/ *//g') \
<(git remote prune $REMOTE | sed 's/^.*$REMOTE//g') \
| grep -v -e main -e master -e develop \
| xargs -L1 -J % git branch -D %