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

1463

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

  • 35
    git branch -D удаляет ветки, которые НЕ были объединены! Используйте с осторожностью!
  • 27
    Чтобы быть немного более конкретным, git branch -D удаляет любую ветку, независимо от того, была ли она объединена или нет.
Показать ещё 3 комментария
Теги:
github
version-control
branch

40 ответов

2352
Лучший ответ

UPDATE:

Вы можете добавить другие ветки, чтобы исключить их как master и dev, если ваш рабочий процесс имеет их как возможный предок. Обычно я отключаю тег "спринт-старт" и мастер, dev и qa не являются предками.

Чтобы удалить все локальные ветки, которые уже объединены в текущую отмеченную ветку:

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

Вы можете видеть, что мастер и dev исключены, если они являются предками.


Вы можете удалить объединенную локальную ветвь с помощью:

git branch -d branchname

Если он не объединен, используйте:

git branch -d branchname

Чтобы удалить его с пульта в старых версиях Git, используйте:

git push origin :branchname

В более поздних версиях Git используйте:

git push --delete origin branchname

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

git remote prune origin

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

git branch -dr branchname

Надеюсь, что это поможет.

  • 2
    да я знаю как удалить ветку. Но у меня есть 100 веток, и 50 из них уже объединены с мастером, а еще 50 еще не слиты. Поэтому я хочу удалить ветви, которые объединены с мастером. Поэтому я спрашиваю здесь, как удалить их быстрее, чем удалять по одному.
  • 1
    мастер проверки git; для ветки в $ (git branch --raw); do git branch - содержит $ branch && git branch -d $ branch; сделанный
Показать ещё 30 комментариев
340

Чтобы удалить все ветки на удаленном сервере, которые уже объединены:

git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin

В более поздних версиях Git

git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin
  • 14
    Лучший ответ на сегодняшний день. Просто обратите внимание, моя основная ветка называется dev поэтому мне пришлось изменить это
  • 36
    Я должен был добавить | grep origin после grep -v master чтобы предотвратить перемещение веток других пультов на источник Настоятельно рекомендуем предварительно проверить вывод, используя git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo
Показать ещё 9 комментариев
140

Просто расширяя Адама немного:

Добавьте это в конфигурацию Git, запустив git config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d"

И затем вы можете удалить все локальные объединенные ветки, выполнив простой git cleanup.

  • 9
    не должна ли первая команда быть: git branch --merged master так как вы хотите посмотреть, что было объединено с master, а не в настоящее время извлеченным ответвлением?
  • 0
    @JoePhilllips У некоторых людей основная ветвь не master, а вместо этого develop или dev и в этом случае команда завершится неудачно с fatal: malformed object name , лучше иметь универсальную команду, и вы несете ответственность за ее запуск.
Показать ещё 10 комментариев
70

Это также позволяет удалить все объединенные ветки, кроме master.

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d
  • 3
    Теперь он не удалит ни одну ветку с master . Попробуйте grep -v ^master$ для середины.
  • 0
    Я бы тоже позволил | grep -v '^\*' чтобы избежать удаления текущей ветки, если вы не на master
Показать ещё 2 комментария
57

Вы хотите исключить ветки master и develop из этих команд.

Локальный git очистить:

git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d

Удаленная git очистка:

git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin

Синхронизировать локальный реестр удаленных ветвей:

git fetch -p
  • 3
    +1 также для удаленной версии (но менее необходимой, так как у нас есть удаленный --prune). Также стоит отметить, что Thoose не будет работать со старой версией Git
  • 3
    git config --global --add fetch.prune true для автоматического git config --global --add fetch.prune true при извлечении или извлечении.
Показать ещё 3 комментария
37

Для тех из вас, кто находится в Windows и предпочитает сценарии PowerShell, вот что удаляет локальные объединенные ветки:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object {$_ -NotMatch "^\*"} |
    Where-Object {-not ( $_ -Like "*master" )} |
    ForEach-Object { git branch -d $_ }
}
  • 11
    Ради любопытства, это можно сократить до git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()}
  • 2
    @IainBallard Конечно, я мог бы использовать псевдонимы. Это не рекомендуется, когда вы хотите максимизировать читабельность. github.com/darkoperator/PSStyleGuide/blob/master/English.md
Показать ещё 3 комментария
19

Git Sweep отлично справляется с этим.

13

