Как я могу удалить все ветки Git, которые были объединены? - PullRequest
1655 голосов
/ 25 мая 2011

У меня много веток Git. Как удалить ветви, которые уже были объединены? Есть ли простой способ удалить их все вместо того, чтобы удалять их по одному?

Ответы [ 40 ]

0 голосов
/ 12 августа 2018

Я использовал следующий метод для удаления объединенных локальных и удаленных ветвей в одном cmd.

В моем файле bashrc есть следующее:

function rmb {
  current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
  if [ "$current_branch" != "master" ]; then
    echo "WARNING: You are on branch $current_branch, NOT master."
  fi
  echo "Fetching merged branches..."
  git remote prune origin
  remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
  local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
  if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
    echo "No existing branches have been merged into $current_branch."
  else
    echo "This will remove the following branches:"
    if [ -n "$remote_branches" ]; then
      echo "$remote_branches"
    fi
    if [ -n "$local_branches" ]; then
      echo "$local_branches"
    fi
    read -p "Continue? (y/n): " -n 1 choice
    echo
    if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
      # Remove remote branches
      git push origin `git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$" | sed 's/origin\//:/g' | tr -d '\n'`
      # Remove local branches
      git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
    else
      echo "No branches removed."
    fi
  fi
}

оригинал источник

Это не удаляет главную ветвь, но удаляет объединенные локальные и удаленные ветки . Как только вы получите это в своем rc-файле, просто запустите rmb, вы увидите потерянные объединенные ветви, которые будут очищены и запросят подтверждение действия. Вы можете изменить код так, чтобы он не запрашивал подтверждения, но, вероятно, его стоит сохранить.

0 голосов
/ 09 октября 2014

Для удаления локальных веток, которые были объединены с главной веткой, я использую следующий псевдоним (git config -e --global):

cleanup = "!git branch --merged master | grep -v '^*\\|master' | xargs -n 1 git branch -D"

Я использую git branch -D, чтобы избежать error: The branch 'some-branch' is not fully merged. сообщений, в то время как моя текущая проверка отличается от основной ветви.

0 голосов
/ 20 апреля 2016

Если вы хотите удалить локальные ветви, которые были объединены, а также удалить их пульты, вот одна строка, которую я предпочитаю:

git branch --merged | xargs -I_br -- sh -c 'git branch -d _br; git push origin --delete _br'
0 голосов
/ 14 мая 2019

Если вы работаете в Windows, вы можете использовать Windows Powershell с Out-GridView (к сожалению, пока он отсутствует в Powershell Core), чтобы получить хороший список ветвей и выбрать с помощью мыши ту из них, которая вам нужна. удалить:

git branch --merged | Out-GridView -PassThru | % { git branch -d $_.Trim() }

enter image description here после нажатия OK Powershell передаст имена этих веток команде git branch -d и удалит их enter image description here

0 голосов
/ 04 мая 2017
for b in $(git branch -a | grep -v "\(master\|remotes\)"); do \ 
git branch -D $b; done && git fetch -p
0 голосов
/ 23 июня 2016

Вклад моего сценария Bash основан на ответе mmrobin .

Требуется несколько полезных параметров, которые включают и исключают, либо для проверки / удаления только локальныхудаленные ветви вместо обоих.

#!/bin/bash

# exclude branches regex, configure as "(branch1|branch2|etc)$"
excludes_default="(master|next|ag/doc-updates)$"
excludes="__NOTHING__"
includes=
merged="--merged"
local=1
remote=1

while [ $# -gt 0 ]; do
  case "$1" in
  -i) shift; includes="$includes $1" ;;
  -e) shift; excludes="$1" ;;
  --no-local) local=0 ;;
  --no-remote) remote=0 ;;
  --all) merged= ;;
  *) echo "Unknown argument $1"; exit 1 ;;
  esac
  shift   # next option
done

if [ "$includes" == "" ]; then
  includes=".*"
