Могу ли я удалить все локальные ветки, кроме текущей?

98

Я хочу удалить все ветки, перечисленные в выводе ...

$ git branch

... но сохраняя текущую ветку за один шаг . Это возможно? Если да, то как?

сенсорарио
источник

Ответы:

67

Основываясь на ответе @pankijs, я сделал два псевдонима git:

[alias]
    # Delete all local branches but master and the current one, only if they are fully merged with master.
    br-delete-useless = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -d;\
    }; f"
    # Delete all local branches but master and the current one.
    br-delete-useless-force = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -D;\
    }; f"

Будет добавлено в ~/.gitconfig


И, как отметил @torek:

Обратите внимание, что строчные буквы -dне удаляют «не полностью объединенную» ветку (см. Документацию). Использование -D приведет к удалению таких ветвей , даже если это приведет к потере фиксации; используйте это с большой осторожностью , так как при этом удаляются также и рефлоги веток, так что обычные вещи «восстановление после случайного удаления» тоже не работают.

По сути, никогда не используйте -forceверсию, если вы не уверены на 300%, что не потеряете ничего важного. Потому что это потеряно навсегда .

Vadorequest
источник
2
коммиты в удаленную ветку еще какое-то время должны быть в журнале ссылок.
CaptRespect
Действительно, коммиты останутся в рефлоге. Но не сама ветка. Я бы не стал пробовать, но я думаю, вы можете найти свои коммиты, но вернуться в состояние ветки? Я в этом сомневаюсь. Cherry-pick можно использовать для получения коммитов в удаленной ветке, но вы не сможете восстановить саму ветку.
Vadorequest
1
@Vadorequest, вы можете воссоздать ветку, указывающую на определенный коммит, выполнивgit branch branchname commitid
pqnet
@pqnet Я не знал, что это воссоздает всю историю этой ветки, спасибо, приятно знать!
Vadorequest
1
@Vadorequest, поскольку объекты фиксации неизменяемы (и индексируются как хэши), каждое редактирование требует создания нового объекта (с другим хешем)
pqnet
190
$ git branch | grep -v "master" | xargs git branch -D 

удалит все ветки, кроме master (замените master веткой, которую вы хотите сохранить, но затем она удалит мастер)

панкис
источник
31
Если вы хотите сохранить текущую ветку, используйте grep -v ^*.
Schwern
2
Многие источники показывают мне этот сценарий, но когда я запускаю его, он всегда сообщает мне, что ветки не найдены :(
tucq88
1
это неточно, ветка с именем master-copy, например, не
удаляется
2
Измените регулярное выражение по мере необходимости, например,grep -v "^ *master$"
Брэд Кох
9
Если вы хотите сохранить две ветки, используйте grep -v "master\|my-other-branch".
Дерек Сойке
23

сначала (переключитесь на ветку, которую вы хотите сохранить> ex : master ):

git checkout master

второй (убедитесь, что вы на главном )

git branch -D $(git branch)
ХогаЭслам
источник
3
очень быстро и легко. Почему это не получает голосов?
princebillyGK
1
Это самый простой и лучший ответ для меня.
Салех Энам Шохаг,
3
Если вы используете PowerShell, используйте git branch -D $(git branch).Trim().
NatoBoram
мы должны заключать $(git branch)в кавычки? Это не работает: ошибка: ветка «$ (git» не найдена. Ошибка: ветка «ветка)» не найдена.
saran3h
1
Следует проголосовать за лучший ответ из всех возможных,
xelber
13

git branch -d(или -D) позволяет использовать несколько имен веток, но немного сложно автоматически предоставить «все локальные ветки, за исключением той, в которой я сейчас работаю», не написав хотя бы немного кода.

"Лучший" (формально правильный) метод - git for-each-refполучить имена веток:

git for-each-ref --format '%(refname:short)' refs/heads

но тогда еще труднее определить, в какой ветке вы находитесь ( git symbolic-ref HEADэто «формально правильный» метод для этого, если вы хотите написать необычный сценарий).

Более удобно, вы можете использовать git branch, который печатает имена ваших локальных веток, которым предшествуют два пробела или (для текущей ветки) звездочка *. Итак, пропустите это через что-нибудь, чтобы удалить *версию, и у вас останутся имена веток, разделенных пробелами, которые вы затем можете передать git branch -d:

git branch -d $(git branch | grep -v '^*')

или:

git branch | grep -v '^*' | xargs git branch -d

Обратите внимание, что строчные буквы -dне удаляют «не полностью объединенную» ветку (см. Документацию). Использование -Dприведет к удалению таких ветвей, даже если это приведет к потере фиксации; используйте это с большой осторожностью, так как при этом удаляются также и рефлоги веток, так что обычные вещи «восстановление после случайного удаления» тоже не работают.

торек
источник
Так и должно быть git branch -D $(git branch | grep -v '^*'), если вы хотите удалить те ветки, которые слились.
Pratik Singhal
@PratikSinghal: удаляет все остальные ветки, а не только ветки, которые Git считает «объединенными». Это редко бывает хорошей идеей. Я уже отмечал оба эти пункта в своем ответе.
torek
12

Чтобы удалить все объединенные ветки (кроме текущей -v ‘*’):

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

Также я сделал такую ​​команду для полной очистки репо:

alias git-clean="git branch  | grep -v '*' | grep -v 'master' | xargs git branch -D  && git reset --hard && git clean -d -x -f"

взято отсюда .

Степан Суворов
источник
1
Это удаляет только объединенные ветки.
Pratik Singhal
10

Удалите все ветки, кроме определенной :

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

Удалите все локальные ветки, кроме разработки и мастера

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Асад Манзур
источник
6

Для Windows в Powershell используйте:

git branch | %{ $_.Trim() } | ?{ $_ -ne 'master' } | %{ git branch -D $_ }
Роберт Корвус
источник
3

Однажды я создал эту конструкцию для своей среды Windows. Может быть, это поможет кому-то другому. Во время выполнения главная и текущая ветки не удаляются . Все остальные объединенные ветки будут удалены независимо.

@echo off
cd PATH_TO_YOUR_REPO

REM -- Variable declerations
set "textFile=tempBranchInfo.txt"
set "branchToKeep=master"
set "branchToReplaceWith="
git branch --merged > %textFile%

REM -- remove "master" from list to keep the branch
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%textFile%" echo(!line:%branchToKeep%=%branchToReplaceWith%!
    endlocal
)