Вы можете добавить фиксацию к опции -merged. Таким образом, вы можете убедиться, что только удалены ветки, которые объединены в i.e origin/master

Следующая команда удалит объединенные ветки из вашего источника.

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

Вы можете проверить, какие ветки будут удалены, заменив начало git push -delete с помощью эха

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
  • 1
    Мне нравится тестовый вариант
12

Использование Git версии 2.5.0:

git branch -d `git branch --merged`
  • 11
    Это может удалить master ветку кстати!
  • 3
    Правда. Я использую его только тогда, когда я уверен, что на master .
Показать ещё 1 комментарий
11

Я использую следующий Ruby script, чтобы удалить уже объединенные локальные и удаленные ветки. Если я делаю это для репозитория с несколькими удаленными устройствами и только хочу удалить из него, я просто добавляю оператор select в список удаленных компьютеров, чтобы получить только удаленные удаленные модули.

#!/usr/bin/env ruby

current_branch = `git symbolic-ref --short HEAD`.chomp
if current_branch != "master"
  if $?.exitstatus == 0
    puts "WARNING: You are on branch #{current_branch}, NOT master."
  else
    puts "WARNING: You are not on a branch"
  end
  puts
end

puts "Fetching merged branches..."
remote_branches= `git branch -r --merged`.
  split("\n").
  map(&:strip).
  reject {|b| b =~ /\/(#{current_branch}|master)/}

local_branches= `git branch --merged`.
  gsub(/^\* /, '').
  split("\n").
  map(&:strip).
  reject {|b| b =~ /(#{current_branch}|master)/}

if remote_branches.empty? && local_branches.empty?
  puts "No existing branches have been merged into #{current_branch}."
else
  puts "This will remove the following branches:"
  puts remote_branches.join("\n")
  puts local_branches.join("\n")
  puts "Proceed?"
  if gets =~ /^y/i
    remote_branches.each do |b|
      remote, branch = b.split(/\//)
      `git push #{remote} :#{branch}`
    end

    # Remove local branches
    `git branch -d #{local_branches.join(' ')}`
  else
    puts "No branches removed."
  end
end
  • 0
    Не возражаете, если я украду этот кусок для маленькой библиотеки git helper? github.com/yupiq/git-branch-util
  • 1
    Пойдите для этого, я не поместил бы это здесь, если бы заботился о людях, повторно использующих код каким-то образом
Показать ещё 3 комментария
8

Удаление объединенных веток в консоли PowerShell

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

См. GitHub для Windows

  • 1
    Более высокие ответы предлагают фильтрацию мастера или других веток. Для тех, кто хочет сделать это в powershell: git branch --merged | findstr / v "мастер" | % {git branch -d $ _. trim ()}
  • 0
    @tredzko Хорошая мысль. FTR более высокий ответ - stackoverflow.com/questions/6127328/… - вы можете опубликовать свой комментарий со ссылкой, и я бы затем удалил это
Показать ещё 1 комментарий
8

Ответ kuboon пропустил удаление ветвей, у которых есть имя слова в имени ветки. Следующее улучшает его ответ:

git branch -r --merged | grep -v "origin/master$" | sed 's/\s*origin\///' | xargs -n 1 git push --delete origin

Конечно, он не удаляет сам "главный":)

7

В Git нет команды, которая сделает это автоматически. Но вы можете написать script, который использует команды Git, чтобы дать вам то, что вам нужно. Это можно сделать разными способами в зависимости от используемой модели ветвления.

Если вам нужно знать, если ветвь была объединена с мастером, следующая команда не даст результата, если myTopicBranch был объединен (т.е. вы можете удалить его)

$ git rev-list master | grep $(git rev-parse myTopicBranch)

Вы можете использовать команду ветвления Git и проанализировать все ветки в Bash и выполнить цикл for по всем ветвям. В этом цикле вы проверяете с помощью приведенной выше команды, если вы можете удалить ветку или нет.

6

Я уже много лет использовал ответы Адама. Тем не менее, есть случаи, когда он не вел себя так, как я ожидал:

  1. ветки, содержащие слово "хозяин", игнорировались, например "notmaster" или "masterful", а не только ведущая ветвь
  2. ветки, содержащие слово "dev", игнорировались, например, "dev-test", а не только ветвь dev
  3. удаление ветвей, достижимых из HEAD текущей ветки (то есть не обязательно ведущей)
  4. в отдельном состоянии HEAD, удаляя каждую ветвь, доступную от текущей фиксации

1 и 2 были просто адресованы, только с изменением регулярного выражения. 3 зависит от контекста того, что вы хотите (т.е. Удалять ветки, которые не были объединены в мастер или против вашей текущей ветки). 4 может иметь катастрофические последствия (хотя и восстанавливаться с помощью git reflog), если вы непреднамеренно git reflog это в отдельном состоянии HEAD.

Наконец, я хотел, чтобы все это было в одном слое, для которого не требовался отдельный (Bash | Ruby | Python) скрипт.

TL; DR

Создайте git-псевдоним "sweep", который принимает необязательный флаг -f:

git config --global alias.sweep '!f(){ git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d; }; f'

и вызвать его с помощью:

git sweep

или же:

git sweep -f

Длинный, подробный ответ

Мне было проще всего создать пример git repo с некоторыми ветвями и фиксации для проверки правильного поведения:

Создайте новый репозиторий git с помощью одной фиксации

mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"

Создание новых ветвей

git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
  bar
  develop
  foo
* master
  masterful
  notmaster

Желаемое поведение: выберите все объединенные ветки, кроме: master, develop или current

Исходное регулярное выражение пропускает ветки "мастерски" и "notmaster":

git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
  bar

С обновленным регулярным выражением (которое теперь исключает "develop", а не "dev"):

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster

Переключитесь на ветвь foo, сделайте новую фиксацию, затем проверьте новую ветвь foobar на основе foo:

echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"

Моя текущая ветвь является foobar, и если я повторно запустил указанную выше команду для списка ветвей, которые я хочу удалить, ветка "foo" включена, хотя она не была объединена с мастером:

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  masterful
  notmaster

Однако, если я запускаю ту же команду на master, ветка "foo" не включается:

git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

И это просто потому, что git branch --merged умолчанию соответствует HEAD текущей ветки, если не указано иное. По крайней мере, для моего рабочего процесса я не хочу удалять локальные ветки, если они не были объединены в master, поэтому я предпочитаю следующий вариант:

git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

Отдельное состояние HEAD

Опираясь на поведение по умолчанию git branch --merged имеет еще более значительные последствия в отдельном состоянии HEAD:

git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  foobar
  masterful
  notmaster

Это удалило бы ветку, на которой я только что был, "foobar" вместе с "foo", что почти наверняка не является желаемым результатом. Однако с нашей пересмотренной командой:

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

Одна строка, включая фактическое удаление

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d

Все завернутые в git псевдоним "sweep":

git config --global alias.sweep '!f(){ git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d; }; f'

Псевдоним принимает дополнительный флаг -f. По умолчанию используется только удаление ветвей, которые были объединены в master, но флаг -f удаляет ветки, которые были объединены в текущую ветку.

git sweep
Deleted branch bar (was 9a56952).
Deleted branch masterful (was 9a56952).
Deleted branch notmaster (was 9a56952).
git sweep -f
Deleted branch foo (was 2cea1ab).
6

git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d удалит все локальные ветки, кроме текущей вывешенной ветки и/или master.

Вот полезная статья для тех, кто хочет понять эти команды: Git Очистить: удалить уже объединенные ветки, Стивеном Харманом.

5

Версия псевдонима Адам обновил ответ:

[alias]
    branch-cleanup = "!git branch --merged | egrep -v \"(^\\*|master|dev)\" | xargs git branch -d #"

Также см. этот ответ для удобных советов по экранированию сложных псевдонимов.

5

Вы можете использовать инструмент git-del-br.

git-del-br -a

Вы можете установить его через pip используя

pip install git-del-br

PS: Я автор инструмента. Любые предложения/отзывы приветствуются.

  • 0
    @ stackoverflow.com/users/100297/martijn-pieters : Почему этот ответ был удален и лишен права голоса?
  • 0
    Ваш ответ и инструмент не работают. Я провожу пару часов на этом. Ничего такого.
Показать ещё 2 комментария
4

Ниже запроса работает для меня

for branch in  'git branch -r --merged | grep -v '\*\|master\|develop'|awk 'NR > 0 {print$1}'|awk '{gsub(/origin\//, "")}1'';do git push origin --delete $branch; done

и это будет фильтровать любую ветвь в grep-канале.

Хорошо работает над http clone, но не так хорошо для ssh-соединения.

4

Попробуйте выполнить следующую команду:

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

Используя git rev-parse, вы получите имя текущего ветки, чтобы исключить его. Если вы получили ошибку, это означает, что локальные ветки не удаляются.

Чтобы сделать то же самое с удаленными ветвями (измените origin на свое удаленное имя), попробуйте:

git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)

Если у вас несколько пультов, добавьте grep origin | до cut, чтобы фильтровать только origin.

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

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

Затем git fetch удаленный снова и снова используйте предыдущую команду git push -vd.

Если вы часто используете его, подумайте о том, чтобы добавить в свой файл ~/.gitconfig псевдонимы.

Если вы удалили несколько ветвей по ошибке, используйте git reflog, чтобы найти потерянные коммиты.

4

Я использую схему именования git -flow esque, поэтому для меня это очень безопасно:

git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d

В основном он ищет объединенные коммиты, начинающиеся с строки fix/ или feature/.

4

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

git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d

Эта команда не повлияет на вашу текущую ветку или главную ветку. Он также расскажет вам, что он делает, прежде чем он это сделает, используя флаг -t xargs.

4

Основываясь на некоторых из этих ответов, я сделал мой собственный Bash script, чтобы сделать это тоже!

Он использует git branch --merged и git branch -d для удаления ветвей, которые были объединены, и запрашивает каждую ветвь перед удалением.

merged_branches(){
  local current_branch=$(git rev-parse --abbrev-ref HEAD)
  for branch in $(git branch --merged | cut -c3-)
    do
      echo "Branch $branch is already merged into $current_branch."
      echo "Would you like to delete it? [Y]es/[N]o "
      read REPLY
      if [[ $REPLY =~ ^[Yy] ]]; then
        git branch -d $branch
      fi
  done
}
3

Напишите script, в котором Git проверяет все ветки, которые были объединены с мастером.

Затем выполните git checkout master.

Наконец, удалите объединенные ветки.

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git checkout $branchnew
done

git checkout master

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git push origin --delete $branchnew
done
2

Принятое решение довольно хорошо, но имеет одну проблему: он также удаляет локальные ветки, которые еще не были объединены в удаленный.

Если вы посмотрите на результат, вы увидите что-то вроде

$ git branch --merged master -v
  api_doc                  3a05427 [gone] Start of describing the Java API
  bla                      52e080a Update wording.
  branch-1.0               32f1a72 [maven-release-plugin] prepare release 1.0.1
  initial_proposal         6e59fb0 [gone] Original proposal, converted to AsciiDoc.
  issue_248                be2ba3c Skip unit-for-type checking. This needs more work. (#254)
  master                   be2ba3c Skip unit-for-type checking. This needs more work. (#254)

Филиалы bla и issue_248 являются локальными ветвями, которые будут удалены молча.

Но вы также можете увидеть слово [gone], которое указывает ветки, которые были нажаты на удаленный (который теперь ушел) и, таким образом, обозначают ветки, которые можно удалить.

Таким образом, исходный ответ может быть изменен на (разбитый на многострочный для более короткой длины строки)

git branch --merged master -v | \
     grep  "\\[gone\\]" | \
     sed -e 's/^..//' -e 's/\S* .*//' | \
      xargs git branch -d

для защиты еще не объединенных веток. Также grepping для мастера, чтобы защитить его, не требуется, так как у этого есть пульт по происхождению и он не отображается, как ушел.

1

В Windows вы можете установить Cygwin и удалить все удаленные ветки, используя следующую команду:

git branch -r --merged | "C:\cygwin64\bin\grep.exe" -v master | "C:\cygwin64\bin\sed.exe" 's/origin\///' | "C:\cygwin64\bin\xargs.exe" -n 1 git push --delete origin
1

По состоянию на 2018.07

Добавьте это в раздел [alias] вашего ~/.gitconfig:

sweep = !"f() { git branch --merged | egrep -v \"(^\\*|master|dev)\" || true | xargs git branch -d; }; f"

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

  • 0
    Для меня вызов git sweep перечисляет только те ветки, которые нужно очистить, но не удаляет их
1

Чтобы избежать случайного запуска команды из любой другой ветки, кроме мастера, я использую следующий bash script. В противном случае запуск git branch --merged | grep -v "\*" | xargs -n 1 git branch -d из ветки, которая была объединена с отключенным мастером, может удалить главную ветвь.

#!/bin/bash

branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)"     # detached HEAD
branch_name=${branch_name##refs/heads/}

if [[ $branch_name == 'master' ]]; then
   read -r -p "Are you sure? [y/N] " response
   if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
       git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
   fi
else
   echo "Refusing to delete branches that are not merged into '$branch_name'. Checkout master first."
fi
0

Я использовал следующий метод для удаления объединенных локальных и удаленных ветвей в одном 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
$ git config --global alias.cleanup
'!git branch --merged origin/master | egrep -v "(^\*|master|staging|dev)" | xargs git branch -d'

(Разделить на несколько строк для удобства чтения)

Вызов "git cleanup" приведет к удалению локальных ветвей, которые уже были объединены в origin/master. Он пропускает мастер, постановку и dev, потому что мы не хотим удалять их в обычных обстоятельствах.

Нарушая это, это то, что он делает:

  1. git config --global alias.cleanup
    • Это создает глобальный псевдоним, называемый "очистка" (во всех ваших репозиториях)
  2. ! в начале команды говорится, что мы будем использовать некоторые команды не-git как часть этого псевдонима, поэтому нам нужно фактически запускать команды bash здесь
  3. git branch --merged origin/master
    • Эта команда возвращает список имен ветвей, которые уже были объединены в origin/master
  4. egrep -v "(^\*|master|staging|dev)"
    • Это удаляет ведущую, промежуточную ветвь и ветвь dev из списка ветвей, которые уже были объединены. Мы не хотим удалять эти ветки, поскольку они не являются функциями.
  5. xargs git branch -d
    • Это приведет к выполнению команды git branch -d xxxxx для каждой из несвязанных ветвей. Это удаляет локальные ветки по одному.
0

В Windows с установкой git bash egrep -v не будет работать

git branch --merged | grep -E -v "(master|test|dev)" | xargs git branch -d

где grep -E -v эквивалентен egrep -v

Используйте -d для удаления уже объединенных ветвей или -d для удаления несвязанных ветвей

  • 0
    egrep -v у меня работает. Я использую gitbash из установщика gitextensions, хотя
0
for b in $(git branch -a | grep -v "\(master\|remotes\)"); do \ 
git branch -D $b; done && git fetch -p
0

Мой вклад Bash script основан на mmrobin answer.

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

#!/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

Если вы хотите удалить локальные ветки, которые были объединены, а также удалить их пульты здесь, мне нужен один лайнер:

git branch --merged | xargs -I_br -- sh -c 'git branch -d _br; git push origin --delete _br'
0

Скажем, у меня есть удаленный названный upstream и origin (стиль GitHub, моя вилка - начало, вверх по потоку вверх).

Я не хочу удалять ЛЮБЫХ мастеров, 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

Скажем, вы найдете ветку 1, ветвь2 и ветвь 3, которые хотите удалить:

git push --delete origin branch1 branch2 branch3
  • 0
    Это не сработает, если у вас есть ветви, названные как feature / my-feature, так как он использует слеш.
0

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

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

0

Windoze-friendly Python script (потому что 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

Чтобы удалить локальные ветки, которые были объединены в master-ветку, я использую следующий псевдоним (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., в то время как моя текущая проверка отличается от основной ветки.

-1

Если они объединены и удалены по источнику (например, github), мы можем обновить список ветвей с помощью команды

git fetch -p
-2

Если вы удаляете свой компьютер локальный, вот мой прямой способ:

Просто перейдите к: C:\Repo\your-project\.git\refs\heads

Каждая ветвь - это файл, созданный в этой папке, просто удалите файлы, соответствующие вашим именам ветвей.

Трудно найти метод в Windows. Я просто понял это, и это спасло меня при установке Windows.

-5

Я нашел a script в GitHub, в котором говорится, что он удаляет объединенные ветки:

Но имейте в виду, что этот script не проверен:

#!/bin/sh

BASE_DIR=$(cd $(dirname $0); pwd)

# Remove merged branches
git for-each-ref --format='%(refname)' refs/heads | while read branch; do
    git rev-parse --quiet --verify "$branch" > /dev/null || continue # make sure it still exists
    git symbolic-ref HEAD "$branch"
#    echo "merged branches:"
#    git branch --merged | grep -v '^\*'
    git branch -d $( git branch --merged | grep -v '^\*' | grep -v 'master' )
done

git checkout master

Ещё вопросы

Сообщество Overcoder
Наверх
Меню