Вы не должны использовать git branch при написании скриптов. Git предоставляет «соединительный» интерфейс , который явно предназначен для использования в сценариях (многие текущие и исторические реализации обычных команд Git (добавление, извлечение, объединение и т. Д.) Используют этот же интерфейс).
Нужная вам сантехническая команда: git for-each-ref :
git for-each-ref --shell \
--format='git log --oneline %(refname) ^origin/master' \
refs/heads/
Примечание: Вам не нужен префикс remotes/
на удаленном реф, если у вас нет других рефсов, которые заставляют origin/master
совпадать с несколькими местами в пути поиска имени реф (см. «Символическое имя реф.…» В Раздел «Указания ревизий» в git-rev-parse (1) ). Если вы пытаетесь явно избежать двусмысленности, используйте полное имя ссылки: refs/remotes/origin/master
.
Вы получите такой вывод:
git log --oneline 'refs/heads/master' ^origin/master
git log --oneline 'refs/heads/other' ^origin/master
git log --oneline 'refs/heads/pu' ^origin/master
Вы можете передать этот вывод в sh .
Если вам не нравится идея генерации шелл-кода, вы можете отказаться от некоторой устойчивости * и сделать это:
for branch in $(git for-each-ref --format='%(refname)' refs/heads/); do
git log --oneline "$branch" ^origin/master
done
*
Имена ссылок должны быть защищены от разбиения слов в оболочке (см. git-check-ref-format (1) ). Лично я бы придерживался прежней версии (сгенерированный код оболочки); Я более уверен, что с этим не может случиться ничего неуместного.
Поскольку вы указали bash и он поддерживает массивы, вы можете сохранить безопасность и при этом избежать генерации кишок вашего цикла:
branches=()
eval "$(git for-each-ref --shell --format='branches+=(%(refname))' refs/heads/)"
for branch in "${branches[@]}"; do
# …
done
Вы можете сделать нечто подобное с $@
, если вы не используете оболочку, которая поддерживает массивы (set --
для инициализации и set -- "$@" %(refname)
для добавления элементов).