Удалить все локальные ветки git

Я следую процессу разработки, когда я создаю новую локальную ветвь для каждой новой функции или сюжетной карты. Когда закончите, я объединить ветку в мастер и затем нажать.

То, что со временем происходит из-за сочетания лености или забывчивости, заключается в том, что я получаю большой список локальных ветвей, некоторые из которых (например, шипы), возможно, не были объединены.

Я знаю, как перечислять все мои локальные ветки, и я знаю, как удалить одну ветку, но мне было интересно, есть ли команда git, которая позволяет мне удалить все мои локальные ветки?

Ниже приведен вывод команды git branch --merged.

[email protected]:~/projects/application[master]$ git branch --merged
  STORY-123-Short-Description
  STORY-456-Another-Description
  STORY-789-Blah-Blah
* master

Все попытки удаления ветвей, перечисленных в grep -v \* (согласно приведенным ниже ответам), приводят к ошибкам:

error: branch 'STORY-123-Short-Description' not found.
error: branch 'STORY-456-Another-Description' not found.
error: branch 'STORY-789-Blah-Blah' not found.

Я использую:
git 1.7.4.1
ubuntu 10.04
GNU bash, версия 4.1.5 (1) -release
GNU grep 2.5.4

Ответ 1

Подкоманда 'git branch -d' может удалять несколько ветвей. Итак, упрощая @sblom ответ, но добавляя критические xargs:

git branch -D `git branch --merged | grep -v \* | xargs`

или, еще более упрощенное:

git branch --merged | grep -v \* | xargs git branch -D 

Важно отметить, что, как отмечено @AndrewC, использование git branch для сценариев не рекомендуется. Чтобы избежать этого, используйте что-то вроде:

git for-each-ref --format '%(refname:short)' refs/heads | grep -v master | xargs git branch -D

Предостережение при удалении!

$ mkdir br
$ cd br; git init
Initialized empty Git repository in /Users/ebg/test/br/.git/
$ touch README; git add README; git commit -m 'First commit'
[master (root-commit) 1d738b5] First commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git branch Story-123-a
$ git branch Story-123-b
$ git branch Story-123-c
$ git branch --merged
  Story-123-a
  Story-123-b
  Story-123-c
* master
$ git branch --merged | grep -v \* | xargs
Story-123-a Story-123-b Story-123-c
$ git branch --merged | grep -v \* | xargs git branch -D
Deleted branch Story-123-a (was 1d738b5).
Deleted branch Story-123-b (was 1d738b5).
Deleted branch Story-123-c (was 1d738b5).

Ответ 2

Я нашел более приятный способ в комментарии по этой проблеме в github:

git branch --merged master --no-color | grep -v master | grep -v stable | xargs git branch -d

edit: добавлена ​​опция без цвета и исключена стабильная ветка (добавьте в ваш регистр другие ветки)

Ответ 3

Разбор вывода git branch не рекомендуется, и не является хорошим ответом для будущих читателей в Stack Overflow.

  • git branch - это то, что известно как фарфоровая команда. Команды фарфора не предназначены для машинного анализа и вывод может изменяться между различными версиями Git.
  • Существуют параметры настройки пользователя, которые изменяют вывод git branch таким образом, что это затрудняет анализ (например, раскраску). Если пользователь установил color.branch, тогда вы получите коды управления на выходе, это приведет к error: branch 'foo' not found., если вы попытаетесь передать его в другую команду. Вы можете обойти это с помощью флага --no-color до git branch, но кто знает, какие другие пользовательские конфигурации могут нарушить вещи.
  • git branch могут делать другие вещи, которые раздражают синтаксический анализ, например поместите звездочку рядом с текущей проверенной веткой.

должен сказать о сценариях вокруг git branch output

Чтобы узнать, что такое текущая ветка, случайные/небрежные пользователи могут иметь сценарий вокруг ветки git, что неверно. Мы активно препятствуем против использования любой команды из фарфора, включая ветвь git, в скрипты, потому что вывод команды может быть изменен на помощь потребительский потребитель использование случай.

Ответы, предлагающие вручную редактировать файлы в каталоге .git (например,.git/refs/heads), также проблематичны (refs могут быть в .git/упакованные-refs вместо этого, или git может изменить свой внутренний макет в будущее).