REM -- execute branch delete commands
for /f "delims=" %%a in (%textFile%) do (
    git branch -D %%a
)

REM -- remove temp-file with branch information inside
DEL %textFile%

REM -- show local branches after the cleaning
echo Local branches:
git branch

pause 
exit
Джордж Махарис
источник
3

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

git branch | grep -v $(git rev-parse --abbrev-ref HEAD) | xargs git branch -D

Дэн Дай
источник
2

Удалить всю объединенную ветку локально:

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

Удалите все ветки, кроме определенной :

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

Удалите все локальные ветки, кроме разработки и мастера

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Асад Манзур
источник
2

Предполагая, git branchпоказывает текущую ветку с префиксом *; Используя Powershell, следующий лайнер удалит все ветки, которые не начинаются *.

git branch | ? { $_ -lt "*" } | % { git branch -D $_.Trim() }

? = Где-Объект

% = По каждому объекту

Аарон
источник
1

Итак, я вижу здесь много жестко закодированных имен веток ... И я думаю, что мой ответ здесь более точен для части вопроса о «текущей ветке», при этом он остается одной строкой и удобочитаем для таких новичков, как я. Просто чтобы отдать должное, ответ, скорее всего, также основан на ответе @pankijs.

git branch | grep -v $(git branch --show-current) | xargs git branch -d

и у меня есть псевдоним в одной строке в моих .bash_aliases в debian.

alias gitbclean='git branch | grep -v $(git branch --show-current) | xargs git branch -d'

(Хотя я думаю, что некоторые функции bash должны быть включены для запуска подкоманды в некоторых командных строках)

NullifiedWarp
источник
1

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

BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
echo $BRANCHES

Я положил это в свой ~/.zshrc

delete_branches() {
  BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
  echo $BRANCHES
}

alias cleanup_branches=delete_branches
Джастин Райс
источник
0

ИМХО, самый безопасный способ удаления локальных веток:

git branch -av | grep "\[gone\]" | awk '{print $1}' | xargs git branch -d

Кроме того, дополнительную информацию по этой теме вы можете найти в разделе Удаление всех локальных веток git.

Эльбик
источник
чтобы напечатать goneмаркер, который вы должны использовать -vv(подробно дважды), -aэто не поможет вам (в нем перечислены также удаленные ветки)
pqnet