【问题标题】:How can I delete all git branches which have been "Squash and Merge" via GitHub?如何通过 GitHub 删除所有“Squash and Merge”的 git 分支?
【发布时间】:2017-09-15 07:17:33
【问题描述】:

自从 GitHub 推出 Squash and Merge 以来,我工作场所的所有酷孩子在合并拉取请求时都在使用它。有没有办法清理“Squash and Merge”分支?

来自How can I delete all git branches which have been merged? 的以下命令不适用于“Squash and Merge”:

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

【问题讨论】:

    标签: git github merge git-branch git-squash


    【解决方案1】:

    这是一个脚本,它将删除所有已被 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'
    

    来源:

    https://github.com/not-an-aardvark/git-delete-squashed

    【讨论】:

    • 这对我来说非常好。它删除了几百个分支,留下了我从未完成或正在试验的分支。很好的答案。
    • 超级有用,谢谢!
    【解决方案2】:

    没有简单的方法可以自动执行此操作,至少不能完全自动化。 (可以处理一些特殊情况。)相反,最好的办法是将此分支删除委托给拉取请求已被压缩合并的人。有几个很好的理由:

    1. 他们是唯一可以确保合并正确完成的人。

      假设,例如,为了 squash-merge 一系列六个提交,进行 squash-merge 的人必须或选择在某个地方更改几个字符一行或两行,出于某种原因是好是坏。那一行或两行意味着最终提交中的总体更改与六次提交中六次更改的总和不同

      但总体结果是否正确正确?如果您自己没有进行任何更改,您怎么知道?

    2. 他们是唯一知道他们是否打算在该分支上继续发展的人。

      仅仅因为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。所以现在问题更简单了,可以自动化:find branches whose "upstream" is gone, and delete those。 (此答案中的单行脚本有一些小缺陷;请参阅 cmets;更高级的会使用 git for-each-ref 并使用 git rev-parse 查找每个分支的上游设置,但这可能有点矫枉过正。)

    【讨论】:

      【解决方案3】:

      git-delete-merged-branches 工具可以方便地删除分支。我特别喜欢互动模式。

      安装(需要python3):

      pip install git-delete-merged-branches
      

      然后执行

      git-delete-merged-branches --effort=3 --branch main
      
      • --effort=3 对删除压扁的分支很重要。
      • --branch main 是必需的(否则使用 master

      替代方案

      【讨论】:

        【解决方案4】:

        这个帖子里的答案也很有用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 %
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-08-03
          • 2017-03-28
          • 2017-06-20
          • 2013-10-03
          • 1970-01-01
          • 2016-01-09
          • 2016-07-26
          • 2018-04-05
          相关资源
          最近更新 更多