else
  includes="($(echo $includes | sed -e 's/ /|/g'))"
fi

current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
  echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching branches...\n"

git remote update --prune
remote_branches=$(git branch -r $merged | grep -v "/$current_branch$" | grep -v -E "$excludes" | grep -v -E "$excludes_default" | grep -E "$includes")
local_branches=$(git branch $merged | grep -v "$current_branch$" | grep -v -E "$excludes" | grep -v -E "$excludes_default" | grep -E "$includes")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
  echo "No existing branches have been merged into $current_branch."
else
  echo "This will remove the following branches:"
  if [ "$remote" == 1 -a -n "$remote_branches" ]; then
    echo "$remote_branches"
  fi
  if [ "$local" == 1 -a -n "$local_branches" ]; then
    echo "$local_branches"
  fi
  read -p "Continue? (y/n): " -n 1 choice
  echo
  if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
    if [ "$remote" == 1 ]; then
      remotes=$(git remote)
      # Remove remote branches
      for remote in $remotes
      do
        branches=$(echo "$remote_branches" | grep "$remote/" | sed "s/$remote\/\(.*\)/:\1 /g" | tr -d '\n')
        git push $remote $branches
      done
    fi

    if [ "$local" == 1 ]; then
      # Remove local branches
      locals=$(echo "$local_branches" | sed 's/origin\///g' | tr -d '\n')
      if [ -z "$locals" ]; then
        echo "No branches removed."
      else
        git branch -d $(echo "$locals" | tr -d '\n')
      fi
    fi
  fi
fi
0 голосов
/ 06 января 2015

Скрипт Python, дружественный к Windoze (потому что git-sweep задохнулся в хранилище Wesnoth):

#!/usr/bin/env python
# Remove merged git branches. Cross-platform way to execute:
#
#   git branch --merged | grep -v master | xargs git branch -d
#
# Requires gitapi - https://bitbucket.org/haard/gitapi
# License: Public Domain

import gitapi

repo = gitapi.Repo('.')
output = repo.git_command('branch', '--merged').strip()
for branch in output.split('\n'):
  branch = branch.strip()
  if branch.strip(' *') != 'master':
    print(repo.git_command('branch', '-d', branch).strip())

https://gist.github.com/techtonik/b3f0d4b9a56dbacb3afc

0 голосов
/ 26 февраля 2015

Если вы используете модель ветвления, такую ​​как HubFlow или GitFlow, вы можете использовать эту команду для удаления объединенных ветвей объектов:

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

0 голосов
/ 04 июня 2019
0 голосов
/ 02 июля 2015

Допустим, у меня есть пульт с именем upstream и origin (стиль GitHub, мой форк - origin, upstream - upstream).

Я не хочу удалять ЛЮБЫЕ мастера, HEAD или что-либо из вышестоящего. Я также не хочу удалять ветку разработки, так как это наша общая ветка, из которой мы создаем PR.

Список всех удаленных веток, отфильтрованных по тем, которые были объединены:

git branch -r

Удалить строки из этого списка, содержащие слова, которые, как я знаю, находятся в названиях ветвей, которые я не хочу удалять:

sed '/develop\|master\|HEAD\|upstream/d'

Удалить удаленное имя из ссылочного имени (origin / somebranch становится somebranch):

sed 's/.*\///'

Используйте xargs для вызова однострочника:

xargs git push --delete origin

Соедините все вместе, вы получите:

git branch -r --merged | sed '/develop\|master\|HEAD\|upstream/d' |  sed 's/.*\///' | xargs git push --delete origin

Это оставит мне только некоторые ветви, над которыми я работал, но не слился. Затем вы можете удалить их один за другим, так как их не должно быть слишком много.

Найдите ветки, которые вам больше не нужны:

git branch -ar

Скажем, вы нашли branch1, branch2 и branch3, которые хотите удалить:

git push --delete origin branch1 branch2 branch3
...