自从 GitHub 推出 Squash 和 Merge 以来,我工作场所的所有酷孩子都在合并拉取请求时使用它。有没有办法清理“挤压和合并”分支?
来自如何删除所有已合并的 git 分支?的以下命令不适用于“挤压和合并”:
git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
这是一个脚本,它将删除所有已被压缩合并到 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'
来源:
更新 (2023-11-30)
git-town prune-branches
从 v10.0.0 开始已停止使用,变更日志现在建议运行 git-town sync
。
更新 该工具
git-delete-merged-branches
对我来说效果不太好。我现在推荐git-town prune-branches
。
工具 git-town 提供 prune-branches:
git-town prune branches
然后它会请求主开发分支。您需要选择您的
main
或 master
分支:
Git Town needs to be configured
? Please specify the main development branch: main
然后要求保留“常年”枝,即主枝以外的枝条。例如下一个版本的分支等。
? Please specify perennial branches:
然后,继续删除:
[main] git fetch --prune --tags
From github.com:JabRef/jabref
[main] git branch -d remove-sav-file
Deleted branch remove-sav-file (was 33c1a869e1).
[main] git branch -d remove-bibtexml
Deleted branch remove-bibtexml (was d21c11337a).
工具 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 基于此。没有简单的方法可以实现这一点自动化,至少不是完全自动化。 (可以处理一些特殊情况。)相反,最好的办法是将这个分支删除委托给拉取请求已被压缩合并的人。有几个很好的理由:
他们是唯一可以确定合并是否正确完成的人。
例如,假设为了压缩合并一系列六个提交,“执行”压缩合并的人出于某种原因必须或选择更改一两行中的一些字符是好是坏。这一行或两行意味着最终提交中的总体更改与六次提交中的六次更改的总和不同。 但是总体结果
正确吗?如果您自己没有进行任何更改,您怎么知道?
的人。 仅仅因为
feature/tall
上的 6 个提交被压缩为添加到
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 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 %