Git предоставляет команду for-each-ref для получения списка ветвей.

Git 2.7.X представит параметр --merged, чтобы вы могли сделать что-то вроде ниже, чтобы найти и удалить все ветки, объединенные в HEAD

for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/)
do
    git branch -d ${mergedBranch}
done

Git 2.6.X и старше, вам нужно будет перечислить все локальные ветки, а затем проверить их индивидуально, чтобы увидеть, были ли они объединены (что будет значительно медленнее и немного сложнее).

for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/)
do
    git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch}
done

Ответ 4

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

for b in 'git branch --merged | grep -v \*'; do git branch -D $b; done

Я бы порекомендовал заменить git branch -D $b на echo $b первые несколько раз, чтобы убедиться, что он удаляет git branch -D $b вам ветки.

Ответ 5

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

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

очень полезно!

Ответ 6

Просто заметьте, я бы обновился до git 1.7.10. Вы можете получать ответы здесь, которые не будут работать над вашей версией. Я предполагаю, что вам нужно будет префикс имени ветки refs/heads/.

ВНИМАНИЕ, действуйте следующим образом, только если вы сделали копию своей рабочей папки и каталога .git.

Я иногда просто иду и удаляю ветки, которые мне не нужны, прямо из .git/refs/heads. Все эти ветки - это текстовые файлы, содержащие 40 символов sha-1, на которые они указывают. У вас будет посторонняя информация в вашем .git/config, если у вас есть определенная настройка отслеживания для любого из них. Вы также можете удалить эти записи вручную.

Ответ 7

Команда ниже удалит все локальные ветки кроме главной ветки.

git branch | grep -v "master" | xargs git branch -D

Вышеуказанная команда

  1. перечислите все ветки
  2. Из списка проигнорируйте главную ветку и возьмите остальные ветки
  3. удалить ветку

Ответ 8

Мне было проще просто использовать текстовый редактор и оболочку.

  • Введите git checkout <TAB> в оболочку. Показать все локальные ветки.
  • Скопируйте их в текстовый редактор, удалите те, которые вам нужно сохранить.
  • Заменить разрывы строк пробелами. (В SublimeText это очень просто.)
  • Откройте оболочку, введите git branch -D <PASTE THE BRANCHES NAMES HERE>.

Что это.

Ответ 9

Чтобы удалить все локальные ветки в Linux, кроме той, на которой вы находитесь

// hard delete

git branch -D $(git branch)

Ответ 10

У меня была подобная ситуация, и недавно я нашел следующую команду полезной.

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'`

