Skip to content

Latest commit

 

History

History
139 lines (85 loc) · 6.15 KB

File metadata and controls

139 lines (85 loc) · 6.15 KB

git-pull-all

git-pull-all — рекурсивно выполняет git pull --ff-only для текущей директории и всех вложенных git-репозиториев.

Путь в репозитории: bin/git-pull-all

🇬🇧 English | 🇷🇺 Русский | ⬅ Главная


Назначение

Если у вас много git-репозиториев под одной общей папкой (~/projects/, ~/work/ и т.п.), git-pull-all обновит все одной командой. Каждый репозиторий тянется с --ff-only, поэтому разошедшаяся ветка громко падает, а не делает merge-коммит.


Поведение

  1. Пробует git pull --ff-only в текущей директории.
  2. Находит все .git ниже . (исключая внутренности .git через -not -path '*/\.git/*').
  3. Для каждого найденного репозитория: cd repo && git pull --ff-only.
  4. Печатает → ошибка! для репо, где pull упал (расхождение веток, сетевая ошибка, нет upstream и т.д.).

Скрипт не прерывается на ошибке — проходит всё и отчитывается.

Исходник: bin/git-pull-all (~14 строк).


Требования

  • git (любая современная версия)
  • bash 3.2+ (системный на macOS) — на Linux тоже работает
  • Заранее настроенная аутентификация:
    • ssh-agent с загруженными ключами, или
    • git credential helper (osxkeychain на macOS), или
    • HTTPS-remotes без аутентификации (публичные репозитории)

Без преднастройки скрипт зависнет на запросе пароля для каждого репо.


Установка

chmod +x bin/git-pull-all     # убедиться, что бит исполнения установлен
mkdir -p ~/bin
ln -s "$PWD/bin/git-pull-all" ~/bin/git-pull-all

# Убедиться, что ~/bin в PATH:
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Или запускать напрямую без установки:

bash bin/git-pull-all

Использование

cd ~/projects        # родительская папка с множеством репозиториев
git-pull-all

Пример вывода:

Обновляем корневой репозиторий...
Корень не обновлён (возможно, не репозиторий)

Обновляем все вложенные репозитории:

 ./macos-utilities
Already up to date.

 ./my-app
Updating a1b2c3d..e4f5g6h
Fast-forward

 ./diverged-repo
     ошибка!

Ограничения

Только fast-forward

git pull --ff-only отказывается мёрджить, если локальная ветка разошлась с upstream. Это намеренно — защищает от тихих merge-коммитов. Цена: расходящиеся ветки пропускаются, вы увидите → ошибка!.

Если нужен merge или rebase — допилите скрипт или обработайте такие репо вручную.

Submodules не поддерживаются

Скрипт ищет независимые вложенные репозитории, а не git-submodules. Для submodules используйте git submodule update --remote отдельно.

Аутентификация может заблокировать

Если репо требует пароль (и helper не настроен), скрипт зависнет на ожидании ввода. Таймаута нет.

Exit-код всегда 0

Скрипт не пробрасывает ошибки через exit-код — они только печатаются в stdout. Чтобы ловить ошибки в CI, парсите stdout на → ошибка! или перепишите скрипт.

Сообщения на русском

Статусные сообщения (Обновляем..., → ошибка!) на русском. Сам скрипт не локализован.


Подсказки

  • Dry-run альтернатива: git fetch --all в каждом репо покажет, что прилетит, без модификации рабочих копий.
  • Параллелизм: скрипт последовательный. Для многих больших репо можно распараллелить через xargs -P, но осторожно с переплетающимся выводом.
  • Пропустить репо: встроенного механизма игнора нет. Либо вынесите репо за пределы поиска, либо форкните скрипт и добавьте фильтр путей.

Troubleshooting

«Корень не обновлён (возможно, не репозиторий)»

Текущая директория не git-репо — всё в порядке, скрипт продолжит с вложенными.

Каждый репо печатает → ошибка!

  • Проверьте сеть: git ls-remote origin в одном из репо.
  • Проверьте аутентификацию: ручной git pull --ff-only в упавшем репо покажет реальную ошибку.
  • Расхождение веток: git status подскажет, опередила ли локальная ветка upstream или отстаёт.

Скрипт висит

Скорее всего ждёт ввод пароля. Ctrl+C и проверьте git pull в висящем репо вручную. Настройте ssh-agent или credential helper.