Как я могу перебрать все локальные ветки в моем репозитории с помощью сценария bash. Мне нужно выполнить итерацию и проверить, есть ли разница между веткой и некоторыми удаленными ветвями. Ex
for branch in $(git branch);
do
git log --oneline $branch ^remotes/origin/master;
done
Мне нужно сделать что-то вроде приведенного выше, но проблема, с которой я столкнулся, заключается в том, что $ (git branch) дает мне папки внутри папки репозитория вместе с ветвями, присутствующими в репозитории.
Это правильный способ решить эту проблему? Или есть другой способ сделать это?
Спасибо
for b in "$(git branch)"; do git branch -D $b; done
Ответы:
При написании скриптов не следует использовать ветку git . Git предоставляет «сантехнический» интерфейс который явно предназначен для использования в сценариях (многие текущие и исторические реализации обычных команд Git (добавление, проверка, слияние и т. Д.) Используют этот же интерфейс).
Вам нужна команда сантехники git for-each-ref :
Примечание.
remotes/
Префикс удаленной ссылки не нужен, если только у вас нет других ссылок, которые приводятorigin/master
к совпадению нескольких мест в пути поиска имени ссылки (см. «Символьное имя ссылки…» в разделе «Указание редакций» в git-rev-parse (1) ). Если вы пытаетесь Явно избежать двусмысленности, то идти с полным именем исх:refs/remotes/origin/master
.Вы получите такой результат:
Вы можете направить этот вывод в sh .
Если вам не нравится идея генерации кода оболочки, вы можете отказаться от некоторой надежности * и сделать следующее:
* Имена ссылок должны быть защищены от разделения слов оболочки (см. Git-check-ref-format (1) ). Лично я бы придерживался предыдущей версии (сгенерированный код оболочки); Я более уверен, что с этим не может случиться ничего неуместного.
Поскольку вы указали bash, и он поддерживает массивы, вы можете поддерживать безопасность и по-прежнему избегать создания внутренностей вашего цикла:
Вы можете сделать что-то подобное,
$@
если вы не используете оболочку, поддерживающую массивы (set --
для инициализации иset -- "$@" %(refname)
добавления элементов).источник
--merged
, нужно ли мне дублировать логику в ветке git? Должен быть лучший способ сделать это.git for-each-ref refs/heads | cut -d/ -f3-
git for-each-ref refs/heads --format='%(refname)'
for-each-ref
теперь поддерживаются все селекторы веток, например--merged
и,git branch
иgit tag
теперь они фактически реализованы в терминах самихgit for-each-ref
себя, по крайней мере, для существующих списков случаев. (Создание новых веток и тегов не является и не должно быть частьюfor-each-ref
.)Это потому,
git branch
что текущая ветвь помечается звездочкой, например:так
$(git branch)
расширяется до, например* master mybranch
, а затем*
расширяется до списка файлов в текущем каталоге.Я не вижу очевидного варианта, чтобы вообще не печатать звездочку; но можно было отрубить:
источник
$(git branch | sed -e s/\\*//g)
.3-
решение.$(git branch | sed 's/^..//')
$(git branch | tr -d " *")
mapfile
Встроенная команда bash создана для этого.все ветки git:
git branch --all --format='%(refname:short)'
все локальные ветки git:
git branch --format='%(refname:short)'
все удаленные ветки git:
git branch --remotes --format='%(refname:short)'
перебрать все ветки git:
mapfile -t -C my_callback -c 1 < <( get_branches )
пример:
для конкретной ситуации OP:
источник: перечислить все локальные ветки git без звездочки
источник
Я повторяю как это например:
источник
Я бы посоветовал,
$(git branch|grep -o "[0-9A-Za-z]\+")
если ваши местные отделения будут называться только цифрами, буквами az и / или AZ.источник
Принятый ответ верен и действительно должен быть подходом, но решение проблемы в bash - отличное упражнение в понимании того, как работают оболочки. Уловка, позволяющая сделать это с помощью bash без дополнительных манипуляций с текстом, состоит в том, чтобы гарантировать, что вывод git branch никогда не будет расширен как часть команды, выполняемой оболочкой. Это предотвращает расширение звездочки при расширении имени файла (шаг 8) расширения оболочки (см. Http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html )
Используйте конструкцию bash while с командой чтения, чтобы разбить вывод ветки git на строки. '*' Будет читаться как буквальный символ. Используйте оператор case, чтобы сопоставить его, уделяя особое внимание шаблонам сопоставления.
Звездочки в bash конструкции case так и в подстановке параметров необходимо экранировать обратной косой чертой, чтобы оболочка не интерпретировала их как символы сопоставления с образцом. Пробелы также экранированы (для предотвращения токенизации), потому что вы буквально соответствуете '*'.
источник
Самый простой вариант для запоминания, на мой взгляд:
git branch | grep "[^* ]+" -Eo
Вывод:
Опция Grep -o (--only-matching) ограничивает вывод только соответствующими частями ввода.
Поскольку ни пробел, ни * недопустимы в именах веток Git, это возвращает список ветвей без дополнительных символов.
Изменить: если вы находитесь в состоянии «отдельная голова» , вам необходимо отфильтровать текущую запись:
git branch --list | grep -v "HEAD detached" | grep "[^* ]+" -oE
источник
Что я в итоге сделал, применительно к вашему вопросу (и вдохновленный упоминанием ccpizza
tr
):git branch | tr -d ' *' | while IFS='' read -r line; do git log --oneline "$line" ^remotes/origin/master; done
(Я часто использую циклы while. Хотя для определенных вещей вы определенно захотите использовать указанное имя переменной [, например, "ветвь"], большую часть времени я занимаюсь только тем, чтобы что-то делать с каждой строкой ввода. 'линия' здесь вместо 'ветки' указывает на возможность повторного использования / мышечную память / эффективность.)
источник
Продолжая ответ @ finn (спасибо!), Следующее позволит вам перебирать ветки без создания промежуточного сценария оболочки. Это достаточно надежно, если в имени ветки нет новых строк :)
Цикл while выполняется в подоболочке, что обычно нормально, если вы не устанавливаете переменные оболочки, к которым хотите получить доступ в текущей оболочке. В этом случае вы используете подстановку процесса, чтобы перевернуть канал:
источник
Если вы в этом состоянии:
И вы запускаете этот код:
Вы получите такой результат:
источник
for b in "$(git branch)"; do git branch -D $b; done
Будь проще
Простой способ получить имя ветки в цикле с помощью сценария bash.
Вывод:
источник
Ответ Googlian, но без использования for
источник
Это использует git сантехнику команды , предназначенные для написания сценариев. Это тоже просто и стандартно.
Ссылка: завершение Git Bash
источник