Я следую процессу разработки, когда я создаю новую локальную ветвь для каждой новой функции или сюжетной карты. Когда закончите, я объединить ветку в мастер и затем нажать.
То, что со временем происходит из-за сочетания лености или забывчивости, заключается в том, что я получаю большой список локальных ветвей, некоторые из которых (например, шипы), возможно, не были объединены.
Я знаю, как перечислять все мои локальные ветки, и я знаю, как удалить одну ветку, но мне было интересно, есть ли команда git, которая позволяет мне удалить все мои локальные ветки?
Ниже приведен вывод команды git branch --merged
.
user@machine:~/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
Просто заметьте, я бы обновился до git 1.7.10. Вы можете получать ответы здесь, которые не будут работать над вашей версией. Я предполагаю, что вам нужно будет префикс имени ветки refs/heads/
.
ВНИМАНИЕ, действуйте следующим образом, только если вы сделали копию своей рабочей папки и каталога .git.
Я иногда просто иду и удаляю ветки, которые мне не нужны, прямо из .git/refs/heads
. Все эти ветки - это текстовые файлы, содержащие 40 символов sha-1, на которые они указывают. У вас будет посторонняя информация в вашем .git/config
, если у вас есть определенная настройка отслеживания для любого из них. Вы также можете удалить эти записи вручную.
Подкоманда '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).
error:branch 'STORY-123-Short-Description' not found.
для каждой из перечисленных веток.
Я нашел более приятный способ в комментарии по этой проблеме в github:
git branch --merged master --no-color | grep -v master | grep -v stable | xargs git branch -d
edit: добавлена опция без цвета и исключена стабильная ветка (добавьте в ваш регистр другие ветки)
error: branch 'my-branch-name' not found.
для каждой отрасли. Использование git версии 1.8.3.4 (Apple Git-47). Есть идеи почему?
Разбор вывода 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
git branch --no-color 2>/dev/null
?
git branch
- это фарфоровая команда, и нет никакой гарантии, что выходные данные не изменятся в какой-либо будущей версии git.
Чтобы удалить каждую ветку, кроме той, которую вы в настоящее время проверили:
for b in `git branch --merged | grep -v \*`; do git branch -D $b; done
Я бы рекомендовал сначала изменить на git branch -D $b
на echo $b
первые несколько раз, чтобы убедиться, что он удалит ветки, которые вы намереваетесь.
error:branch 'a_branch_name' not found.
Я могу видеть, что вы пытаетесь сделать, и я играл с командой, но по какой-то причине git, похоже, не нравятся предоставленные имена веток ...
git branch --merged
Простейший способ удалить все ветки, но держать других, таких как "разработка" и "мастер", следующий:
git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
очень полезно!
Мне было проще просто использовать текстовый редактор и оболочку.
git checkout <TAB>
в оболочку. Показать все локальные ветки.git branch -D <PASTE THE BRANCHES NAMES HERE>
.Что это.
Команда ниже удалит все локальные ветки кроме главной ветки.
git branch | grep -v "master" | xargs git branch -D
Вышеуказанная команда
git branch | grep -v "master" | xargs git branch -d
сначала, поэтому я не удаляю неотправленные ветки, просто для безопасности. Но хороший ответ!
,@(git branch | Select-String -Pattern "[^(*?)\s? master]") | ForEach-Object{$_.Line.Trim()} | %{git branch -D $_}
У меня была подобная ситуация, и недавно я нашел следующую команду полезной.
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 }'`
надеюсь, что это поможет кому-то.
git branch -D `git branch | awk '{ if ($0 !~ /master/) printf "%s", $0 }'`
самом деле я думаю, что они у вас были изначально, но они потерялись в SO-форматировании.
Если вам не нужно проходить через 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
Решение поиска, вероятно, более переносимо, но пути обрезки и имена файлов сложны и потенциально более подвержены ошибкам.
Ни один из ответов не удовлетворил мои потребности полностью, поэтому мы идем:
git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin
Это приведет к удалению всех локальных ветвей, которые объединены и начинаются с feature/
, bugfix/
или hotfix/
. После этого удаленный origin
на выезде обрезается (вам может потребоваться ввести пароль).
Работает на Git 1.9.5.
Над ответами работает отлично. Вот другой подход, когда у нас много веток в локальном репо, и нам нужно удалить много веток, кроме тех, которые лежат на локальной машине.
Первая git branch
выведет список всех локальных веток.
Чтобы переместить столбец с именами ветвей в одну строку в файле, запустив команду unix git branch > sample.txt
Это сохранит его в файле sample.txt. И беги awk 'BEGIN { ORS = " " } { print }' sample.txt
Команда в оболочке. Это преобразует столбец в строку и копирует список названий ветвей в одну строку.
А потом беги git branch -D branch_name(s)
.
Это удалит все перечисленные ветки, присутствующие в локальном
Хотя это не решение для командной строки, я удивлен, что Git GUI еще не предлагался.
Я использую командную строку в 99% случаев, но в этом случае она либо слишком медленная (отсюда исходный вопрос), либо вы не знаете, что собираетесь удалить, прибегая к каким-то длительным, но умным манипуляциям с оболочкой.
Пользовательский интерфейс решает эту проблему, поскольку вы можете быстро отметить ветки, которые хотите удалить, и получать напоминания о тех, которые хотите сохранить, без необходимости вводить команду для каждой ветки.
В пользовательском интерфейсе перейдите в " Ветвь" → "Удалить" и нажмите Ctrl + клик по веткам, которые вы хотите удалить, чтобы они были выделены. Если вы хотите убедиться, что они объединены в ветвь (например, dev
), в разделе " Только удаление", если "Объединить в" установите для " Местной ветки" значение dev
. В противном случае установите значение Всегда, чтобы игнорировать эту проверку.
Я написал сценарий оболочки, чтобы удалить все локальные ветки, кроме 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
Следующий 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]