ГИТ удалить все слилось в местные отделения


Я написал программу скрипт для удаления всех слили местные отделения.

#!/usr/bin/env bash

# Remove references to remote branches that no longer exist.
git remote prune origin
# Create a file containing list of all merged branches.
git branch --merged > 5db3bb3c-718a-444c-b1ce-d90a5a0d1cb3.clc

nano 5db3bb3c-718a-444c-b1ce-d90a5a0d1cb3.clc
# Trim trailing and leading whitespace etc.
sed 's/^[ \t]*//;s/[ \t]*$//' < 5db3bb3c-718a-444c-b1ce-d90a5a0d1cb3.clc
# Soft delete all branches left in the file and then remove tmp file.
xargs git branch -d < 5db3bb3c-718a-444c-b1ce-d90a5a0d1cb3.clc
rm 5db3bb3c-718a-444c-b1ce-d90a5a0d1cb3.clc

Хотя я написал это только для личного использования, я, вероятно, создать репозиторий на мой аккаунт на GitHub и я не особо знаком с shell-скрипт лучшей практики.



2334
11
задан 20 февраля 2018 в 04:02 Источник Поделиться
Комментарии
5 ответов

Улучшить управляемость вашего файла:


  • Не использовать жестко закодированные имя файла для временных файлов.

  • Не изрыгать временные файлы в текущем каталоге.

  • Убедитесь, что вы очистить временные файлы даже на ошибку.

Первые два могут быть решены путем использования mktemp. Последние могут быть решены с trap.

branchesfile=$(mktemp)
trap "{ rm -f $branchesfile; }" EXIT

Вы должны также чтить Выбор редактора по умолчанию, а не требуется нано. Вы можете получить пользователя редактор предпочтения git var GIT_EDITOR:

$(git var GIT_EDITOR) $branchesfile

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

if [ $? -ne 0 ]; then
exit 1
fi

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

Собрал все воедино:

#!/usr/bin/env bash
branchesfile=$(mktemp)
trap "{ rm -f $branchesfile; }" EXIT

# Remove references to remote branches that no longer exist.
git remote prune origin
# Create a file containing list of all merged branches.
git branch --merged > $branchesfile

$(git var GIT_EDITOR) $branchesfile
if [ $? -ne 0 ]; then
exit 1
fi

# Trim trailing and leading whitespace etc.
sed 's/^[ \t]*//;s/[ \t]*$//' < $branchesfile
# Soft delete all branches left in the file and then remove tmp file.
xargs git branch -d < $branchesfile

Есть еще один вопрос: ваш скрипт будет пытаться продолжать, если любой другой команды ошибок. set -e одним из способов решить эту проблему, но есть предостережения к его использованию. Если вы решите использовать set -eвам потребуется изменить код завершения проверки редактором, так как Баш выйдет, прежде чем он доберется до if.

16
ответ дан 20 февраля 2018 в 11:02 Источник Поделиться

Сухой - не повторяйся

"Не повторяй себя" - это популярный принцип программирования. Вы могли бы применить его здесь не повторять твое имя снова и снова.

MY_BRANCHES="5db3bb3c-718a-444c-b1ce-d90a5a0d1cb3.clc"
git branch --merged > $MY_BRANCHES

nano $MY_BRANCHES
# Trim trailing and leading whitespace etc.
sed 's/^[ \t]*//;s/[ \t]*$//' < $MY_BRANCHES
# Soft delete all branches left in the file and then remove tmp file.
xargs git branch -d < $MY_BRANCHES
rm $MY_BRANCHES

14
ответ дан 20 февраля 2018 в 05:02 Источник Поделиться

Я предполагаю, что вы начинаете nano Так что вы можете удалить возможные случаи master филиал (или некоторые другие статические филиал) из списка. Вы можете сделать то же самое в одной командной строке:

git branch --merged | grep -vE "(^\*|master|other|fixed|names)" | xargs git branch -d

