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


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%, что не потеряете ничего важного. Потому что это потеряно навсегда .


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


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 должны быть включены для запуска подкоманды в некоторых командных строках)


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.