Если вы хотите сохранить несколько ветвей, тогда

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`

надеюсь, что это поможет кому-то.

Ответ 11

Если вам не нужно проходить через Git, вы также можете удалить головы под .git/refs/heads вручную или программно. Следующее должно работать с минимальной настройкой в ​​ Bash:

shopt -s extglob
rm -rf .git/refs/heads/!(master)

Это приведет к удалению каждой локальной ветки, кроме основной ветки. Поскольку ваши восходящие ветки хранятся в .git/refs/remotes, они останутся нетронутыми.

Если вы не используете Bash или хотите повторно разместить много репозиториев Git сразу, вы можете сделать что-то подобное с GNU find:

find . \
    -path remotes -path logs -prune -o \
    -wholename \*.git/refs/heads/\* \! -name master -print0 |
xargs -0 rm -rf

Решение поиска, вероятно, более переносимо, но пути обрезки и имена файлов сложны и потенциально более подвержены ошибкам.

Ответ 12

Ни один из ответов не удовлетворил мои потребности полностью, поэтому мы идем:

git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin

Это приведет к удалению всех локальных ветвей, которые объединены и начинаются с feature/, bugfix/ или hotfix/. После этого удаленный origin на выезде обрезается (вам может потребоваться ввести пароль).

Работает на Git 1.9.5.

Ответ 13

Из командной строки Windows удалите все, кроме текущей извлеченной ветки, используя:

for /f "tokens=*" %f in ('git branch ^| find /v "*"') do git branch -D %f

Ответ 14

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

git for-each-ref --format '%(refname:short)' refs/heads | grep -Ev 'git ls-remote --quiet --heads origin | awk '{print substr($2, 12)}'| paste -sd "|" -' | xargs git branch -D

Ответ 15

Хотя это не решение для командной строки, я удивлен, что Git GUI еще не предлагался.

Я использую командную строку в 99% случаев, но в этом случае она либо слишком медленная (отсюда исходный вопрос), либо вы не знаете, что собираетесь удалить, прибегая к каким-то длительным, но умным манипуляциям с оболочкой.

Пользовательский интерфейс решает эту проблему, поскольку вы можете быстро отметить ветки, которые хотите удалить, и получать напоминания о тех, которые хотите сохранить, без необходимости вводить команду для каждой ветки.

В пользовательском интерфейсе перейдите в " Ветвь" → "Удалить" и нажмите Ctrl + клик по веткам, которые вы хотите удалить, чтобы они были выделены. Если вы хотите убедиться, что они объединены в ветвь (например, dev), в разделе " Только удаление", если "Объединить в" установите для " Местной ветки" значение dev. В противном случае установите значение Всегда, чтобы игнорировать эту проверку.

GitUI: delete local branches

Ответ 16

Для PowerShell это будет работать:

git branch --format '%(refname:lstrip=2)' --merged '
    | Where-Object { $_ -ne 'master' } '
    | ForEach-Object { git branch -d $_ }

Ответ 17

git branch | grep -v "master" | xargs git branch -D

Ответ 18

Следующий script удаляет ветки. Используйте его и изменяйте его на свой страх и риск и т.д. И т.д.

Основываясь на других ответах на этот вопрос, я написал для себя быстрый bash script. Я назвал его "gitbd" (git branch -D), но если вы его используете, вы можете переименовать его так, как хотите.

gitbd() {
if [ $# -le 1 ]
  then
    local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"`
    printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] "
    read -n 1 -r # Immediately continue after getting 1 keypress
    echo # Move to a new line
    if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]]
      then
        echo $branches_to_delete | xargs git branch -D
    fi
else
  echo "This command takes one arg (match pattern) or no args (match all)"
fi
}

Он предложит удалить любые ветки, которые соответствуют аргументу шаблона, если он передан, или все локальные ветки при вызове без аргументов. Он также даст вам подтверждение, так как вы знаете, что мы удаляем все, так что приятно.

Это немного глупо - если нет ветвей, которые соответствуют шаблону, он не осознает этого.

Пример вывода:

$ gitbd test
Matching branches:

dummy+test1
dummy+test2
dummy+test3

Delete? [Y/n] 

Ответ 19

Я написал сценарий оболочки, чтобы удалить все локальные ветки, кроме develop

branches=$(git branch | tr -d " *")
output=""
for branch in $branches 
do
  if [[ $branch != "develop" ]]; then
    output="$output $branch"
  fi
done
git branch -d $output

Ответ 20

Над ответами работает отлично. Вот другой подход, когда у нас много веток в локальном репо, и нам нужно удалить много веток, кроме тех, которые лежат на локальной машине.

Первая git branch выведет список всех локальных веток.

Чтобы переместить столбец с именами ветвей в одну строку в файле, запустив команду unix
git branch > sample.txt
Это сохранит его в файле sample.txt. И беги
awk 'BEGIN { ORS = " " } { print }' sample.txt
Команда в оболочке. Это преобразует столбец в строку и копирует список названий ветвей в одну строку.

А потом беги
git branch -D branch_name(s).
Это удалит все перечисленные ветки, присутствующие в локальном

Ответ 21

Самый прагматичный способ: убедитесь, что у вас нет незафиксированной работы над master, выполните коммит /push, если нужно, клонируйте свежую копию репозитория и удалите старую.

Ответ 22

Для этого вы можете использовать git-extras

$ git delete-merged-branches
Deleted feature/themes (was c029ab3).
Deleted feature/live_preview (was a81b002).
Deleted feature/dashboard (was 923befa).

Ответ 23

Убедитесь, что вы делаете это первым

git fetch

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

 git branch -a | grep -v "master" | grep remotes | sed 's/remotes\/origin\///g' | xargs git push origin --delete