В ^* регистрация будет удалена в настоящее время взяты для изменения ветке, и вы можете поместить в другой ветке имена в команде grep шаблон.

7
ответ дан 20 февраля 2018 в 05:02 Источник Поделиться

Я написал скрипт, чтобы сделать то же самое сам. Мои советы:

Советы


  • Я бы не использовать git branchее выход только должен быть читабельным (в Git языком, это часть ЖКТ это фарфор). Лучше всего подходит команда git for-each-ref который выводит данные в машиночитаемом формате (часть в Git 'сантехника').

  • Я бы также быть более явным об отделении, в котором вы заботитесь о том слились. Я считаю по умолчанию git branch --merged покажет вам все ветви уже слились в текущей ветви. Это работает, если вы находитесь на master или все, что вашей главной/багажник/интеграции филиала. Но, если вам случится быть на другой ветке, вы в конечном итоге удаление кучу веток, которые вы не хотели.

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

  • Убедитесь, что вы не удаляя основную ветку (он покажет, как объединить в себе).

  • Я тоже не просто волей-неволей удалить ветви, не спросив об этом пользователя.

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

Собираем все вместе

Немедленно остановить скрипт в любой командной ошибке:

set -e

Чтобы попасть в "основной" ветке вашего РЕПО вы можете сделать:

main_branch=$(git rev-parse --abbrev-ref HEAD)

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

git for-each-ref --merged "${main_branch}" --format '%(refname:short)' 'refs/heads/'

Теперь вы хотите, чтобы перебрать этот список. Имена в Git ветке обычно безопасны от странных персонажей, которые могли бы связываться с разбора оболочки, так что мы могли бы сделать:

for branch in $(git for-each-ref --merged "${main_branch}" --format '%(refname:short)' 'refs/heads/') ; do
# something here
done

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

while read branch ; do
# something here
done < <(git for-each-ref --merged "${main_branch}" --format '%(refname:short)' 'refs/heads/')

Теперь, что код мы помещаем внутри цикла? Ну, сначала мы хотим убедиться, что мы не удаляем основной ветке:

  test "${main_branch}" = "${branch}" && continue

Построить команду удалить ветку

  cmd="git branch -d '${branch}';"$'\n'

Спрашивать пользователя о выполнении команды "удалить" (убедитесь, что мы читаем из терминала , поскольку мы находимся внутри цикла while, который считывает из git for-each-ref команды):

  read -p "${cmd}Execute(y/N)? " run < /dev/tty

Только если пользователь ответил именно "у", Мы запускаем команду:

  test "${run}" = "y" && eval "${cmd}"

Целый притон

#!/usr/bin/env bash

set -e

main_branch=$(git rev-parse --abbrev-ref HEAD)

while read branch ; do
done < <(git for-each-ref --merged "${main_branch}" --format '%(refname:short)' 'refs/heads/')
test "${main_branch}" = "${branch}" ] && continue

cmd="git branch -d '${branch}';"$'\n'
read -p "${cmd}Execute(y/N)? " run < /dev/tty
test "${run}" = "y" && eval "${cmd}"
done < <(git for-each-ref --merged "${main_branch}" --format '%(refname:short)' 'refs/heads/')

Примечания:

Теперь, если эти местные филиалы, удаленные удаленных филиалах, которые должны быть удалены, вы захотите сделать что-то вроде:

# Get the remote name of the main branch, probably just 'origin'
remote=$(git config "branch.${main_branch}.remote")

# Then inside the loop, you'd do something like this:
git push --delete "${remote}" "${branch}"

Но это немного сложнее, поскольку вы захотите сначала выяснить, если эта ветка даже есть пульт установить, что фактический удаленную ветку зовут (может отличаться от местных), если его HEAD в (или предок) местного отделения, и т. д.

2
ответ дан 21 февраля 2018 в 03:02 Источник Поделиться

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

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

1
ответ дан 21 февраля 2018 в 12:02 Источник Поделиться